2012-05-17 14 views
8

Tengo un contenedor con azulejos (hierba, agua, etc.) y en algunos de ellos tengo elementos (sprites de borde, árboles y elementos generales). Debido a la naturaleza de los sprites, todos los elementos son de 64x64, mientras que los mosaicos son solo de 32x32.No desencadenar evento de desplazamiento sobre niños

Mi problema es que quiero desencadenar un evento de desplazamiento en las teselas, pero a veces son sombreadas por elementos de otras teselas.

La imagen siguiente muestra el problema. El área verde gruesa es la que realmente se queda suspendida cuando quiero pasar el azulejo del árbol.

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

El 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; 
} 

El HTML, simplificado:

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

Aquí está la demostración en vivo http://sleavely.com/tiles/

yo no sé ni cómo expresar la pregunta, pero aquí va:

¿Es posible activar solo el evento en el elemento primario (.tile) para que los elementos secundarios (.item) no ofusquen qué mosaico realmente sobrevuelo?

EDIT: Gracias a @Brilliand he implementado la siguiente

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

¿Podemos ver su javascript? Nada en el código que publicó hasta ahora se refiere al vuelo estacionario. – Fresheyeball

+1

Guau, esta es una pregunta muy específica. Pero creo que todo se reduce a un evento burbujeante. – Jivings

+0

@Fresheyeball: ahora mismo es básicamente un 'jQuery (" # map_viewport "). On (" hover "," .tile ", función (e) {' que uso para alternar una clase en el mosaico. El problema es que el evento se desencadena en el mosaico incorrecto. – Sleavely

Respuesta

1

En lo que se refiere a su navegador, se cierne sobre algo que sobresale de un azulejo es el mismo que se cierne sobre la azulejo que sobresale, que no se cierne sobre lo que se está cubriendo. Para evitar esto en su situación específica, le sugiero que coloque su función de desplazamiento sobre #map_canvas, y que trabaje en esa función sobre qué mosaico se está pasando el cursor. Para los mosaicos en una cuadrícula rectangular, esto es aritmética simple.

Por supuesto, para que esto funcione tendrá que incluir un evento mousemove (para detectar cuando el mouse se mueve de una tesela a otra), y probablemente debería incluir código para salir de la función si el usuario todavía está sobrevolando el mismo azulejo

EDIT: Aunque esta respuesta ya ha sido aceptado, he aquí una solución basada en mi comentario:

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

Esto parece solucionar el problema para todos los azulejos con artículos sobre ellos, a pesar de que los tornillos hasta su : declaraciones vacíasLo menciono principalmente porque se acerca más a responder su pregunta como se le preguntó.

+0

También podría funcionar para insertar un div vacío y absolutamente posicionado con un alto índice z sobre cada tesela, esto podría interceptar el evento de desplazamiento antes de que llegue al elemento superpuesto. – Brilliand

+0

Creo que probaré esta solución más adelante, ya que probablemente no necesite Javascript en absoluto. – Sleavely

0

Editar: Si es de hecho un problema con burbujeo de eventos y está utilizando jQuery, echa un vistazo a la event.stopPropagation method.

¿Has intentado añadir 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.stopPropagation solo impide que el evento burbujee up, no proveniente de un niño. :( No estoy seguro de entender el propósito de z-index en este contexto, sin embargo. – Sleavely

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

o

$(".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

Intenté su segundo y tercer ejemplo, ninguno de los cuales funcionó. El tercer ejemplo solamente activado en fichas que no tenían hijos y no tenían mosaicos contiguos con elementos en ellos. :( – Sleavely

Cuestiones relacionadas