在另一个元素后面的画布上的事件侦听器
Event listener on a canvas behind another element
我有一个鼠标移动事件监听器附加到我的画布。但是在画布的顶部是一个div,它的z-index更高,它包含了一些菜单按钮。
我面临的问题是,我希望鼠标移动事件仍然激活当鼠标在菜单元素-其中是在画布元素。
当前,它的行为就好像鼠标不再位于画布的顶部,因为菜单元素由于z-index顺序而优先。
是否有一种方法可以使这个事件侦听器忽略任何妨碍它的元素?
我代码:var canvas = new function(){
var self = this
self.outputMouseData = function(evt,el){
var pos = mouse.relativePosition(evt,el);
el.ctx.clearRect(0,0,el.width,el.height);
el.ctx.fillStyle = "white";
el.ctx.font = "bold 16px Arial";
el.ctx.fillText(pos.x+' | '+pos.y, el.width-150,el.height-10);
}
}
elements.addEvent(foreground,'mousemove',
function(evt){ canvas.outputMouseData(evt,foreground); }
);
我HTML <div class="parent">
<canvas id="canvas"></canvas>
<div class="menu">Menu output</div>
</div>
父元素是相对定位的。Canvas和menu是绝对位置的,但是menu的z-index在Canvas的顶部
HTML事件在节点树中冒泡(您可以在这里阅读关于此的很好的解释)。
这意味着,如果您将事件处理程序附加到包含其他元素的元素上,则当事件发生在子元素上时(假定冒泡没有显式终止),该处理程序将调用甚至。你可以把你的画布包起来。Div放在包装器元素(例如span)中,并在其上附加处理程序。无论z-index如何,您都将获得事件。
下面是一个简短的代码示例(从这里获取的getOffsetSum):
var canvas = document.getElementById('canvas');
var canvasPos = getOffsetSum(canvas);
var ctx = canvas.getContext('2d');
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(0, 0, 99, 99);
var container = document.getElementById('container');
var mousemove = document.getElementById('mousemove');
container.addEventListener('mousemove', function(evt) {
var pos = getOffsetSum(evt.target);
pos.top += evt.offsetY - canvasPos.top;
pos.left += evt.offsetX - canvasPos.left;
mousemove.innerHTML = 'offsetX: ' + evt.offsetX + ' | offsetY: ' + evt.offsetY + '<br/>' +
'canvasX: ' + pos.left + ' | canvasY: ' + pos.top;
});
function getOffsetSum(elem) {
var top = 0, left = 0;
while (elem) {
top = top + parseInt(elem.offsetTop);
left = left + parseInt(elem.offsetLeft);
elem = elem.offsetParent;
}
return {
top: top,
left: left
}
}
.ontop {
position: absolute;
top: 20px;
left: 20px;
}
<span id="container">
<canvas id="canvas" width="100" height="100"></canvas>
<div class="ontop">ON TOP</div>
</span>
<div id="mousemove"></div>
将canvas和menu-div放到一个容器div中。
然后使用jQuery事件委托来监听容器上的鼠标移动事件,但是让你的画布响应这些鼠标移动事件。
$('#container').on('mousemove','#myCanvas',function(){ doSomething(); }
您可以在这里了解更多关于事件委托的信息:http://api.jquery.com/on/
您可以简单地将pointer-events: none;
应用于菜单div,而不是像其他答案中建议的那样使用包装器。这将允许画布发出mousemove
事件。
.menu {
pointer-events: none;
}
我最初的想法是将" mousmove "事件添加到文档本身(而不是画布元素或元素),并使用evt跟踪元素。currTarget或event .target。通过这种方式,无论您将鼠标悬停在菜单上还是画布上(或任何地方),mousemovet都将始终存在。
- 如何在for循环中添加事件侦听器
- 未命中服务器发送的事件侦听器
- 如何覆盖原型中的事件侦听器
- 无法将事件侦听器附加到画布
- 如何在d3.js中自定义事件侦听器
- 在es6中,将带有回调的事件侦听器设置为可迭代的
- 事件侦听器未在chrome扩展中的options.js中启动
- IE8更改文本区域上的事件侦听器不工作
- 将事件侦听器添加到文档,而不是签入元素存在,然后添加事件侦听器
- javascript删除事件侦听器
- 我应该/如何清除mousemove JQuery事件侦听器
- 在JQuery中使用谷歌地图Api事件/侦听器
- 如何使用我的Jquery代码创建委托事件侦听器
- 'mousemove'画布中的事件侦听器-指针仅在最后一个矩形中更改
- 为什么此事件侦听器不工作
- 是否可以在数字输入框中的小按钮中添加事件侦听器
- 在Google Chrome扩展中添加事件侦听器
- SVG元素在转换后会丢失事件侦听器
- jQuery事件侦听器多次启动
- 如何在不删除类似侦听器的情况下从父对象中删除jQuery事件侦听器