0

我试图让我的 jQuery 事件回调正确触发,但我似乎无法解决我感兴趣的元素没有收到事件的事实,因为页面上覆盖了另一个元素。我可以将其总结如下(我对元素进行了样式设置,因此它们显示在 jsfiddle 中):

<div id='mydiv'>
    <div style="border: 1px solid; border-color: red; position: absolute; left: 0px; top: 0px; width: 200px; height: 200px; z-index: 100">Hello</div>
    <canvas style="border: 1px solid; border-color: yellow; position: absolute; left: 50px; top: 50px; width: 150px; height: 150px"></canvas>
</div>​

对于上面的部分,如果我尝试听鼠标单击<canvas>,则永远不会调用该事件:

$('#mydiv').on('mousedown', 'canvas', this, function(ev) {
    console.log(ev.target);
});

但是,如果我修改我的事件处理程序以侦听<div>元素,则会按预期触发回调:

$('#mydiv').on('mousedown', 'div', this, function(ev) {
    console.log(ev.target);
});

我怎样才能强迫我<canvas>接收事件,同时将有问题的<div>块留在最前面?

4

4 回答 4

1

你不能。顶部的对象获取点击事件。这就是 DOM 的工作方式。

如果要处理该单击事件,则需要在顶部的对象中进行处理,或者使用冒泡并在父对象中进行处理。您可以在顶部对象中处理它,如果需要,可以通过触发对另一个对象的单击或直接调用单击处理程序将其“转发”到另一个对象。

或者,您可以通过将其设置为更高的值来将画布元素移动到 ul 上方,z-index然后它将获得点击事件。

或者,您可以在顶部创建一个新的透明画布对象来获取事件,而将其他两个对象留在原处以获得所需的视觉效果。

于 2012-02-26T15:35:37.537 回答
1

您可以将元素绑定到最近的公共父级,并检查鼠标的 X 和 Y 坐标是否在画布范围内。

  • 在下面的示例中,我缓存了画布的尺寸(高度和宽度),因为我假设它们是恒定的。如果尺寸不是恒定的,则将其移动到函数内部。

  • 我使用该.offset()方法计算<canvas>s左上角的真实X和Y坐标。outerWidth()我通过添加和的值来计算右下角的坐标.outerHeight()

基本演示:http: //jsfiddle.net/75qbX/2/

var $canvas = $('canvas'), /* jQuery reference to the <canvas> */
    $canvasWidth = $canvas.outerWidth(), /* assuming height and width to be constant */
    $canvasHeight = $canvas.outerHeight();
function isCanvasClicked(x, y, target) {
    if (target.tagName === 'CANVAS') return true;
    var offset = $canvas.offset(),
        left = offset.left,
        top = offset.top;

    return x >= left && x <= left + $canvasWidth &&
           y >= top && y <= top + $canvasHeight;              
}
$('#mydiv').on('mousedown', '*', this, function(ev) {
    if (isCanvasClicked(ev.pageX, ev.pageY, ev.target)) {
        $canvas.fadeOut().fadeIn();
    }
});
于 2012-02-26T15:49:59.763 回答
1

正如已经提出的,这应该是最简单的解决方案:

http://jsfiddle.net/CUJ68/4/

$('canvas').on('mousedown', function(ev) {
    console.log(ev.target);
});
$('ul').on('mousedown', function(ev){
    $('canvas').mousedown();
});

如果您需要原始事件数据:

$('canvas').bind('mousedown', function(ev, parentEV) {
    if(parentEV){
        console.log(parentEV);
        alert("Canvas INdirectly clicked!");
    }else{
        console.log(ev);
        alert("Canvas directly clicked!");
    }
});
$('ul').on('mousedown', function(ev){
    $('canvas').trigger('mousedown', ev);
});
于 2012-02-26T15:52:28.260 回答
0

在这里,您有一个解决方案,包括在上面的元素上捕获点击事件,并在另一个元素上触发事件:注册对另一个元素下的元素的点击

于 2012-02-26T15:35:26.530 回答