Fai clic per div sugli elementi sottostanti


1593

Ho un divche ha background:transparent, insieme a border. Sotto questo div, ho più elementi.

Attualmente, sono in grado di fare clic sugli elementi sottostanti quando faccio clic all'esterno della sovrapposizione div. Tuttavia, non riesco a fare clic sugli elementi sottostanti quando si fa clic direttamente sulla sovrapposizione div.

Voglio essere in grado di fare clic su questo in divmodo da poter fare clic sugli elementi sottostanti.

Il mio problema

Risposte:


2616

Sì, è POSSIBILE farlo.

Utilizzando pointer-events: noneinsieme alle istruzioni condizionali CSS per IE11 (non funziona in IE10 o versioni precedenti), è possibile ottenere una soluzione compatibile con più browser per questo problema.

Usando AlphaImageLoader, puoi anche mettere .PNG/.GIFs trasparenti nella sovrapposizione dive far scorrere i clic verso gli elementi sottostanti.

CSS:

pointer-events: none;
background: url('your_transparent.png');

IE11 condizionale:

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='your_transparent.png', sizingMethod='scale');
background: none !important;

Ecco una pagina di esempio di base con tutto il codice.


7
cosa succede se sto usando transizioni o stati hover su quel div?
Manticore,

2
@Manticore Risposta breve: non puoi. In questo caso la risposta fornita non funziona.
Niels Abildgaard,

10
IE11 supporta pienamente gli eventi puntatore. Ciò significa che tutti i browser moderni lo supportano. Questa è una soluzione praticabile alla fine del 2014. caniuse.com/#search=pointer-events
Judah Gabriel Himango

Come notato da @Andy, questo interrompe lo scorrimento. Ho aperto un problema separato per vedere se c'è una soluzione a questo stackoverflow.com/questions/41592349/…
Oliver Joseph Ash,

1
@Manticore Ho scoperto che puoi sovrascrivere "pointer-events: none;" per l'elemento nidificato, in modo da poter scrivere qualcosa bypassato dal clic con qualcosa che ottenga il clic e più, per le parti sovrascritte è possibile utilizzare gli effetti e fare clic
Luca C.

292

Anche bello sapere ...
È possibile disabilitare gli eventi puntatore in un elemento padre (probabilmente div trasparente) ma è ancora abilitato per i suoi elementi figlio.
Ciò è utile se si lavora con più div layer sovrapposti, in cui si desidera poter fare clic su elementi figlio, pur facendo in modo che i layer principali non reagiscano su alcun evento del mouse.

Per questo tutti i div parenting ottengono pointer-events: nonee i relativi figli cliccabili ottengono riattivati ​​gli eventi puntatorepointer-events: auto

.parent {
    pointer-events:none;        
}
.child {
    pointer-events:auto;
}

<div class="some-container">
   <ul class="layer-0 parent">
     <li class="click-me child"></li>
     <li class="click-me child"></li>
   </ul>

   <ul class="layer-1 parent">
     <li class="click-me-also child"></li>
     <li class="click-me-also child"></li>
   </ul>
</div>

4
Perfetto, questo è proprio quello di cui avevo bisogno!
RobbyReindeer,

1
super utile, grazie
SpaceBear il

43

Consentire all'utente di fare clic su un divelemento sottostante dipende dal browser. Tutti i browser moderni, inclusi Firefox, Chrome, Safari e Opera, comprendono pointer-events:none.

Per IE, dipende dallo sfondo. Se lo sfondo è trasparente, il click-through funziona senza che tu debba fare nulla. D'altra parte, per qualcosa del genere background:white; opacity:0; filter:Alpha(opacity=0);, IE ha bisogno dell'inoltro manuale di eventi.

Vedi un test JSFiddle e gli eventi del puntatore CanIUse .


20

Sto aggiungendo questa risposta perché non l'ho vista qui per intero. Sono stato in grado di farlo utilizzando elementFromPoint. Quindi in poche parole:

  • allegare un clic al div che si desidera fare clic
  • nascondilo
  • determinare su quale elemento si trova il puntatore
  • attiva il clic sull'elemento lì.
var range-selector= $("")
    .css("position", "absolute").addClass("range-selector")
    .appendTo("")
    .click(function(e) {
        _range-selector.hide();

        $(document.elementFromPoint(e.clientX,e.clientY)).trigger("click");
    });

Nel mio caso il div overlaying è assolutamente posizionato, non sono sicuro che questo faccia la differenza. Funziona almeno su IE8 / 9, Safari Chrome e Firefox.


