Klik melalui div ke elemen yang mendasarinya

1593

Saya punya divyang punya background:transparent, bersama dengan border. Di bawah ini div, saya memiliki lebih banyak elemen.

Saat ini, saya bisa mengklik elemen yang mendasarinya ketika saya mengklik di luar hamparan div. Namun, saya tidak dapat mengklik elemen yang mendasarinya ketika mengklik langsung pada overlay div.

Saya ingin dapat mengklik ini divsehingga saya bisa mengklik elemen yang mendasarinya.

Masalahku

Ryan
sumber

Jawaban:

2616

Ya, Anda BISA melakukan ini.

Menggunakan pointer-events: nonebersama dengan pernyataan kondisi CSS untuk IE11 (tidak bekerja di IE10 atau di bawah), Anda bisa mendapatkan solusi yang kompatibel dengan browser lintas untuk masalah ini.

Dengan menggunakan AlphaImageLoader, Anda bahkan dapat menempatkan transparan .PNG/.GIFdi hamparan divdan memiliki klik mengalir ke elemen di bawahnya.

CSS:

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

Bersyarat IE11:

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

Ini adalah halaman contoh dasar dengan semua kode.

LawrenceKSRealEstate
sumber
7
bagaimana jika saya menggunakan transisi atau hover-state pada div itu?
Manticore
2
@Anticore Jawaban singkat: Anda tidak bisa. Dalam hal ini jawaban yang diberikan tidak berfungsi.
Niels Abildgaard
10
IE11 sepenuhnya mendukung pointer-events. Ini berarti semua browser modern mendukungnya. Ini adalah solusi yang bisa diterapkan pada akhir 2014. caniuse.com/#search=pointer-events
Judah Gabriel Himango
Seperti yang dicatat oleh @Andy, ini memecah scroll. Saya membuka masalah terpisah untuk melihat apakah ada solusi untuk stackoverflow.com/questions/41592349/…
Oliver Joseph Ash
1
@Anticore saya menemukan bahwa Anda dapat menimpa "pointer-events: none;" untuk elemen bersarang, sehingga Anda dapat menulis sesuatu yang dilewati oleh klik dengan sesuatu yang mendapatkan klik dan lebih, untuk bagian yang ditimpa Anda dapat menggunakan efek dan klik
Luca C.
292

Juga menyenangkan untuk diketahui ...
Anda dapat menonaktifkan pointer-events dalam elemen induk (mungkin div transparan) tetapi masih mengaktifkannya untuk elemen turunannya.
Ini berguna jika Anda bekerja dengan beberapa lapisan div yang tumpang tindih, di mana Anda ingin dapat mengeklik elemen anak, sambil membiarkan lapisan induk tidak bereaksi pada peristiwa mouse sama sekali.

Untuk ini, dapatkan semua parenting divs pointer-events: nonedan anak-anaknya yang dapat diklik mendapatkan pointer-events diaktifkan kembali olehpointer-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>
Allisone
sumber
4
Sempurna, inilah yang saya butuhkan!
RobbyReindeer
1
sangat membantu, terima kasih
SpaceBear
43

Mengizinkan pengguna mengklik divelemen elemen yang mendasarinya tergantung pada browser. Semua browser modern, termasuk Firefox, Chrome, Safari, dan Opera, mengerti pointer-events:none.

Untuk IE, itu tergantung pada latar belakang. Jika latar belakangnya transparan, klik per tayang berfungsi tanpa Anda perlu melakukan apa pun. Di sisi lain, untuk sesuatu seperti background:white; opacity:0; filter:Alpha(opacity=0);, IE memerlukan penerusan acara manual.

Lihat uji JSFiddle dan acara pointer CanIUse .

Vladimir Prodan
sumber
20

Saya menambahkan jawaban ini karena saya tidak melihatnya sepenuhnya di sini. Saya bisa melakukan ini menggunakan elementFromPoint. Pada dasarnya:

  • lampirkan klik pada div yang ingin diklik
  • Sembunyikan itu
  • tentukan elemen penunjuk apa yang aktif
  • jalankan klik pada elemen di sana.
