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

its*_*kem 2 jquery internet-explorer svg shadow-dom

我有一个像这样的结构:

<div class="linkedItem" data-yt="youtubelink">
  <svg><use></svg>
  <div>youtube link</div>
</div>
Run Code Online (Sandbox Code Playgroud)

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

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

function launchYouTube(e){
    var _src = $(e.target).closest(".linkedItem").data("yt"));
};
Run Code Online (Sandbox Code Playgroud)

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

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

小智 8

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

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

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

例如,你可以替换......

function launchYouTube(e){
    var _src = $(e.target).closest(".linkedItem").data("yt"));
};
Run Code Online (Sandbox Code Playgroud)

与...

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));
};    
Run Code Online (Sandbox Code Playgroud)

要么....

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));
};    
Run Code Online (Sandbox Code Playgroud)