12
  1. Nascondi sovrapponendo l'elemento
  2. Determina le coordinate del cursore
  3. Ottieni elementi su quelle coordinate
  4. Fai clic sull'elemento
  5. Mostra di nuovo l'elemento di sovrapposizione
$('#elementontop').click(e => {
    $('#elementontop').hide();
    $(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");
    $('#elementontop').show();
});

Hai dimenticato di chiudere gli apostrofi? Forse $('#elementontop)dovrebbe essere $('#elementontop')?
johannchopin,

10

Ho dovuto fare questo e ho deciso di prendere questo percorso:

$('.overlay').click(function(e){
    var left = $(window).scrollLeft();
    var top = $(window).scrollTop();

    //hide the overlay for now so the document can find the underlying elements
    $(this).css('display','none');
    //use the current scroll position to deduct from the click position
    $(document.elementFromPoint(e.pageX-left, e.pageY-top)).click();
    //show the overlay again
    $(this).css('display','block');
});

6

Attualmente lavoro con fumetti di tela. Ma poiché il fumetto con il puntatore è racchiuso in un div, alcuni link sottostanti non sono più in grado di fare clic. Non posso usare extjs in questo caso. Vedi l'esempio di base per il mio tutorial sull'aerostato vocale richiede HTML5

Così ho deciso di raccogliere tutte le coordinate dei collegamenti dall'interno dei palloncini in un array.

var clickarray=[];
function getcoo(thatdiv){
         thatdiv.find(".link").each(function(){
                 var offset=$(this).offset();           
                 clickarray.unshift([(offset.left),
                                     (offset.top),
                                     (offset.left+$(this).width()),
                                     (offset.top+$(this).height()),
                                     ($(this).attr('name')),
                                     1]);
                                     });
         }

Chiamo questa funzione su ogni (nuovo) fumetto. Cattura le coordinate degli angoli sinistro / superiore e destro / basso di un link.class - inoltre l'attributo name per cosa fare se qualcuno fa clic su quelle coordinate e mi è piaciuto impostare un 1, il che significa che non è stato cliccato jet . E sposta questo array sul clickarray. Puoi usare anche push.

Per lavorare con quell'array:

$("body").click(function(event){
          event.preventDefault();//if it is a a-tag
          var x=event.pageX;
          var y=event.pageY;
          var job="";
          for(var i in clickarray){
              if(x>=clickarray[i][0] && x<=clickarray[i][2] && y>=clickarray[i][1] && y<=clickarray[i][3] && clickarray[i][5]==1){
                 job=clickarray[i][4];
                 clickarray[i][5]=0;//set to allready clicked
                 break;
                }
             }
          if(job.length>0){   
             // --do some thing with the job --
            }
          });

Questa funzione prova le coordinate di un evento click body o se è già stato cliccato e restituisce l'attributo name. Penso che non sia necessario andare più a fondo, ma vedi che non è così complicato. La speranza è stata animare ...


4

non funziona in questo modo. il problema consiste nel controllare manualmente le coordinate del clic del mouse sull'area occupata da ciascun elemento.

l'area occupata da un elemento può essere trovata per 1. ottenere la posizione dell'elemento rispetto alla parte superiore sinistra della pagina e 2. la larghezza e l'altezza. una libreria come jQuery lo rende piuttosto semplice, anche se può essere fatto in js semplice. l'aggiunta di un gestore di eventi per l'oggetto fornirà aggiornamenti continui della posizione del mouse dalla parte superiore e sinistro della pagina. decidere se il mouse si trova su un determinato oggetto consiste nel verificare se la posizione del mouse si trova tra i bordi sinistro, destro, superiore e inferiore di un elemento.mousemovedocument


2
Come accennato in precedenza, puoi ottenere ciò utilizzando i CSS {pointer-events: none;} sul tuo contenitore trasparente.
Empereol,

4

No, non è possibile fare clic su "attraverso" un elemento. Puoi ottenere le coordinate del clic e provare a capire quale elemento si trovava sotto l'elemento cliccato, ma questo è davvero noioso per i browser che non lo hanno document.elementFromPoint. Quindi devi ancora emulare l'azione predefinita del clic, che non è necessariamente banale a seconda di quali elementi hai sotto.

Poiché hai un'area della finestra completamente trasparente, probabilmente starai meglio implementandola come elementi di bordo separati all'esterno, lasciando l'area centrale libera da ostacoli in modo da poter semplicemente fare clic direttamente.


4

Un'altra idea da provare (situazionalmente) sarebbe:

  1. Metti il ​​contenuto che desideri in un div;
  2. Posiziona l'overlay senza clic sull'intera pagina con un indice z più alto,
  3. crea un'altra copia ritagliata del div originale
  4. overlay e abs posizionano il div della copia nello stesso posto del contenuto originale di cui si desidera fare clic con un indice z ancora più alto?

qualche idea?


2

Penso che tu possa prendere in considerazione la possibilità di cambiare il tuo markup. Se non sbaglio, ti piacerebbe mettere un livello invisibile sopra il documento e il tuo markup invisibile potrebbe precedere l'immagine del documento (è corretto?).

Invece, propongo di mettere l'invisibile subito dopo l'immagine del documento ma cambiando la posizione in assoluta.

Nota che hai bisogno di un elemento genitore per avere position: relative e quindi sarai in grado di usare questa idea. Altrimenti il ​​tuo livello assoluto verrà posizionato proprio nell'angolo in alto a sinistra.

Un elemento di posizione assoluta viene posizionato rispetto al primo elemento padre che ha una posizione diversa da statica. Se non viene trovato tale elemento, il blocco contenitore è html

Spero che sia di aiuto. Vedi qui per maggiori informazioni sul posizionamento CSS.


2

Basta avvolgere il atag attorno a tutto l'estrazione HTML, ad esempio

<a href="/categories/1">
  <img alt="test1" class="img-responsive" src="/assets/photo.jpg" />
  <div class="caption bg-orange">
    <h2>
      test1
    </h2>
  </div>
</a>

nel mio esempio la mia classe di didascalia ha effetti hover, che con pointer-events: none; perderai semplicemente

il confezionamento del contenuto manterrà i tuoi effetti al passaggio del mouse e puoi fare clic su tutte le immagini, div inclusa, saluti!


buon punto! grazie
Mr.Vertigo

1

Puoi posizionare un overlay AP come ...

#overlay {
  position: absolute;
  top: -79px;
  left: -60px;
  height: 80px;
  width: 380px;
  z-index: 2;
  background: url(fake.gif);
}
<div id="overlay"></div>

mettilo dove non vuoi, ad es. Funziona in tutto.


1

Un modo più semplice sarebbe incorporare l'immagine di sfondo trasparente usando gli URI dei dati come segue:

.click-through {
    pointer-events: none;
    background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}

0

Penso che event.stopPropagation();dovrebbe essere menzionato anche qui. Aggiungi questo alla funzione Click del tuo pulsante.

Impedisce all'evento di gorgogliare l'albero del DOM, impedendo a qualsiasi gestore padre di essere informato dell'evento.


0

Questa non è una risposta precisa alla domanda, ma può aiutare a trovare una soluzione alternativa.

Avevo un'immagine che mi nascondevo al caricamento della pagina e che visualizzavo quando aspettavo una chiamata AJAX e poi mi nascondevo di nuovo ...

Ho trovato l'unico modo per visualizzare la mia immagine durante il caricamento della pagina, quindi farla scomparire e poter fare clic sulle cose in cui era posizionata l'immagine prima di nasconderla era mettere l'immagine in un DIV, rendere la dimensione del DIV 10x10 pixel o piccola abbastanza per evitare che causi un problema, quindi nascondere il div contenente. Ciò ha permesso all'immagine di traboccare il div mentre era visibile e quando il div era nascosto, solo l'area div era influenzata dall'impossibilità di fare clic sugli oggetti sottostanti e non sull'intera dimensione dell'immagine contenuta e visualizzata dal DIV.

Ho provato tutti i metodi per nascondere l'immagine tra cui CSS display = none / block, opacity = 0, nascondendo l'immagine con hidden = true. Tutto ciò ha comportato che la mia immagine fosse nascosta, ma l'area in cui veniva visualizzata si comportava come se ci fosse una copertura sulle cose sottostanti, quindi i clic e così via non avrebbero agito sugli oggetti sottostanti. Una volta che l'immagine era all'interno di un minuscolo DIV e ho nascosto il minuscolo DIV, l'intera area occupata dall'immagine era chiara e solo la minuscola area sotto il DIV che ho nascosto era interessata, ma mentre la rendevo abbastanza piccola (10x10 pixel), il problema è stato risolto (sorta di).

Ho scoperto che questa è una soluzione sporca per quello che dovrebbe essere un problema semplice, ma non sono stato in grado di trovare alcun modo per nascondere l'oggetto nel suo formato nativo senza un contenitore. Il mio oggetto era in forma di ecc. Se qualcuno ha un modo migliore, per favore fatemelo sapere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.