var range-selector= $("")
    .css("position", "absolute").addClass("range-selector")
    .appendTo("")
    .click(function(e) {
        _range-selector.hide();

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

Dalam kasus saya, overlay div benar-benar diposisikan — saya tidak yakin apakah ini membuat perbedaan. Ini berfungsi pada IE8 / 9, Safari Chrome dan Firefox setidaknya.

Tim
sumber
12
  1. Sembunyikan hamparan elemen
  2. Tentukan koordinat kursor
  3. Dapatkan elemen pada koordinat tersebut
  4. Pemicu klik pada elemen
  5. Tampilkan elemen overlay lagi
$('#elementontop').click(e => {
    $('#elementontop').hide();
    $(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");
    $('#elementontop').show();
});
wcloister
sumber
Apakah Anda lupa untuk menutup apostrof? Mungkin $('#elementontop)seharusnya begitu $('#elementontop')?
johannchopin
10

Saya perlu melakukan ini dan memutuskan untuk mengambil rute ini:

$('.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
sumber
6

Saat ini saya bekerja dengan balon pidato kanvas. Tetapi karena balon dengan pointer dibungkus dengan div, beberapa tautan di bawahnya tidak lagi bisa klik. Saya tidak bisa menggunakan extjs dalam hal ini. Lihat contoh dasar untuk tutorial balon ucapan saya membutuhkan HTML5

Jadi saya memutuskan untuk mengumpulkan semua koordinat tautan dari dalam balon dalam sebuah 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]);
                                     });
         }

Saya menyebut fungsi ini pada setiap balon (baru). Itu mengambil koordinat sudut kiri / atas dan kanan / bawah dari link.class - juga atribut nama untuk apa yang harus dilakukan jika seseorang mengklik koordinat itu dan saya suka menetapkan 1 yang artinya tidak diklik jet . Dan lepaskan array ini ke clickarray. Anda juga bisa menggunakan push.

Untuk bekerja dengan array itu:

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

Fungsi ini membuktikan koordinat acara klik tubuh atau apakah sudah diklik dan mengembalikan atribut nama. Saya pikir tidak perlu masuk lebih dalam, tetapi Anda lihat itu tidak terlalu rumit. Harapan dalam bahasa Inggris ...

BF
sumber
4

tidak bekerja seperti itu. cara mengatasinya adalah secara manual memeriksa koordinat klik mouse terhadap area yang ditempati oleh setiap elemen.

area yang ditempati oleh suatu elemen dapat ditemukan dengan 1. mendapatkan lokasi elemen sehubungan dengan bagian kiri atas halaman, dan 2. lebar dan tinggi. perpustakaan seperti jQuery membuat ini sangat sederhana, meskipun dapat dilakukan dalam js sederhana. menambahkan event handler untuk mousemovedi documentobyek akan memberikan update terus-menerus dari posisi mouse dari atas dan kiri halaman. memutuskan apakah mouse berada di atas objek yang diberikan terdiri dari memeriksa apakah posisi mouse berada di antara tepi kiri, kanan, atas dan bawah suatu elemen.

lincolnk
sumber
2
Seperti disebutkan di atas, Anda dapat mencapai ini menggunakan CSS {pointer-events: none;} pada wadah transparan Anda.
Empereol
4

Tidak, Anda tidak dapat mengeklik elemen 'melalui'. Anda bisa mendapatkan koordinat klik dan mencoba mencari tahu elemen apa yang ada di bawah elemen yang diklik, tetapi ini sangat membosankan untuk browser yang tidak memiliki document.elementFromPoint. Maka Anda masih harus meniru tindakan default mengklik, yang tidak selalu sepele tergantung pada elemen apa yang Anda miliki di bawah sana.

Karena Anda memiliki area jendela yang sepenuhnya transparan, Anda mungkin akan lebih baik menerapkannya sebagai elemen perbatasan yang terpisah di luar, meninggalkan area pusat bebas dari halangan sehingga Anda dapat benar-benar klik langsung.

bobince
sumber
4

Gagasan lain untuk mencoba (secara situasional) adalah:

  1. Masukkan konten yang Anda inginkan dalam div;
  2. Letakkan overlay tanpa mengklik di atas seluruh halaman dengan indeks-z lebih tinggi,
  3. buat salinan terpotong lain dari div asli
  4. overlay dan abs posisi salinan div di tempat yang sama dengan konten asli Anda ingin diklik dengan indeks-z yang lebih tinggi?

