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

<use> within <svg> not finding closest <div> in IE

我的结构是这样设置的:

<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 中它是 undefined。似乎IE11中的<use>不知道它的父级是什么,因此找不到最接近的div.linkedItem.

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

对于每个 SVGUseElement,SVG DOM 维护一个 SVGElementInstance 类型对象的影子树("instance tree")。 SVGUseElement 有一个 instanceRoot 属性 指向影子树根部的 SVGElementInstance。 SVGElementInstance 有一个相应的 UseElement 属性 指向 SVGUseElement。这两个属性允许您在主 DOM 树和影子树之间跳转。

我在 Internet Explorer 和 Chrome 中测试了您的示例。在 Chrome 中,'click' 事件被传递给 SVGUseElement,jQuery 然后使用它在主 DOM 树中向上移动以找到所需的 'div' 元素。在 Internet Exploer 中,'click' 事件被传递给 SVGElementInstance,然后 jQuery 使用它沿着影子树向上移动。由于影子树不是主 DOM 树的一部分,因此 jQuery 永远找不到所需的 'div' 元素。

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

来检查 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));
};