Kliknij div do podstawowych elementów

1590

Mam, divże ma background:transparent, wraz z border. Pod tym divmam więcej elementów.

Obecnie jestem w stanie kliknąć podstawowe elementy, gdy kliknę poza nakładką div. Nie mogę jednak kliknąć podstawowych elementów, klikając bezpośrednio nakładkę div.

Chcę móc przez to klikać, divaby móc klikać podstawowe elementy.

Mój problem

Ryan
źródło

Odpowiedzi:

2612

Tak, MOŻE to zrobić.

Korzystając pointer-events: nonez instrukcji warunkowych CSS dla IE11 (nie działa w IE10 lub niższej), możesz uzyskać rozwiązanie tego problemu kompatybilne z różnymi przeglądarkami.

Używając AlphaImageLoader, możesz nawet umieścić przezroczyste .PNG/.GIFs w nakładce divi przepuszczać kliknięcia do elementów pod spodem.

CSS:

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

Warunek IE11:

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

Oto podstawowa przykładowa strona z całym kodem.

LawrenceKSRealEstate
źródło
7
co jeśli korzystam z przejść lub stanów aktywowania na tym div?
Manticore
2
@Manticore Krótka odpowiedź: Nie możesz. W takim przypadku podana odpowiedź nie działa.
Niels Abildgaard
10
IE11 w pełni obsługuje zdarzenia wskaźnika. Oznacza to, że wszystkie nowoczesne przeglądarki obsługują to. Jest to wykonalne rozwiązanie na koniec 2014 roku. Caniuse.com/#search=pointer-events
Judah Gabriel Himango
Jak zauważył @Andy, przerywa to przewijanie. Otworzyłem osobny problem, aby sprawdzić, czy istnieje rozwiązanie tego stackoverflow.com/questions/41592349/...
Oliver Joseph Ash
1
@ Mantoreore Odkryłem, że możesz zastąpić „zdarzenia wskaźnika: brak;” dla elementu zagnieżdżonego, aby można było napisać coś pomijanego przez kliknięcie z czymś, co powoduje kliknięcie i więcej, w przypadku nadpisanych części można używać efektów i klikać
Luca C.
292

Również miło wiedzieć ...
Możesz wyłączyć zdarzenia wskaźnika w elemencie nadrzędnym (prawdopodobnie przezroczysty div), ale nadal włączać dla jego elementów potomnych.
Jest to przydatne, jeśli pracujesz z wieloma nakładającymi się warstwami div, w których chcesz mieć możliwość klikania elementów potomnych, a warstwy macierzyste nie reagują na żadne zdarzenia myszy.

W tym celu wszystkie divy rodzicielskie otrzymują, pointer-events: nonea ich klikalne dzieci otrzymują wskaźniki-zdarzeń ponownie włączone przezpointer-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>
Wszystko jest jednym
źródło
4
Idealnie, właśnie tego potrzebowałem!
RobbyReindeer
1
super pomocny, dzięki
SpaceBear
43

Zezwolenie użytkownikowi na kliknięcie divelementu bazowego zależy od przeglądarki. Wszystkie nowoczesne przeglądarki, w tym Firefox, Chrome, Safari i Opera, rozumieją pointer-events:none.

W przypadku IE zależy to od tła. Jeśli tło jest przezroczyste, klikanie działa bez potrzeby wykonywania jakichkolwiek czynności. Z drugiej strony, dla czegoś takiego background:white; opacity:0; filter:Alpha(opacity=0);, IE wymaga ręcznego przekazywania zdarzeń.

Zobacz test JSFiddle i zdarzenia wskaźnika CanIUse .

Vladimir Prodan
źródło
20

Dodaję tę odpowiedź, ponieważ nie widziałem jej tutaj w całości. Byłem w stanie to zrobić za pomocą elementFromPoint. Więc w zasadzie:

  • dołącz kliknięcie do div, który chcesz kliknąć
  • Ukryj to
  • określ element, na którym znajduje się wskaźnik
  • strzel tam kliknięciem elementu.