Adakah pikiran?

Adam
sumber
2

Saya pikir Anda dapat mempertimbangkan untuk mengubah markup Anda. Jika saya tidak salah, Anda ingin meletakkan lapisan tak terlihat di atas dokumen dan markup tak terlihat Anda mungkin mendahului gambar dokumen Anda (apakah ini benar?).

Sebagai gantinya, saya mengusulkan agar Anda meletakkan yang tidak terlihat tepat setelah gambar dokumen tetapi mengubah posisi menjadi absolut.

Perhatikan bahwa Anda memerlukan elemen induk untuk memiliki posisi: relatif dan kemudian Anda akan dapat menggunakan ide ini. Kalau tidak, lapisan absolut Anda akan ditempatkan tepat di sudut kiri atas.

Elemen posisi absolut diposisikan relatif terhadap elemen induk pertama yang memiliki posisi selain statis. Jika tidak ada elemen yang ditemukan, blok yang mengandung html

Semoga ini membantu. Lihat di sini untuk informasi lebih lanjut tentang penentuan posisi CSS.

julianm
sumber
2

Bungkus saja atag di sekitar semua ekstrak HTML, misalnya

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

dalam contoh saya kelas teks saya memiliki efek hover, yang dengan pointer-events: none;Anda hanya akan kalah

membungkus konten akan menjaga efek hover Anda dan Anda dapat mengklik di semua gambar, termasuk div, salam!

Alexis
sumber
poin bagus! thnks
Mr.Vertigo
1

Anda dapat menempatkan hamparan AP seperti ...

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

letakkan saja di tempat yang tidak Anda inginkan, yaitu berdenting. Berfungsi dalam semua.

eric
sumber
1

Cara yang lebih mudah adalah dengan inline gambar latar transparan menggunakan URI Data sebagai berikut:

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

Saya pikir event.stopPropagation();harus disebutkan di sini juga. Tambahkan ini ke fungsi Klik tombol Anda.

Mencegah peristiwa menggelegak pohon DOM, mencegah penangan orang tua diberitahu tentang acara tersebut.

kenny
sumber
0

Ini bukan jawaban yang tepat untuk pertanyaan tetapi dapat membantu dalam menemukan solusi untuk itu.

Saya memiliki gambar yang saya sembunyikan pada pemuatan halaman dan ditampilkan saat menunggu panggilan AJAX lalu bersembunyi lagi ...

Saya menemukan satu-satunya cara untuk menampilkan gambar saya ketika memuat halaman kemudian membuatnya menghilang dan dapat mengklik hal-hal di mana gambar itu berada sebelum menyembunyikannya untuk meletakkan gambar ke dalam DIV, membuat ukuran DIV 10x10 piksel atau kecil cukup untuk mencegahnya menyebabkan masalah kemudian menyembunyikan div yang mengandung. Ini memungkinkan gambar meluap div saat terlihat dan ketika div disembunyikan, hanya area div dipengaruhi oleh ketidakmampuan untuk mengklik objek di bawah dan bukan seluruh ukuran gambar yang DIV isi dan tampilkan.

Saya mencoba semua metode untuk menyembunyikan gambar termasuk tampilan CSS = none / block, opacity = 0, menyembunyikan gambar dengan hidden = true. Semuanya menghasilkan gambar saya disembunyikan tetapi area di mana ia ditampilkan untuk bertindak seperti ada penutup atas barang-barang di bawahnya sehingga klik dan sebagainya tidak akan bertindak pada objek yang mendasarinya. Setelah gambar berada di dalam DIV kecil dan saya menyembunyikan DIV kecil itu, seluruh area yang ditempati oleh gambar itu jelas dan hanya area kecil di bawah DIV yang saya sembunyikan yang terpengaruh, tetapi saat saya membuatnya cukup kecil (10x10 piksel), masalahnya telah diperbaiki (semacam).

Saya menemukan ini sebagai solusi kotor untuk apa yang seharusnya menjadi masalah sederhana tapi saya tidak dapat menemukan cara untuk menyembunyikan objek dalam format aslinya tanpa wadah. Objek saya adalah dalam bentuk dll. Jika ada yang memiliki cara yang lebih baik, tolong beri tahu saya.

David Crawford
sumber