jQuery select <object> 标签内的 SVG 锚点元素

jQuery select SVG anchor elements inside <object> tag

我在使用我的 SVG 中内置的锚元素时遇到了一些麻烦(显示为 <object>)。我正在尝试使用 jQuery 定位对象中的锚点元素,以便在单击时切换其各自的内容。

如果您看一下我的示例,我的 SVG 中内置了 3 个链接(它们的绿色阴影比其他的更浅)。我使用 InkScape 创建我的 SVG 图像,并且在链接的浅绿色区域上只是 href 属性分别等于“#operable-shades”、“#gutters-downspouts”和“#gable-pediments”的形状。

我的 SVG 在我的页面上很好地显示(使用 <object> 标签),当鼠标悬停在我创建的链接上时,我得到原始对象数据 URL,我的指定锚点附加到当我期望它是 'https://example.com/#gable-pediments'.

时结束(例如 'https://example.com/wp-content/uploads/GHB_Interface-v0.1.svg#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>

如何修改我的 jQuery 以便能够成功地与我的 <object> 中的锚点元素进行交互,以 hide/show 具有唯一标识符的相应内容?

要定位 <object><iframe> 中加载的 svg 文档的内容,您需要将正确的文档上下文传递给 jQuery:您可以从中访问的那个嵌入元素的 .contentDocument 属性。

请注意,这需要以 same-origin 方式加载 svg 文档,这在 StackSnippets 的空源框架中是不可能的,因此这里是 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
    } );
};

另请注意,在您的 svg 中,您定义了 xlink:href 属性,而不仅仅是 href,因此您的 jQuery 选择器应该是 'a[xlink\:href^="#"]'


但是如果你的目标是在你的 svg 中设置锚点相对于另一个基础 URL 而不是从中加载文档的基础,那么你不需要所有这些,你可以简单地插入一个HTML <base> 元素位于 svg 文档的开头,所有相关 URL 元素都将使用它。
将现场演示视为 plnkr 和更复杂的片段:

// 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>