javascript - tag - title title html
Registro de clics en un elemento que está debajo de otro elemento. (4)
Creo que Lelando tiene el golpe correcto. En mi caso, resolví usando solo css y puedes insertar eventos de puntero: ninguno en tu elemento #past .
Tengo elementos que están debajo de un elemento con opacidad: 0.5 en los que quiero poder hacer clic. ¿Cómo puedo hacer clic en "a través" del elemento superior?
Aquí hay un ejemplo que demuestra mi problema. Haga clic en las casillas para activarlas y desactivarlas. Puedes editarlo en jsbin para probar tu solución.
Puntos de bonificación si puede hacer que las cajas se activen al pasar el ratón.
<!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>
De acuerdo, hay dos cosas que creo que haría: (1) una respuesta de CSS3, que todavía no se ha adoptado ampliamente, y (2) un plan de respaldo de Javascript para el resto. (No estoy seguro de qué hacer con los usuarios sin JS en los navegadores antiguos que no admiten la parte CSS). Sigue leyendo
Primero: use este código CSS3 para que el elemento superior sea "invisible" a la interacción con el mouse:
pointer-events: none;
Esto todavía no es compatible con varios navegadores. Solo funciona en elementos SVG y HTML en los navegadores Gecko y Webkit, pero solo en elementos SVG en Opera, y no en absoluto en IE.
Por el MDN:
Los eventos de puntero de propiedad de CSS permiten a los autores controlar si un elemento puede ser el objetivo de un evento de mouse o cuándo. Esta propiedad se usa para especificar bajo qué circunstancia (si existe) un evento del mouse debe pasar por un elemento y apuntar a cualquier elemento que se encuentre debajo de ese elemento.
Aquí está la documentación: https://developer.mozilla.org/en/css/pointer-events
Segundo: use alguna Detección de funciones de javascript para aquellos navegadores que aún no admiten este CSS. Tendrá que rodar el suyo, similar a Modernizr , ya que aún no se prueba para esto (que yo sepa). La idea es que cree un elemento, aplique el CSS de eventos de puntero, lo compruebe y, si el navegador es compatible con la función, obtendrá el resultado esperado, en lugar de algo nulo o indefinido; entonces destruye el elemento. De todos modos, una vez que tenga la detección de características, puede usar jQuery o similar para adjuntar un oyente al elemento superior y asignar un clic para que haga clic en otra cosa. Echa un vistazo a jQuery y utiliza la función click () para obtener más información (no hay suficiente reputación para publicar el enlace, sry).
Si tengo tiempo más tarde, podría ser capaz de elaborar un jsFiddle rápido en él. Espero que esto ayude.
He modificado el código de arriba a función jQuery, alguien podría encontrarlo útil:
Buscar elementos alternativos en los que se hace clic:
$(''.child'').click(function(e) {
$(this).siblingsUnderMouse(e).each(fn);
});
Si quieres ignorar los píxeles transparentes en las imágenes:
$(''.child'').click(function(e) {
$(this).siblingsUnderMouse(e).each(function() {
var clickOnVisiblePixel = $(this).isOnVisiblePixel(e);
});
});
Código:
$.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);
}
Si el elemento superior está contenido dentro del elemento a continuación, puede dejar que el evento "fluya". Si no es así, tienes que activar el clic manualmente. No hay forma de activar el controlador de eventos simplemente haciendo clic.
Para disparar el evento manualmente, puedes hacer esto:
$("#topelement").click(function() {
$("#elementbelow").click();
return false;
});
EDITAR (respuesta a los comentarios):
Para enumerar todas las casillas, puede hacer esto (desde la parte superior de mi cabeza. Sin pruebas, ni siquiera podría estar libre de errores de sintaxis)
$("#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
});
});