var range-selector= $("")
    .css("position", "absolute").addClass("range-selector")
    .appendTo("")
    .click(function(e) {
        _range-selector.hide();

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

W moim przypadku nakładający się div jest absolutnie ustawiony - nie jestem pewien, czy to robi różnicę. Działa to przynajmniej w IE8 / 9, Safari Chrome i Firefox.

Tim
źródło
12
  1. Ukryj nakładanie elementu
  2. Określ współrzędne kursora
  3. Uzyskaj element na tych współrzędnych
  4. Trigger kliknij element
  5. Pokaż ponownie element nakładający
$('#elementontop').click(e => {
    $('#elementontop').hide();
    $(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");
    $('#elementontop').show();
});
wcloister
źródło
Czy zapomniałeś zamknąć apostrofy? Może $('#elementontop)powinno być $('#elementontop')?
johannchopin
10

Musiałem to zrobić i postanowiłem wybrać tę trasę:

$('.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');
});
Matthew Grima
źródło
6

Obecnie pracuję z balonami na płótnie. Ale ponieważ balon ze wskaźnikiem jest zawinięty w div, niektóre łącza pod nim nie są już w stanie kliknąć. W tym przypadku nie mogę używać extjs. Zobacz podstawowy przykład mojego samouczka z dymkiem wymaga HTML5

Postanowiłem więc zebrać wszystkie współrzędne łącza z wnętrza balonów w jednym szeregu.

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]);
                                     });
         }

Wywołuję tę funkcję na każdym (nowym) balonie. Pobiera współrzędne lewego / górnego i prawego / dolnego rogu linku. Klasa - dodatkowo atrybut name dla tego, co zrobić, jeśli ktoś kliknie te współrzędne, a ja uwielbiam ustawiać 1, co oznacza, że ​​nie został kliknięty odrzutowiec . I cofnij tę tablicę do tablicy kliknięć. Możesz też użyć push.

Aby pracować z tą tablicą:

$("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 --
            }
          });

Ta funkcja sprawdza współrzędne zdarzenia kliknięcia ciała lub czy zostało już kliknięte i zwraca atrybut name. Myślę, że nie trzeba wchodzić głębiej, ale widzicie, że nie jest to takie skomplikowane. Nadzieja się skończyła ...

BF
źródło
4

to nie działa w ten sposób. obejście polega na ręcznym sprawdzeniu współrzędnych kliknięcia myszą w stosunku do obszaru zajmowanego przez każdy element.

obszar zajmowany przez element można znaleźć poprzez 1. uzyskanie położenia elementu względem lewego górnego rogu strony oraz 2. szerokości i wysokości. biblioteka taka jak jQuery sprawia, że ​​jest to dość proste, chociaż można to zrobić w zwykłym js. dodanie mousemovemodułu obsługi zdarzeń dla documentobiektu zapewni ciągłe aktualizacje pozycji myszy od góry i po lewej stronie. decyzja, czy wskaźnik myszy znajduje się nad danym obiektem, polega na sprawdzeniu, czy położenie myszy znajduje się między lewą, prawą, górną i dolną krawędzią elementu.

lincolnk
źródło
2
Jak wspomniano powyżej, możesz to osiągnąć za pomocą CSS {pointer-events: none;} na przezroczystym pojemniku.
Empereol,
4

Nie, nie można kliknąć elementu „przez”. Możesz uzyskać współrzędne kliknięcia i spróbować ustalić, który element znajdował się pod klikniętym elementem, ale jest to naprawdę nudne w przypadku przeglądarek, które go nie mają document.elementFromPoint. Następnie nadal musisz emulować domyślną akcję klikania, co niekoniecznie jest trywialne w zależności od tego, jakie elementy masz pod nim.

Ponieważ masz w pełni przezroczysty obszar okna, prawdopodobnie lepiej będzie, jeśli zastosujesz go jako oddzielne elementy obramowania na zewnątrz, pozostawiając obszar środkowy wolny od przeszkód, dzięki czemu możesz po prostu kliknąć prosto.

Bobin
źródło
4

Innym pomysłem (sytuacyjnym) byłoby:

  1. Umieść treść, którą chcesz w div;
  2. Nałóż nakładkę nie klikającą na całą stronę z wyższym indeksem Z,
  3. wykonaj kolejną przyciętą kopię oryginalnego pliku div
  4. nakładka i abs ustawia div div w tym samym miejscu, co oryginalna treść, którą chcesz klikać z jeszcze wyższym indeksem Z?

jakieś pomysły?

Adam
źródło
2

