将鼠标事件调度到视觉上在接收元素"后面"的元素

Eri*_*rik 5 javascript css css3

在我的网页上,我有两个div,A和B:

在此输入图像描述

DOM看起来如下(简化).这里需要注意的主要问题是,div在DOM层次结构中处于同一级别,并且它们不按任何顺序排序.此外,外部div不仅包含A和B,还包含更多的div,C,D,E等.B可能不一定与A重叠.它也可能是C,位于A后面.

<div>
    <div style="...">B</div>
    <div style="...">A</div>
</div>
Run Code Online (Sandbox Code Playgroud)

单击处理程序附加到外部div,在冒泡阶段捕获A或B上的鼠标单击事件.单击进入A和B的交叉点将导致A上的单击事件,该事件会冒泡到我现在触发的单击处理程序.

现在的问题是:在某些条件下,处理程序决定该事件不应由A处理但应属于B.如果事件应由B处理,则将触发相同的单击处理程序,但事件对象currentTarget属性将为B代替.

我怎样才能做到这一点?

我已经看过JS中的css3指针处理程序和一些事件调度方法,但是在这里找不到解决方案.

可能的解决方案1(不兼容跨浏览器)?:

我想我可能会使用pointer-events css3属性.如果处理程序决定该事件应由B处理,则它将指针事件设置为无.然后,它重新触发鼠标点击.问题在于:是否可以仅使用坐标重新触发鼠标,而不指定特定元素?

无论如何,指针事件的支持是有限的:http://caniuse.com/pointer-events

Yos*_*shi 3

您可以尝试将事件传递给B(使用 jQuery):

\n\n

伪代码

\n\n
var $A = $(\'#A\'), $B = $(\'#B\');\n\n$B.on(\'click\', function () {\n  console.log(\'B clicked\');   \n});\n\n$(\'#outer\').on(\'click\', function (evt) {\n    if (Math.random() < 0.1) { // << pseudo condition\n        $B.trigger(evt);\n    }\n});\xe2\x80\x8b\n
Run Code Online (Sandbox Code Playgroud)\n\n

http://jsfiddle.net/hzErh/

\n\n
\n\n

更新

\n\n

使用这样的函数:

\n\n
// this function should (did not enough testing) return all elements at a given\n// point in the order of top to bottom.\nvar elementsFromPoint = function (x, y, root) {\n  var buffer = [], result = [], el, i = 0, lim;\n\n  while ((el = document.elementFromPoint(x, y)) && [root, document.body, document.body.parentNode].indexOf(el) < 0) {\n    result.push(el);\n    buffer.push({el: el, visibility: el.style.visibility});\n    el.style.visibility = \'hidden\';\n  }\n\n  for (lim = buffer.length; i < lim; i += 1) {\n    buffer[i].el.style.visibility = buffer[i].visibility;\n  }\n\n  return result;\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以获得给定 x/y 坐标的元素。虽然它有点老套,但需要更多测试。

\n\n
$(\'#outer\').on(\'click\', function (evt) {\n  var elements = elementsFromPoint(\n    evt.pageX + $(this).offset().left,\n    evt.pageY + $(this).offset().top,\n    this\n  );\n\n  console.log(elements);\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

演示: http: //jsfiddle.net/hzErh/1/

\n\n
\n\n

更新 2:此版本应该为许多元素提供更好的性能:

\n\n
// this function should (did not enough testing) return all elements at a given\n// point, though the order is not representative for the visible order.\nvar elementsFromPoint = function (root, x, y) {\n  var result = [], i = 0, lim = root.childNodes.length, bb;\n\n  for (; i < lim; i += 1) {\n    bb = root.childNodes[i].getBoundingClientRect();\n    if (bb.left <= x && x <= bb.right && bb.top <= y && y <= bb.bottom) {\n      result.push(root.childNodes[i]);\n    }\n  }\n\n  return result;\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

演示: http: //jsfiddle.net/CTdZp/2/

\n