在另一个元素下的元素上注册点击

时间:2009-07-18 19:57:21

标签: javascript jquery

我的元素位于不透明度的元素下:0.5我希望能够点击。如何点击“穿过”最顶层的元素?

这是一个演示我的问题的例子。单击框以打开和关闭它们。您可以对其进行编辑on jsbin以试用您的解决方案。

如果您可以在悬停时切换框,则可获得奖励积分。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<title>Sandbox</title> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
<style type="text/css" media="screen"> 
body { background-color: #000; } 
.box {width: 50px; height: 50px; border: 1px solid white} 
.highlight {background-color: yellow;} 
</style>
<script type="text/javascript">
var dthen = new Date();
$('<div id="past">').css({'height':  (dthen.getMinutes()*60)+dthen.getSeconds() +'px'
            ,'position': 'absolute'
            ,'width': '200px'
            ,'top': '0px'
            ,'background-color': 'grey'
            ,'opacity': '0.5'
            })
        .appendTo("#container");

setInterval(function(){
    dNow = new Date();
    $('#past').css('height', ((dNow.getSeconds()+(dNow.getMilliseconds()/1000))*50)%300 +'px');
},10)

 $(".box").click(function(){
      $(this).toggleClass("highlight");
    });
</script>
</head> 
<body> 
  <div id="container"> 
     <div class="box" style="position:absolute; top: 25px; left: 25px;"></div> 
     <div class="box" style="position:absolute; top: 50px; left: 125px;"></div> 
     <div class="box" style="position:absolute; top: 100px; left: 25px;"></div> 
     <div class="box" style="position:absolute; top: 125px; left: 125px;"></div> 
     <div class="box" style="position:absolute; top: 225px; left: 25px;"></div> 
     <div class="box" style="position:absolute; top: 185px; left: 125px;"></div> 
  </div> 
</body> 
</html>

4 个答案:

答案 0 :(得分:20)

如果你最顶层的元素包含在下面的元素中,你可以让事件“冒泡”。如果不是,则必须手动触发点击。只需单击即可触发事件处理程序。

要手动触发事件,您可以执行以下操作:

$("#topelement").click(function() {
   $("#elementbelow").click();
   return false;
});

编辑(对评论的回应):

要枚举所有方框,你可以这样做(在我的头顶。没有测试,甚至不能没有语法错误)

$("#topelement").click(function(e) {
    $(".box").each(function() {
       // check if clicked point (taken from event) is inside element
       var mouseX = e.pageX;
       var mouseY = e.pageY;
       var offset = $(this).offset;
       var width = $(this).width();
       var height = $(this).height();

       if (mouseX > offset.left && mouseX < offset.left+width 
           && mouseY > offset.top && mouseY < offset.top+height)
         $(this).click(); // force click event
    });
});

答案 1 :(得分:17)

好的,所以我认为我会做两件事:(1)CSS3答案,尚未广泛采用,以及(2)其余的Javascript备份计划。 (对于不支持CSS部分的旧浏览器,不知道如何处理没有JS的用户)。请继续阅读...

首先:使用此CSS3代码使鼠标交互的上部元素“不可见”:

pointer-events: none;

这还不兼容跨浏览器。它只适用于SVG&amp; Gecko中的HTML元素&amp; Webkit浏览器,但仅限于Opera中的SVG元素,而不是IE中的。

根据MDN:

  

CSS属性指针事件允许   作者控制是否或何时   元素可能是鼠标的目标   事件。这个属性习惯了   指明在哪种情况下(如果   任何)鼠标事件应该“通过”   一个元素和目标无论是什么   “取而代之的是那个元素。”

以下是该文档:https://developer.mozilla.org/en/css/pointer-events

第二:对那些尚不支持此CSS的浏览器使用一些javascript功能检测。你必须自己滚动,类似于Modernizr,因为它还没有测试(据我所知)。我们的想法是你创建一个元素,将指针事件CSS应用于它,检查它,如果浏览器支持该功能,你将获得预期的结果,而不是null或undefined;然后破坏元素。无论如何,一旦你有功能检测,你可以使用jQuery或类似的方法将一个监听器附加到最上面的元素,并从中分配一个点击以点击其他东西。查看jQuery并使用click()函数获取更多信息(没有足够的声誉发布链接,sry)。

如果我以后有时间,我或许可以快速完成jsFiddle。我希望这会有所帮助。

答案 2 :(得分:2)

我已经将上面的代码修改为jquery函数,有人可能觉得它很有用:

查找替代点击元素:

$('.child').click(function(e) {
    $(this).siblingsUnderMouse(e).each(fn);
});

如果要忽略图像中的透明像素:

$('.child').click(function(e) {
    $(this).siblingsUnderMouse(e).each(function() {
        var clickOnVisiblePixel = $(this).isOnVisiblePixel(e);
    });
});

代码:

$.fn.reverse = [].reverse;
$.fn.siblingsUnderMouse = function(e, filter)
{
    filter = filter || '*';

    var arr = $();
    this.parent().children().filter(filter).reverse().each(function()
    {
        var t = $(this);
        // check if clicked point (taken from event) is inside element
        var x = (e.pageX - t.offset().left).toFixed();
        var y = (e.pageY - t.offset().top).toFixed();
        var w = t.width();
        var h = t.height();

        if (x < 0 || x >= w || y < 0 || y >= h)
            return;

        arr.push(t);
    });
    return arr;
}

$.fn.isOnVisiblePixel = function(e)
{
    if (e.type == 'mouseleave') return false;

    var t = this[0];
    if (!t || t.tagName != 'IMG')
        t = this.find('img')[0];
    if (!t) return;

    var w = $(t).width();
    var h = $(t).height();
    var o = $(t).offset();
    var x = (e.pageX - o.left).toFixed();
    var y = (e.pageY - o.top).toFixed();
    if (x < 0 || y < 0 || x >= w || y >= h)
        return false;

    var c = $('<canvas>')[0];
    c.width = w;
    c.height = h;

    var ctx = c.getContext('2d');
    ctx.drawImage(t, 0, 0, w, h);

    var a = ctx.getImageData(x, y, 1, 1).data[3];
    return (a > 128);
}

答案 3 :(得分:0)

我认为Lelando得到了正确的打击。 在我的情况下,我只使用css解决了你可以将指针事件:无插入 #past 元素。