2009-09-09 72 views
149

Estoy tratando de superponer un elemento en la parte superior de una página web (para dibujar gráficos arbitrarios), y he llegado al punto en el que puedo apílelo dentro de un elemento encima de todo, pero esto evita que el usuario haga clic en los enlaces/botones/etc. ¿Hay alguna manera de hacer que su contenido flote sobre todo (es semitransparente, por lo que aún se puede ver lo que está detrás) y hacer que el usuario interactúe con la capa debajo de él?HTML "superposición" que permite a los clics que caen a través de los elementos detrás de él

He encontrado mucha información sobre el modelo de eventos DOM, pero nada de eso resuelve el problema donde los botones y otros controles "nativos" nunca parecen obtener los clics en primer lugar.

+0

Ver también:. Http://stackoverflow.com/questions/3015422/forwarding-mouse-events-through-layers-divs/11935377 – kitchin

+0

'$ ("div") haga clic en (function (e) { e.preventDefault();}); 'Lo uso la mayoría de las veces –

Respuesta

3

Se puede utilizar una superposición con la opacidad de poner en orden a los botones/anclajes en la parte de atrás se quedan visibles, pero una vez que tenga que superpuesta sobre un elemento, no se puede haga clic en él.

+0

Creo que si la superposición es transparente (como en ningún fondo, una imagen transparente como fondo no funcionará), los clics caerán. Sin embargo, no estoy seguro si esto funciona para todos los navegadores. – mbillard

+0

Correcto, ya que así es como ocurre el clickjacking (el iframe transparente de pantalla completa se encuentra en la parte superior de la página). –

2

En general, esto no es una gran idea. Tomando su escenario, si tiene malas intenciones, podría ocultar todo debajo de su "superposición". Luego, cuando un usuario hace clic en un enlace que cree que debería llevarlo a bankofamerica.com, en su lugar desencadena el enlace oculto que lo lleva a myevilsite.com.

Dicho esto, la propagación de eventos obras, y si está dentro de una aplicación, no es un gran problema. El siguiente código es un ejemplo. Al hacer clic en el área azul aparece una alerta, aunque la alerta se establece en el área roja. Tenga en cuenta que el área naranja NO funciona, porque el evento se propagará a través de los elementos PARENT, por lo que su superposición debe ser dentro de sea cual sea el elemento en el que esté observando los clics. En su escenario, puede que no tenga suerte.

<html> 
<head> 
</head> 
<body> 
    <div id="outer" style="position:absolute;height:50px;width:60px;z-index:1;background-color:red;top:5px;left:5px;" onclick="alert('outer')"> 
     <div id="nested" style="position:absolute;height:50px;width:60px;z-index:2;background-color:blue;top:15px;left:15px;"> 
     </div> 
    </div> 
    <div id="separate" style="position:absolute;height:50px;width:60px;z-index:3;background-color:orange;top:25px;left:25px;"> 
    </div> 
</body> 
</html> 
+5

"Tomando su escenario, si tiene malas intenciones, puede ocultar todo debajo de su" superposición ". Luego, cuando un usuario hace clic en un enlace que cree que debería llevarlo a bankofamerica.com, en su lugar activa el enlace oculto que lo lleva a myevilsite.com ". - Eso ni siquiera tiene sentido. ¿Por qué tendría que tomarse la molestia? Podría usar js para ir allí, ¿por qué necesitaría activar un enlace oculto? –

+1

¡No hay malas intenciones aquí! Esto es estrictamente interno; solo tiene que funcionar en uno de Safari o Firefox exactamente en una computadora :) No me importa nada la portabilidad en este momento. Su idea es interesante, pero requiere anidar dentro del elemento, lo que no funciona para cosas como botones de formulario o enlaces, que es el caso de uso que describí en la publicación original :( –

+1

@Steven, lo sé, razón por la cual Mencioné que creo que no tienes suerte con ese enfoque. @Russell, si considera que puede hacer que un usuario realice acciones sin que ellos lo sepan, puede hacer cosas como iniciar la redirección de eventos del teclado, etc., lo que a su vez le permitirá ingresar nombres de archivos para cargar, y así sucesivamente . Esto fue un gran problema con flash no hace mucho tiempo, porque sin saberlo, podría encender su cámara web flash y/o controles de audio y enviar audio/video sin darse cuenta. – jvenema

35

Mi sugerencia sería que se podía capturar el evento clic en la superposición, ocultar la superposición, entonces refire el evento clic, a continuación, mostrar la superposición de nuevo. Sin embargo, no estoy seguro de si obtendrías un efecto de parpadeo.

[Actualización] Exactamente este problema y exactamente mi solución acaba de aparecer en este post: "Forwarding Mouse Events Through Layers". Sé que es probable que sea un poco tarde para el OP, pero por el bien de alguien que tenga este problema en el futuro, pensé que lo incluiría.

+3

El enlace que proporcionó es impresionante. En particular, me permitió conocer la propiedad de "eventos de puntero" de Mozilla que hace exactamente el truco. http://hacks.mozilla.org/2009/12/pointer-events-for-html-in-firefox-3-6/ – NicDumZ

+12

Básicamente, necesitas agregar 'pointer-events: none;' CSS al elemento de arriba para es "invisible" a los eventos. – lepe

+0

@lepe: <3 Todas estas complicaciones, cuando todo lo que realmente se necesitaba era su asombrosa y concisa solución. – VSO

5

En caso de que alguien más se está ejecutando en el mismo problema, la única solución que podría encontrar que me satisfizo era tener el lienzo cubre todo y luego elevar el índice Z de todos los elementos se puede hacer clic. No puede dibujar sobre ellos, pero al menos se puede hacer clic en ellos ...

6

Para el registro, un enfoque alternativo podría ser hacer que la capa clicable sea la superposición: la hace semitransparente y luego coloca la "superposición" imagen detrás de (de manera un tanto intuitiva, la imagen "superpuesta" podría ser opaca). Dependiendo de lo que intente hacer, es posible que pueda obtener exactamente el mismo efecto visual (de una imagen y una capa cliqueable superpuestas superpuestas una encima de la otra), mientras evita los problemas de capacidad de cliqueo (porque la "superposición" "de hecho está en el fondo).

0

¿Qué tal esto para IE ?:

onMouseDown: ocultar todos los elementos que podrían superponer el evento. Debido a que display: none visibility: hidden not realy works, empuje el div superpuesto fuera de la pantalla por un número fijo de píxeles. Después de un retraso, vuelva a colocar el div superpuesto con la misma cantidad de píxeles.

onmouseup: Mientras tanto este es el evento que quiera disparar.

 //script 
    var allclickthrough=[];   
    function hidedivover(){ 
       if(allclickthrough.length==0){ 
       allclickthrough=getElementsByClassName(document.body,"clickthrough");// if so .parentNode 
       } 
       for(var i=0;i<allclickthrough.length;i++){ 
       allclickthrough[i].style.left=parseInt(allclickthrough[i].style.left)+2000+"px"; 
       } 
       setTimeout(function(){showdivover()},1000); 
       } 
    function showdivover(){ 
      for(var i=0;i<allclickthrough.length;i++){ 
       allclickthrough[i].style.left=parseInt(allclickthrough[i].style.left)-2000+"px"; 
       } 
      }  
    //html 
    <span onmouseup="Dreck_he_got_me()">Click me if you can.</span> 
    <div onmousedown="hidedivover()" style="position:absolute" class="clickthrough">You'll don't get through!</div> 
-2

Estaba teniendo este problema al ver mi sitio web en un teléfono. Mientras intentaba cerrar la superposición, casi estaba haciendo clic en cualquier cosa debajo de la superposición. Una solución que encontré trabajando para mí solo es agregar la etiqueta a alrededor de toda la superposición

3

Mi equipo se encontró con este problema y lo resolvió muy bien.

  • agregue una clase "passthrough" o algo por el estilo de cada elemento que desee hacer clic y que esté debajo de la superposición.
  • para cada elemento ".passthrough" anexe un div y colóquelo exactamente encima de su elemento primario. agrega la clase "element-overlay" a este nuevo div.
  • El css ".element-overlay" debe tener un alto índice z (por encima de la superposición de la página) y los elementos deben ser transparentes.

Esto debería resolver su problema ya que los eventos en ".element-overlay" deberían aparecer hasta ".passthrough". Si todavía tiene problemas (no vimos ninguno hasta el momento), puede jugar con el enlace.

Esta es una mejora de la solución de @ jvenema.

Lo bueno de esto es que

  • no pasa por todos los eventos a todos los elementos. Solo los que quieres. (resuelto el argumento de @ jvenema)
  • Todos los eventos funcionarán correctamente. (pase el mouse por ejemplo).

Si tiene algún problema, por favor háganmelo saber para que pueda dar más detalles.

+0

Interesante, pero creo que realmente no entiendo. Sin embargo, trajo a otra idea: hacer que la capa real sea completamente transparente y colocarla encima de la superposición. Haz una copia no transparente y ponla a continuación. Se garantiza que todos los eventos funcionan, la pantalla puede estar equivocada si la copia no está sincronizada. WDYT? – maaartinus

97

Un truco tonto que hice fue establecer la altura del elemento a cero pero desbordamiento: visible; combinando esto con eventos de puntero: ninguno; parece cubrir todas las bases.

.overlay { 
    height:0px; 
    overflow:visible; 
    pointer-events:none; 
    background:none !important; 
} 
+0

Me gusta: funciona para mí siempre que la superposición sea completamente transparente, p. si solo se usa para colocar un mensaje/botón/imagen. – Tom

+24

No estoy seguro de por qué esta no es la respuesta aceptada o la más valorada. 'pointer-events: none' es la respuesta que estamos buscando aquí. – cazzer

+0

loco fácil, gracias! Funciona en los elementos svg también. –

Cuestiones relacionadas