8

私はタイル(草、水など)の入ったコンテナを持っており、それらのいくつかにはアイテム(ボーダースプライト、木、および一般的なアイテム)があります。スプライトの性質上、すべてのアイテムは64x64ですが、タイルは32x32のみです。

私の問題は、タイルでホバーイベントをトリガーしたいのですが、別のタイルのアイテムによってシャドウされることがあります。

下の画像は問題を示しています。濃い緑色の領域は、ツリータイルをホバーしたいときに実際にホバーされるタイルです。

問題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');​
4

3 に答える 3

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');
于 2012-05-17T19:14:18.483 に答える
1

ブラウザに関する限り、タイルから突き出ているものにカーソルを合わせるのは、覆い隠されているものにカーソルを合わせるのではなく、突き出ているタイルにカーソルを合わせるのと同じです。特定の状況でこれを回避するには、ホバー関数を#map_canvasに配置し、その関数でどのタイルがホバーされているかを確認することをお勧めします。長方形グリッドのタイルの場合、これは単純な計算です。

もちろん、これを機能させるには、mousemoveイベント(マウスが1つのタイルから別のタイルに移動するタイミングを検出するため)を含める必要があります。ユーザーが同じタイルにカーソルを合わせている場合は、関数を終了するコードを含める必要があります。

編集:この回答はすでに受け入れられていますが、これが私のコメントに基づく解決策です:

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

これにより、:empty宣言が台無しになりますが、アイテムが含まれるすべてのタイルの問題が修正されるようです。私が言及するのは、主に質問に答えるのに近いからです。

于 2012-05-17T19:40:34.947 に答える
0

編集:それが実際にイベントバブリングの問題であり、jQueryを使用している場合は、event.stopPropagationメソッドを確認してください。

z-indexesを追加してみましたか?

    #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;
    }
于 2012-05-17T19:13:31.183 に答える