在另一个元素后面的画布上的事件监听器

时间:2015-08-06 22:22:10

标签: javascript html5 canvas

我的画布上附有鼠标移动事件监听器。但是在我的画布上面是一个具有更高z-index的div,它包含一些菜单按钮。

我面临的问题是,我希望鼠标移动事件在鼠标悬停在菜单元素上时仍然激活 - 该元素位于画布元素之上。

目前,它的作用就好像鼠标不再位于画布顶部,因为菜单元素因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>

父母是相对定位的。画布和菜单是绝对定位的,但菜单在画布上是z-index'd。

4 个答案:

答案 0 :(得分:3)

HTML事件正在冒泡节点树(你可以阅读关于here的一个很好的解释)。

这意味着如果将事件处理程序附加到包含其他元素的元素,则当子元素上发生事件时,该处理程序将被称为甚至(给定冒泡未明确中止) )。你可以包装你的画布&amp; div包装元素(例如span)并在其上附加处理程序。无论z-index如何,你都会得到这个事件。

以下是代码外观的简短示例(取自here的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>

答案 1 :(得分:1)

将canvas和menu-div放入容器div中。

然后使用jQuery事件委托来侦听容器上的mousemove事件,但让画布响应那些mousemove事件。

$('#container').on('mousemove','#myCanvas',function(){ doSomething(); }

您可以在此处详细了解活动授权:http://api.jquery.com/on/

答案 2 :(得分:0)

我最初的想法是将“mousemove”事件添加到文档本身(而不是canvas元素或元素),并使用evt.currTarget或evt.target跟踪元素。通过这种方式,无论您将鼠标悬停在菜单或画布上(或任何地方),mousemove evt都将始终存在。

答案 3 :(得分:0)

您不必像其他答案中那样使用包装器,只需将pointer-events: none;应用于菜单div。这将允许画布发出mousemove事件。

.menu {
  pointer-events: none;
}