简体   繁体   中英

jQuery select SVG anchor elements inside <object> tag

I am having quite a bit of trouble using the anchor elements built into my SVG (displayed as an <object> ). I am trying to target the anchor elements within my Object with jQuery to toggle its respective piece of content when clicked.

If you take a look at my example, I have 3 links built into my SVG (they are a lighter shade of green than the others). I used InkScape to create my SVG image, and on the light green areas that are linked are just shapes with the href attribute equal to "#operable-shades", "#gutters-downspouts", and "#gable-pediments" respectively.

With my SVG displaying nicely on my page (using an <object> tag), when hovering over the links I have created I get the original object data URL with my specified anchor appended to the end of it (ex. 'https://example.com/wp-content/uploads/GHB_Interface-v0.1.svg#gable-pediments') when I would expect it to be 'https://example.com/#gable-pediments'.

 <script type="text/javascript"> jQuery(document).ready(function($) { $('.ghb_toggle').hide() $('a[href^="#"]').on('click', function(event) { var target = $(this).attr('href'); $(target).toggle(); }); }); </script>
 .ghb_toggle { display:none; }
 <object type="image/svg+xml" data="https://example.com/wp-content/uploads/test.svg" width="500" height="400"></object> <div id="gable-pediments" class="ghb_toggle"> <p>Content 1</p> </div> <div id="gutters-downspouts" class="ghb_toggle"> <p>Content 2</p> </div> <div id="operable-shades" class="ghb_toggle"> <p>Content 3</p> </div>

How can I modify my jQuery to be able to successfully interact with my anchor elements inside my <object> to hide/show a respective piece of content with a unique identifier?

To target the content of an svg document loaded inside an <object> , or <iframe> , you need to pass the correct Document context to jQuery: the one you can access from the .contentDocument property of the embedding element.

Note that this requires that the svg document has been loaded in a same-origin way, which is not possible in StackSnippets' null origined frames, so here is a live plnkr .

$( "object" ).on( "load", (evt) => {
  const svg_doc = this.contentDocument;
  $( "a[href]", svg_doc ) // second argument is context
    .on( 'click', (evt) => {
      // add your listener here
    } );
};

Also note that in your svg you have xlink:href attributes being defined, not just href , so your jQuery selector should be 'a[xlink\\\\:href^="#"]'


But if your goal is to set the anchors in you svg relative to an other base URL than the one the document is loaded from, then you don't need all this, you can simply insert an HTML <base> element at the beginning of your svg document and all the relative URLs will use it.
See live demo as a plnkr and a more complicated snippet:

 // To be able to embed it in a StackSnippet (directly in this answer), // we need to generate the file in memory from JS // you don't need it const svg_content = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="300" > <!-- we must declare it in the HTML namespace --> <base xmlns="http://www.w3.org/1999/xhtml" href="https://google.com" /> <a href="#foo-bar"> <rect fill="green" x="10" y="10" width="30" height="30" /> </a> </svg> `; const svg_blob = new Blob( [ svg_content ], { type: "image/svg+xml" } ); const svg_url = URL.createObjectURL( svg_blob ); document.querySelector( "object" ).data = svg_url;
 <object></object>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM