2009-09-09 14 views
149

Sto cercando di sovrapporre un elemento in cima a una pagina Web (per disegnare grafica arbitraria), e sono arrivato al punto in cui posso impilarlo all'interno di un elemento in cima a tutto, ma questo impedisce all'utente di fare clic su qualsiasi link/pulsanti/ecc. C'è un modo per rendere il suo contenuto mobile su tutto (è semi-trasparente, così puoi ancora vedere cosa c'è dietro) e l'utente interagire con il livello sottostante?HTML "overlay" che consente ai clic di passare attraverso elementi dietro di esso

Ho trovato molte informazioni sul modello di eventi DOM, ma nessuna di esse risolve il problema in cui i pulsanti e altri controlli "nativi" non sembrano mai ottenere i clic in primo luogo.

+0

Vedi anche:. Http://stackoverflow.com/questions/3015422/forwarding-mouse-events-through-layers-divs/11935377 – kitchin

+0

'$ ("div") clicca (function (e) { e.preventDefault();}); 'Uso la maggior parte delle volte –

risposta

3

È possibile utilizzare una sovrapposizione con il set di opacità in modo che i pulsanti/ancore nella parte posteriore rimangano visibili, ma una volta che si ha sovrapposizione su un elemento, non è possibile fare clic.

+0

Penso che se l'overlay è trasparente (come in nessuno sfondo, un'immagine trasparente come sfondo non funzionerà), i clic cadranno. Non sono sicuro se funziona comunque per tutti i browser. – mbillard

+0

Corretto, poiché si verifica il tipo di clickjacking (l'iframe trasparente a schermo intero si trova sulla parte superiore di una pagina). –

2

Generalmente, questa non è una grande idea. Prendendo il tuo scenario, se avevi intenzioni malvagie, potresti nascondere tutto sotto il tuo "overlay". Quindi, quando un utente fa clic su un link che ritiene debba portarli su bankofamerica.com, attiva invece il collegamento nascosto che li porta a myevilsite.com.

Detto questo, il bubbling degli eventi funziona e, se è all'interno di un'applicazione, non è un grosso problema. Il seguente codice è un esempio. Facendo clic sull'area blu viene visualizzato un avviso, anche se l'avviso è impostato sull'area rossa. Nota che l'area arancione NON funziona, perché l'evento si propagherà attraverso gli elementi PARENT, quindi l'overlay deve essere all'interno di qualsiasi elemento su cui stai osservando i clic. Nel tuo scenario, potresti essere sfortunato.

<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

"Prendendo il tuo scenario, se avevi intenzioni malvagie, potresti nascondere tutto sotto il tuo" overlay ".Quando, un utente fa clic su un link che pensano dovrebbe portarli su bankofamerica.com, invece attiva il link nascosto che li porta a myevilsite.com. " - Non ha nemmeno senso. Perché avrebbe bisogno di andare nei guai. Poteva semplicemente usare js per andare lì, perché avrebbe dovuto attivare un collegamento nascosto? –

+1

Nessuna intenzione malvagia qui! Questo è strettamente in-house; deve solo lavorare su uno di Safari o Firefox su un solo computer :) Al momento non mi interessa nulla della portabilità. La tua idea è interessante, ma richiede l'annidamento all'interno dell'elemento - che non funziona per cose come pulsanti o link del modulo, che è il caso d'uso che ho descritto nel post originale :( –

+1

@Steven, lo so, ed è per questo che Ho detto che penso che tu sia sfortunato per questo approccio. @Russell, se consideri che è possibile che un utente esegua azioni senza che lo sappiano, puoi fare cose come iniziare a reindirizzare gli eventi di tastiera, ecc. Che, a sua volta, ti consentirebbero di inserire nomi di file per il caricamento, e così via . Questo è stato un grosso problema con il flash non molto tempo fa, perché senza saperlo, è possibile accendere la webcam flash e/oi controlli audio e inviare audio/video senza rendersene conto. – jvenema

35

Il mio suggerimento sarebbe che si potrebbe catturare l'evento click con l'overlay, nascondere la sovrapposizione, quindi refire l'evento click, quindi visualizzare nuovamente la sovrapposizione. Non sono sicuro di ottenere comunque un effetto di sfarfallio.

[Aggiorna] Esattamente questo problema ed esattamente la mia soluzione è apparsa in questo post: "Forwarding Mouse Events Through Layers". So che probabilmente è un po 'tardi per l'OP, ma per il bene di qualcuno che ha questo problema in futuro, penso che lo includerei.

+3

Il link che hai fornito è fantastico. In particolare, mi ha permesso di conoscere la proprietà "pointer-events" di Mozilla che fa esattamente il trucco. http://hacks.mozilla.org/2009/12/pointer-events-for-html-in-firefox-3-6/ – NicDumZ

+12

Fondamentalmente è necessario aggiungere 'pointer-events: none;' CSS all'elemento precedente è "invisibile" agli eventi. – lepe

+0

@lepe: <3 Tutte queste complicazioni, quando tutto ciò che era veramente necessario era la tua fantastica soluzione concisa. – VSO

5

Nel caso in cui qualcun altro stia correndo verso lo stesso problema, l'unica soluzione che ho trovato che mi soddisfaceva era che la tela coprisse tutto e quindi aumentasse l'indice Z di tutti gli elementi cliccabili. Non è possibile disegnare su di essi, ma almeno sono cliccabili ...

6

Per la cronologia un approccio alternativo potrebbe essere quello di rendere il livello cliccabile della sovrapposizione: lo si rende semitrasparente e quindi si posiziona la "sovrapposizione" image dietro (un po 'controintuitivamente, l'immagine "sovrapposizione" potrebbe quindi essere opaca). A seconda di ciò che stai cercando di fare, potresti essere in grado di ottenere esattamente lo stesso effetto visivo (di un'immagine e di un livello cliccabile sovrapposti semi-trasparente l'uno sopra l'altro), evitando i problemi di cliccabilità (perché l'overlay "è infatti sullo sfondo).

0

Che ne dite di questo per IE ?:

onmousedown: Nascondi tutti gli elementi che potrebbero sovrapporre l'evento. Perché display: nessuna visibilità: hidden non funziona davvero, spingere il div overlay fuori dallo schermo per un numero fisso di pixel. Dopo un ritardo, spingere indietro il div overlay con lo stesso numero di pixel.

onmouseup: Nel frattempo questo è l'evento che ti piace sparare.

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

Ho riscontrato questo problema durante la visualizzazione del mio sito Web su un telefono. Mentre stavo cercando di chiudere la sovrapposizione, stavo praticamente facendo clic su qualsiasi cosa sotto l'overlay. Una soluzione che ho trovato utile è aggiungere il tag a all'intero overlay

3

Il mio team ha riscontrato questo problema e l'ha risolto molto bene.

  • aggiungere una classe "passthrough" o qualcosa a ciascun elemento che si desidera fare clic e che si trova sotto l'overlay.
  • per ciascun elemento ".passthrough" aggiungi un div e posizionalo esattamente sopra il suo genitore. aggiungi la classe "elemento-sovrapposizione" a questo nuovo div.
  • Il css ".element-overlay" dovrebbe avere un alto indice z (sopra l'overlay della pagina) e gli elementi dovrebbero essere trasparenti.

Questo dovrebbe risolvere il tuo problema in quanto gli eventi su ".element-overlay" dovrebbero apparire ".passthrough". Se hai ancora problemi (non li abbiamo visti finora), puoi giocare con la rilegatura.

Questo è un miglioramento della soluzione di @ jvenema.

La cosa bella di questo è che

  • non si passa attraverso tutti gli eventi a tutti gli elementi. Solo quelli che vuoi (risolto l'argomento @ jvenema)
  • Tutti gli eventi funzioneranno correttamente. (passa il mouse ad esempio).

Se avete problemi per favore fatemelo sapere così posso elaborare.

+0

Interessante, ma credo di non capirlo davvero. Tuttavia, ha portato a un'altra idea: rendere il vero strato completamente trasparente e metterlo sopra la sovrapposizione. Crea una copia non trasparente e mettila sotto. Tutti gli eventi sono garantiti per funzionare, il display potrebbe essere sbagliato se la copia non è sincronizzata. WDYT? – maaartinus

97

Un trucco sciocco che ho fatto è stato di impostare l'altezza dell'elemento a zero, ma traboccare: visibile; combinando questo con eventi-puntatore: nessuno; sembra coprire tutte le basi.

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

Mi piace - funziona per me purché la sovrapposizione sia completamente trasparente, ad es. se è appena usato per posizionare un messaggio/pulsante/immagine. – Tom

+24

Non sono sicuro del motivo per cui questa non è la risposta accettata o la più votata. 'pointer-events: none' è la risposta che stiamo cercando qui. – cazzer

+0

pazzo facile, grazie! Funziona anche su elementi svg. –

Problemi correlati