不要在孩子身上引发悬停事件

时间:2012-05-17 19:10:09

标签: jquery css

我有一个带瓷砖的容器(草,水等),其中一些我有物品(边境精灵,树木和一般物品)。由于精灵的性质,所有项目都是64x64,而瓷砖只有32x32。

我的问题是我想在磁贴上触发悬停事件,但它们有时会被其他磁贴的项目遮挡。

下图显示了问题。当我想悬停树形图块时,厚绿色区域是真正悬停的图块。

the problem http://upload.cip.nu/pfile.php?file_id=2327

CSS:

#map_canvas .tile{
    height: 32px;
    position: absolute;
    width: 32px;
}
#map_canvas .tile .item{
    background-position: bottom right;
    background-repeat: no-repeat;
    bottom: 0;
    display: inline-block;
    height: 64px;
    margin: 0;
    padding: 0;
    position: absolute;
    right: 0;
}

HTML,简化:

<div class="tile" style="background-image: url(grass.png);"></div>
<div class="tile" style="background-image: url(grass.png);"></div>
<div class="tile" style="background-image: url(grass.png);">
    <div class="item" style="background-image(top-left-border.png);"></div>
</div>

这是现场演示http://sleavely.com/tiles/

我甚至不知道如何表达这个问题,但这里有:

是否有可能只触发父元素(.tile)上的事件,以便溢出的子元素(.item)不会混淆我真正悬停的哪个图块?

编辑:感谢@Brilliand我实施了以下

function figureOutTile(e){
    var $source = jQuery(e.srcElement);
    if($source.hasClass("item")){
        var $parent = $source.parent();
        var posx = $parent.attr("col");
        var posy = $parent.attr("row");
        if(e.offsetY <= 32){
            if(e.offsetX <= 32){
                return jQuery(".tile[col="+ (posx-1) +"][row="+ (posy-1) +"]");
            }else{
                return jQuery(".tile[col="+ posx +"][row="+ (posy-1) +"]");
            }
        }else{
            if(e.offsetX <= 32){
                return jQuery(".tile[col="+ (posx-1) +"][row="+ posy +"]");
            }else{
                return $parent;
            }
        }
    }else{
        return $source;
    }
}
jQuery("#map_viewport").on({
    mouseenter: function(e) {
        var $target = figureOutTile(e);
        $target.addClass('hovered');
    },
    mouseleave: function() {
        jQuery(".tile.hovered").removeClass('hovered');
    }
}, '.tile');​

3 个答案:

答案 0 :(得分:3)

$(".tile").children().on('mouseenter', function(e) { 
   e.stopPropogation(); 
});

$(".tile").on('mouseenter', function(e) { 
   if (this===e.target) {
      //do stuff
   }
});

编辑:

$("#map_viewport").on({
    mouseenter: function(e) {
        if (this===e.target) {
            $(element).addClass('someClass')
        }
    },
    mouseleave: function() {
        $(element).removeClass('someClass')
    }
}, '.tile');

答案 1 :(得分:1)

就你的浏览器而言,将鼠标悬停在一块瓷砖上的东西与悬停在瓷砖上的东西相同,而不是悬停在任何被覆盖的东西上。为了在您的特定情况下解决这个问题,我建议将您的悬停功能放在#map_canvas上,并在该功能中处理正在悬停的磁贴。对于矩形网格中的切片,这是一个简单的算术。

当然,要实现这一点,您需要包含一个mousemove事件(以检测鼠标从一个磁贴移动到另一个磁贴的时间),如果用户仍然悬停在该磁贴上,您应该包含退出该函数的代码。相同的瓷砖。

编辑:虽然这个答案已被接受,但这是基于我的评论的解决方案:

$(".tile").append($("<div/>", {
    css: {
        position: "absolute",
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        "z-index": 50
    }
}));

这似乎解决了所有带有项目的tile的问题,虽然它搞砸了你的:空声明。我之所以提到这主要是因为它更接近回答问题。

答案 2 :(得分:0)

编辑:如果事件冒泡确实存在问题并且您正在使用jQuery,请查看event.stopPropagation method

您是否尝试过添加z-index es?

    #map_canvas .tile{
        height: 32px;
        position: absolute;
        width: 32px;
        z-index: 1;
    }
    #map_canvas .tile .item{
        background-position: bottom right;
        background-repeat: no-repeat;
        bottom: 0;
        display: inline-block;
        height: 64px;
        margin: 0;
        padding: 0;
        position: absolute;
        right: 0;
        z-index: 2;
    }