2012-05-17 11 views
8

Mam pojemnik z kafelkami (trawa, woda itp.), Aw niektórych z nich mam przedmioty (obramowania, drzewa i przedmioty ogólne). Ze względu na naturę sprite'ów wszystkie przedmioty mają rozmiar 64x64, a płytki są tylko 32x32.Nie wyzwalaj zdarzenia najechania na dzieci

Mój problem polega na tym, że chcę wywołać zdarzenie na kafelkach, ale czasami są one zacienione przez inne elementy kafli.

Zdjęcie poniżej pokazuje problem. Gruba zielona powierzchnia to kafelek, który staje się unerwiony, gdy chcę unieść kafelek drzewa.

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, uproszczone:

<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> 

Oto demo na żywo http://sleavely.com/tiles/

ja nawet nie wiem, jak wyrażenie pytanie, ale tutaj idzie:

Czy można wywołać zdarzenie tylko w elemencie nadrzędnym (.tile), aby przepełnione dzieci (.item) nie zaciemniały tego, który kafelek naprawdę unoszą?

EDIT: Dzięki @Brilliand I wdrożone następujące

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');​ 
+0

Czy możemy zobaczyć Twój javascript? Nic w kodzie, który wysłałeś do tej pory, nie dotyczy zawisu. – Fresheyeball

+1

Wow, to bardzo szczegółowe pytanie. Ale myślę, że sprowadza się to do bulgotania zdarzeń. – Jivings

+0

@Fresheyeball: W tej chwili jest to po prostu 'jQuery (" # map_viewport "). On (" hover "," .tile ", funkcja (e) {' której używam do przełączania klasy na kafelku. że zdarzenie uruchamia się na niewłaściwym kafelku – Sleavely

Odpowiedz

1

O ile Twoja przeglądarka jest zaniepokojony, unoszące się nad czymś wystający z płytki jest taka sama jak unoszące się nad płytka, z której wystaje, a nie unosi się nad tym, co jest zasłonięte. Aby obejść to w twojej konkretnej sytuacji, sugeruję umieszczenie funkcji najeżcej na #map_canvas i pracę nad tą funkcją, na której jest przewracany kafelek. W przypadku płytek w prostokątnej siatce jest to prosta arytmetyczna.

Oczywiście, aby to zadziałało, musisz uwzględnić zdarzenie mousemove (aby wykryć, kiedy mysz przesuwa się z jednego kafelka na drugi) i prawdopodobnie powinieneś dołączyć kod, aby wyjść z funkcji, jeśli użytkownik wciąż unosi się nad nią ta sama płytka.

EDIT: Chociaż ta odpowiedź została już przyjęta, oto rozwiązanie oparte na mój komentarz:

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

To wydaje się rozwiązać problem dla wszystkich płytek z elementów na nich, choć śrub zapasowych : puste deklaracje.Wspominam o tym głównie dlatego, że jest on bliższy odpowiedzi na zadane pytanie.

+0

Może również działać wstawianie pustego absolutnie umieszczonego elementu div z wysokim indeksem z na każdym kafelku, może to być w stanie przechwycić zdarzenie najechania, zanim dotrze do zachodzącego na siebie elementu. – Brilliand

+0

Myślę, że spróbuję tego rozwiązania później, ponieważ prawdopodobnie wcale nie potrzebuje JavaScript. – Sleavely

0

Edycja: Jeśli jest to rzeczywiście problem z bulgotanie zdarzeń i używasz jQuery, sprawdź event.stopPropagation method.

Czy próbowałeś/aś dodać 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; 
    } 
+0

event.stopPropagacja tylko przeszkadza wydarzeniu od bulgotania w górę, nie pochodząc od dziecka. :( Nie jestem pewien, czy rozumiem cel z-index w tym kontekście, jednak. – Sleavely

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

lub

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

EDIT:

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

Próbowałem twój drugi i trzeci przykład, z których żaden nie działał. wyzwalane na kafelkach które były bezdzietne i nie miały sąsiednich płytek z przedmiotami na nich. :( – Sleavely

Powiązane problemy