【问题标题】:How can I map click events to elements in multiple layers?如何将点击事件映射到多个图层中的元素?
【发布时间】:2013-12-13 16:04:24
【问题描述】:

我有多个不同组中的 SVG 元素。它们相互重叠。示例:

<svg id="board" width="100%" height="80%">
   <g id="terrain" class="layer">
     <path d="M-32,-32L32,-32 32,32 -32,32Z" transform="translate(0, 0)" class="mote terrain hill"></path>
   </g>
   <g id="guy" class="layer">
     <path d="M-21...Z" transform="translate(192, 448)" class="mote guy"></path>
   </g>
</svg>

当单击与两者都匹配的 x、y 位置时,我想知道两者都被单击的所有内容。如果我将每个都绑定到“点击”事件,则只有顶部的事件处理程序会被调用。这是合理的,虽然不是我想要的。

我正在考虑创建一个最顶层并让它捕获所有点击,然后确定应该通知其他层中的哪些元素。如果可能的话,我想避免很多跟踪。有更简单的方法吗?

【问题讨论】:

  • 您提出的解决方案对我来说听起来很合适;由于元素是兄弟元素,事件不会通过它们冒泡,因此您需要捕获委托事件并确定哪些元素受到影响。
  • 这个问题已经回答here
  • 问题尚未得到解答。

标签: javascript svg layer z-order


【解决方案1】:

来自SVG spec

"默认情况下,指针事件不得在形状的裁剪(不可见)区域上发送。例如,半径为 10 的圆被裁剪为半径为 5 的圆将不会接收较小半径之外的“点击”事件。更高版本的 SVG 可能会定义新属性,以便对命中测试和剪辑之间的交互进行细粒度控制。”

但是,有一种方法可以获取在特定点相交的 svg 形状列表。 “getIntersectionList”函数返回项目列表。

我已经创建了其中一个 jsfiddle 事物jsfiddle.net/uKVVg/1/ 单击圆圈的交叉点以获取 ID 列表。手动将事件发送到该列表。

Javascript 如下:

function s$(a) {
    return document.getElementById(a);
}

var list 

function hoverElement(evt) {
    var root = s$("canvas");

    var disp = s$("pointer");
    disp.setAttribute("x",evt.clientX);
    disp.setAttribute("y",evt.clientY);

    rpos = root.createSVGRect();
    rpos.x = evt.clientX;
    rpos.y = evt.clientY;
    rpos.width = rpos.height = 1;
    list = root.getIntersectionList(rpos, null);
    s = "clicked: "
    $.each(list,function(item,val){
        if (val.id != "pointer") {
            s = s + (val.id) + " ";
        }
    })
    alert(s);
}

var root = s$("canvas");
root.addEventListener("click", hoverElement, false);

有一些 javascript 可能会被整理,但希望它能回答您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 2020-12-22
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2020-10-01
    相关资源
    最近更新 更多