在<svg>中<use>未在IE中找到最接近的</svg> <div>

时间:2015-11-12 13:21:15

标签: jquery internet-explorer svg shadow-dom

我的结构设置如下:

<div class="linkedItem" data-yt="youtubelink">
  <svg><use></svg>
  <div>youtube link</div>
</div>

在jQuery中,我在包装器<div>上分配了一个点击事件:

$("div.linkedItem").on("click",launchYouTube);

function launchYouTube(e){
    var _src = $(e.target).closest(".linkedItem").data("yt"));
};

在事件处理程序中,我在Chrome中获得了_src的值,但在IE11中,它是未定义。似乎IE11中的<use>不知道它的父级是什么,因此无法找到最接近的div.linkedItem

我看到一篇关于svg gotchas的文章,我认为最接近的是#4(jQuery抛出错误),但我不认为这是出于某种原因。任何见解都表示赞赏。

1 个答案:

答案 0 :(得分:8)

对于每个SVGUseElement,SVG DOM维护一个SVGElementInstance类型的对象的影子树(&#34;实例树&#34;)。 SVGUseElement有一个instanceRoot属性,该属性指向阴影树根目录下的SVGElementInstance。 SVGElementInstance有一个relatedUseElement属性,指向SVGUseElement。这两个属性允许您在主DOM树和阴影树之间跳转。

我在Internet Explorer和Chrome中测试了您的示例。在Chrome中,点击&#39;事件传递给SVGUseElement,jQuery然后使用它来走主DOM树以找到所需的&#39; div&#39;元件。在Internet Exploer中,点击&#39;事件传递给SVGElementInstance,然后jQuery使用它来向上移动阴影树。由于影子树不是主DOM树的一部分,jQuery永远不会找到所需的&#39; div&#39; div元件。

您可以通过检查目标来解决此问题。如果target是SVGElementInstance,则将target.correspondingUseElement传递给jQuery,否则将目标传递给jQuery。您可以通过测试adjacentUseElement属性或通过测试toString()等于&#34; [object SVGElementInstance]&#34;来检查SVGELementInstance。

例如,您可以替换...

function launchYouTube(e){
    var _src = $(e.target).closest(".linkedItem").data("yt"));
};

...与

function launchYouTube(e){
    var target = e.target;
    if (target.correspondingUseElement) {
        target = target.correspondingUseElement;
    }
    var _src = $(target).closest(".linkedItem").data("yt");
    console.log(JSON.stringify(_src));
};    

...或

function launchYouTube(e){
    var target = e.target;
    if (target.toString() === "[object SVGElementInstance]") {
        target = target.correspondingUseElement;
    }
    var _src = $(target).closest(".linkedItem").data("yt");
    console.log(JSON.stringify(_src));
};