Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Mousemove事件被屏蔽SVG元素阻止_Javascript_Svg_Snap.svg - Fatal编程技术网

Javascript Mousemove事件被屏蔽SVG元素阻止

Javascript Mousemove事件被屏蔽SVG元素阻止,javascript,svg,snap.svg,Javascript,Svg,Snap.svg,我有一个带有mousemove事件的SVG元素,显示指针的坐标。当鼠标移动到阻挡元素上时,mousemove事件被阻止。我需要使事件传播到原始元素 我已尝试更改“指针事件”属性,但这会影响所有鼠标事件,并且我需要遮挡元素来响应其他事件。任何建议 解决这一问题的一种方法可能是将所有事件绑定到svg和遮挡元素所在的容器/父节点上——根据该“外部”元素中子元素的属性记录鼠标在该“外部”元素中的位置 如果问题中没有代码示例,则很难确切知道需要什么,但原则可能遵循以下思路 <!-- HTML sam

我有一个带有mousemove事件的SVG元素,显示指针的坐标。当鼠标移动到阻挡元素上时,mousemove事件被阻止。我需要使事件传播到原始元素


我已尝试更改“指针事件”属性,但这会影响所有鼠标事件,并且我需要遮挡元素来响应其他事件。任何建议

解决这一问题的一种方法可能是将所有事件绑定到svg和遮挡元素所在的容器/父节点上——根据该“外部”元素中子元素的属性记录鼠标在该“外部”元素中的位置

如果问题中没有代码示例,则很难确切知道需要什么,但原则可能遵循以下思路

<!-- HTML sample -->
<div id="container">
    <div id="elem1" class="occluded">Element #1</div>
    <div id="elem2" class="occluded">Element #2</div>
    <div class="fullWidthHeightOverlay"></div>
</div>
<div id="eventLog"></div>
您将看到,我还创建了几个变量,我们可以将.occluded元素指定给它们

接下来,我们需要logMousePos和occludedClick函数,在这些函数中,记录两个被遮挡元素相对于其上方.FullWidthHeightOver层上鼠标位置的位置属性,然后启动一些简单行为,例如

function logMousePos(e) {
    var e1 = elem1.getBoundingClientRect(),
        e2 = elem2.getBoundingClientRect(),
        e1CL = elem1.classList,
        e2CL = elem2.classList;

    /* is mouse inside #elem1 ? */
    if (check.X(e.clientX, e1) && check.Y(e.clientY, e1)) {
        /* if no 'over' class add it... */
        if (!e1CL.contains('over')) e1CL.add('over');
    } else {
        /* ...if 'over' class remove it */
        if (e1CL.contains('over')) e1CL.remove('over');
    }

    /* is mouse inside #elem2 ? */
    if (check.X(e.clientX, e2) && check.Y(e.clientY, e2)) {
        if (!e2CL.contains('over')) e2CL.add('over');
    } else {
        if (e2CL.contains('over')) e2CL.remove('over');
    }
}

function occludedClick(e) {
    var e1 = elem1.getBoundingClientRect(),
        e2 = elem2.getBoundingClientRect(),
        e1CL = elem1.classList,
        e2CL = elem2.classList;

    /* was mouse clicked inside #elem1 or #elem2 or not ? */
    if (check.X(e.clientX, e1) && check.Y(e.clientY, e1)) {
        $('#eventLog').textContent = 'Element #1 pseudo-Clicked';
    } else if (check.X(e.clientX, e2) && check.Y(e.clientY, e2)) {
        $('#eventLog').textContent = 'Element #2 pseudo-Clicked';
    } else {
        $('#eventLog').textContent = '';
    }
 }
…你会注意到我指的是一些检查对象的方法,呃,检查鼠标是否在任何一个被遮挡元素的“boundingClientRect”内

你可以找到整个事情的大致情况

我希望这能给你足够的机会,使你能够在你的特殊情况下运用这一原则


总结布赖恩·皮科克优秀而详细的建议的关键思想: 问题似乎在于svg元素的图形顺序并不遵循DOM层次结构,因此不能直接使用事件的正常冒泡。因此,我们必须在一个共同的高点捕捉事件,并务实地寻找该点下的元素


作为一般性的讨论点,请原谅,在这里,应该注意的是,在许多情况下,这不是一个最佳的解决方案。例如,当捕捉到快速发生的事件(如mousemove)时,当SVG中有许多元素时,以及当平滑GUI需要快速响应时,该策略可能在计算上过于昂贵。如果SVG规范中包含更好的事件处理系统,浏览器中也包含更好的事件处理系统,那么一切都可以由引擎完成,这将是非常棒的。这将显著提高拥有纯SVG GUI的能力

a将有助于将鼠标事件侦听器放在一个公共祖先元素中……您可以将处理程序放在svg上,然后临时使用getElementFromPoint更改指针事件,并对下一个对象重复此操作,直到点击svg,然后再将指针事件放回。可能比较便宜。如果没有代码,很难知道。试想一下,如果鼠标移动是拖动的一部分,也可能有一种方法,即拖动的开始,关闭其他元素的指针事件,并在拖动完成后将类放回去。我要解决的特殊问题是在局部坐标中显示光标位置,当在背景矩形上操作时,在顶部操作对象。通过在公共连接处捕获事件,这很容易实现。我对拖动操作没有问题,因为我只使用选定的对象和处理程序。用于通过单击或区域矩形进行选择。你的教程在这里很有用。如果SVG2建议的实施不是那么零碎就好了。但这是另一天的另一个问题
function logMousePos(e) {
    var e1 = elem1.getBoundingClientRect(),
        e2 = elem2.getBoundingClientRect(),
        e1CL = elem1.classList,
        e2CL = elem2.classList;

    /* is mouse inside #elem1 ? */
    if (check.X(e.clientX, e1) && check.Y(e.clientY, e1)) {
        /* if no 'over' class add it... */
        if (!e1CL.contains('over')) e1CL.add('over');
    } else {
        /* ...if 'over' class remove it */
        if (e1CL.contains('over')) e1CL.remove('over');
    }

    /* is mouse inside #elem2 ? */
    if (check.X(e.clientX, e2) && check.Y(e.clientY, e2)) {
        if (!e2CL.contains('over')) e2CL.add('over');
    } else {
        if (e2CL.contains('over')) e2CL.remove('over');
    }
}

function occludedClick(e) {
    var e1 = elem1.getBoundingClientRect(),
        e2 = elem2.getBoundingClientRect(),
        e1CL = elem1.classList,
        e2CL = elem2.classList;

    /* was mouse clicked inside #elem1 or #elem2 or not ? */
    if (check.X(e.clientX, e1) && check.Y(e.clientY, e1)) {
        $('#eventLog').textContent = 'Element #1 pseudo-Clicked';
    } else if (check.X(e.clientX, e2) && check.Y(e.clientY, e2)) {
        $('#eventLog').textContent = 'Element #2 pseudo-Clicked';
    } else {
        $('#eventLog').textContent = '';
    }
 }
var check = {
    X: function(x, el) {
        return (x > el.left && x < el.right);
    },
    Y: function(y, el) {
        return (y > el.top && y < el.bottom);
    }
};
(function init() {
    addEvents();
    elem1 = $('#elem1');
    elem2 = $('#elem2');
}());