Myślę, że możesz rozważyć zmianę znaczników. Jeśli się nie mylę, chciałbyś umieścić niewidoczną warstwę nad dokumentem, a twój niewidoczny znacznik może poprzedzać obraz dokumentu (czy to prawda?).

Zamiast tego proponuję umieścić niewidzialne zaraz za obrazem dokumentu, ale zmieniając pozycję na absolutną.

Zauważ, że potrzebujesz elementu nadrzędnego, aby mieć pozycję: względną, a wtedy będziesz mógł skorzystać z tego pomysłu. W przeciwnym razie warstwa bezwzględna zostanie umieszczona w lewym górnym rogu.

Element pozycji absolutnej jest pozycjonowany względem pierwszego elementu macierzystego, który ma pozycję inną niż statyczna. Jeśli taki element nie zostanie znaleziony, blokiem zawierającym jest html

Mam nadzieję że to pomoże. Zobacz tutaj, aby uzyskać więcej informacji na temat pozycjonowania CSS.

Julianm
źródło
2

Wystarczy na przykład owinąć atag wokół całego wyciągu HTML

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

w moim przykładzie moja klasa napisów ma efekty najechania kursorem, które przy zdarzeniach wskaźnikowych: none; po prostu przegrasz

zawijanie zawartości zachowa efekty najechania myszką i możesz kliknąć całe zdjęcie, włącznie z div, pozdrawiam!

Alexis
źródło
Słuszna uwaga! podziękowania
Mr.Vertigo
1

Możesz umieścić nakładkę AP, taką jak ...

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

po prostu połóż to tam, gdzie nie chcesz, tj. kliknij. Działa we wszystkich.

eric
źródło
1

Łatwiejszym sposobem byłoby wstawienie przezroczystego obrazu tła za pomocą identyfikatorów URI danych w następujący sposób:

.click-through {
    pointer-events: none;
    background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}
MathuSum Mut
źródło
0

Myślę, że event.stopPropagation();należy tutaj również wspomnieć. Dodaj to do funkcji Click swojego przycisku.

Zapobiega propagacji zdarzenia w drzewie DOM, zapobiegając powiadamianiu o zdarzeniu przez wszystkie programy nadrzędne.

Kenny
źródło
0

To nie jest dokładna odpowiedź na pytanie, ale może pomóc w znalezieniu rozwiązania tego problemu.

Miałem obraz, który ukrywałem przy ładowaniu strony i wyświetlałem podczas oczekiwania na połączenie AJAX, a następnie chowałem się ponownie ...

Znalazłem jedyny sposób, aby wyświetlić mój obraz podczas ładowania strony, a następnie sprawić, aby zniknął i móc klikać rzeczy, w których znajdował się obraz przed ukryciem, aby umieścić obraz w DIV, zrobić rozmiar DIV 10x10 pikseli lub mały wystarczająco, aby zapobiec problemowi z ukryciem zawierającego div. Umożliwiło to przepełnienie obrazu div podczas gdy jest widoczny, a gdy div był ukryty, na obszar divs miała wpływ niemożność kliknięcia obiektów poniżej, a nie cały rozmiar obrazu, który DIV zawierał i wyświetlał.

Próbowałem wszystkich metod, aby ukryć obraz, w tym CSS display = none / block, opacity = 0, ukrywanie obrazu za pomocą hidden = true. Wszystkie spowodowały, że mój obraz został ukryty, ale obszar, w którym był wyświetlany, zachowywał się tak, jakby znajdował się pod nim materiał, więc kliknięcia itd. Nie działałyby na leżące pod nim obiekty. Gdy obraz znalazł się w maleńkim DIV, a ja ukryłem maleńki DIV, cały obszar zajmowany przez obraz był wyraźny i tylko niewielki obszar pod DIV, który ukryłem, został zmieniony, ale ponieważ uczyniłem go wystarczająco małym (10x10 pikseli), problem został naprawiony (w pewnym sensie).

Uznałem, że jest to nieprzyjemne obejście tego, co powinno być prostym problemem, ale nie byłem w stanie znaleźć sposobu, aby ukryć obiekt w jego natywnym formacie bez kontenera. Mój obiekt był w formie itp. Jeśli ktoś ma lepszy sposób, daj mi znać.

David Crawford
źródło