Bagaimana cara menghentikan propagasi acara dengan atribut onclick inline?

313

Pertimbangkan yang berikut ini:

<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header');">something inside the header</span>
</div>

Bagaimana saya bisa membuatnya sehingga ketika pengguna mengklik rentang, itu tidak memunculkan divacara klik?

Sam
sumber

Jawaban:

272

Gunakan event.stopPropagation () .

<span onclick="event.stopPropagation(); alert('you clicked inside the header');">something inside the header</span>

Untuk IE: window.event.cancelBubble = true

<span onclick="window.event.cancelBubble = true; alert('you clicked inside the header');">something inside the header</span>
James
sumber
11
Tidak ada yang namanya objek acara di FireFox.
Robert C. Barth
6
Objek acara adalah parameter dari panggilan balik. Sebenarnya, tidak ada yang namanya objek acara di IE karena objek ini dapat diakses melalui jendela. Bahkan alih-alih menjadi parameter fungsi :-)
Vincent Robert
66
Ini hanya salah - penangan onclick inline inline tidak mendapatkan acara disahkan sebagai argumen. Solusi yang benar adalah Gareths, di bawah ini.
Benubird
2
Di Firefox, Anda dapat memiliki akses ke acara variabel dalam skrip inline, tetapi window.event tidak tersedia. <div onclick = "alert (event);"> </div>
Morgan Cheng
1
eventtampaknya tersedia di acara inline di iOS Safari juga.
Yuval A.
210

Ada dua cara untuk mendapatkan objek acara dari dalam suatu fungsi:

  1. Argumen pertama, di browser yang kompatibel dengan W3C (Chrome, Firefox, Safari, IE9 +)
  2. Objek window.event di Internet Explorer (<= 8)

Jika Anda perlu mendukung browser lawas yang tidak mengikuti rekomendasi W3C, umumnya di dalam fungsi Anda akan menggunakan sesuatu seperti berikut:

function(e) {
  var event = e || window.event;
  [...];
}

yang akan memeriksa yang pertama, dan yang lain dan menyimpan mana yang ditemukan di dalam variabel acara. Namun dalam event handler inline tidak ada eobjek untuk digunakan. Dalam hal ini Anda harus mengambil keuntungan dari argumentskoleksi yang selalu tersedia dan merujuk pada set lengkap argumen yang dilewatkan ke fungsi:

onclick="var event = arguments[0] || window.event; [...]"

Namun, secara umum Anda harus menghindari penangan event inline jika Anda perlu melakukan sesuatu yang rumit seperti menghentikan propagasi. Menulis event handler Anda secara terpisah dan melampirkannya ke elemen adalah ide yang jauh lebih baik dalam jangka menengah dan panjang, baik untuk keterbacaan dan pemeliharaan.

Gareth
sumber
11
Dari pendengar sebaris, Anda bisa melewati objek acara seperti:, onclick="foo(event)"lalu dalam fungsi function foo(event){/* do stuff with event */}. Ini bekerja di kedua model acara IE dan W3C.
RobG
5
"Lebih kecil atau sama dengan delapan" itu agak ... ambigu.
TechNyquist
8
ini sebenarnya tidak menjawab pertanyaan.
jcomeau_ictx
1
jawaban rapi untuk pertanyaan yang berbeda. : - /
Arel
80

Ingatlah bahwa window.event tidak didukung di FireFox, dan karena itu pasti ada sesuatu seperti:

e.cancelBubble = true

Atau, Anda dapat menggunakan standar W3C untuk FireFox:

e.stopPropagation();

Jika Anda ingin menjadi mewah, Anda dapat melakukan ini:

function myEventHandler(e)
{
    if (!e)
      e = window.event;

    //IE9 & Other Browsers
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    //IE8 and Lower
    else {
      e.cancelBubble = true;
    }
}
Robert C. Barth
sumber
12
Dan untuk membuatnya bekerja, kita perlu menyebutnya seperti ini:<div onclick="myEventHandler(event);">
DarkDust
1
Bisa jadi "event || window.event".
Runcing
1
jika (e.cancelBubble) tidak cocok untuk saya, Anda setel ke true jika sudah benar
Guillaume86
e.cancelBubblemengembalikan false di IE! Itu tidak dapat mencapai e.cancelBubble = true;instruksi. Gunakan kondisi SoftwareARM sebagai gantinya !!
mauretto
45

Gunakan fungsi ini, itu akan menguji keberadaan metode yang benar.

function disabledEventPropagation(event)
{
   if (event.stopPropagation){
       event.stopPropagation();
   }
   else if(window.event){
      window.event.cancelBubble=true;
   }
}
SoftwareARM
sumber
20

Saya memiliki masalah yang sama - kotak kesalahan js di IE - ini berfungsi dengan baik di semua browser sejauh yang saya bisa lihat (event.cancelBubble = true melakukan pekerjaan di IE)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"
MSC
sumber
1
Terima kasih @MSC apa yang saya butuhkan!
DannyC
1
Skrip sebaris. Itu menjawab pertanyaan
Cesar
10

Ini berhasil untuk saya

<script>
function cancelBubble(e) {
 var evt = e ? e:window.event;
 if (evt.stopPropagation)    evt.stopPropagation();
 if (evt.cancelBubble!=null) evt.cancelBubble = true;
}
</script>

<div onclick="alert('Click!')">
  <div onclick="cancelBubble(event)">Something inside the other div</div>
</div>
Matías Contreras Selman
sumber
Apakah Anda yakin bahwa potongan kode yang tepat ini cocok untuk Anda? Karena sepertinya ada masalah kutipan string pada onclick handler div luar ...?!
Nicole
7

Untuk halaman web ASP.NET (bukan MVC), Anda bisa menggunakan Sys.UI.DomEventobjek sebagai pembungkus acara asli.

<div onclick="event.stopPropagation();" ...

atau, meneruskan acara sebagai parameter ke fungsi dalam:

<div onclick="someFunction(event);" ...

dan dalam beberapa fungsi:

function someFunction(event){
    event.stopPropagation(); // here Sys.UI.DomEvent.stopPropagation() method is used
    // other onclick logic
}
Evgeny Gorb
sumber
5

Menurut halaman ini , di IE Anda perlu:

event.cancelBubble = true

ajh1138
sumber
2

Saya tidak dapat berkomentar karena Karma jadi saya menulis ini sebagai jawaban keseluruhan: Menurut jawaban Gareth (var e = argumen [0] || window.event; [...]) Saya menggunakan ineliner inline ini pada onclick untuk hack cepat:

<div onclick="(arguments[0] || window.event).stopPropagation();">..</div>

Saya tahu ini sudah terlambat, tetapi saya ingin memberi tahu Anda bahwa ini bekerja dalam satu baris. Kawat gigi mengembalikan sebuah acara yang memiliki fungsi stopPropagation terpasang dalam kedua kasus, jadi saya mencoba untuk merangkum mereka dalam kawat gigi seperti di jika dan .... berfungsi. :)

pengguna3611941
sumber
1

Ini juga berfungsi - Di tautan gunakan HTML onclick dengan pengembalian seperti ini:

<a href="mypage.html" onclick="return confirmClick();">Delete</a>

Dan kemudian fungsi comfirmClick () harus seperti:

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};
Rajendra
sumber
2
Bukan itu maksud pertanyaan itu.
jzonthemtn
@ jbird Itulah yang dimaksud pertanyaan itu. Ini adalah cara (yang lebih tua) yang berbeda untuk membatalkan suatu peristiwa dari menggelegak pohon dom (itu ada dalam spesifikasi dom api level 1).
gion_13
@ gion_13 Tapi aksi klik itu bukan sesuatu yang perlu dikonfirmasi pengguna. Dalam pertanyaan, kami hanya ingin onclick anak () untuk diaktifkan dan bukan onclick orang tua (). Menempatkan prompt pengguna di antara keduanya tidak membantu. Saya harap Anda dapat melihat perbedaan ini.
jzonthemtn
1
Itu confirmtidak relevan. Saya mengacu pada nilai pengembalian . kutipan: Di tautan HTML gunakan onclick dengan pengembalian seperti ini
gion_13
mengembalikan pembatalan palsu setelah tautan, itu tidak membatalkan propagasi di chrome saya
commonpike
1

Mengapa tidak memeriksa elemen mana saja yang diklik? Jika Anda mengklik sesuatu, window.event.targetditugaskan ke elemen yang diklik, dan elemen yang diklik juga dapat diteruskan sebagai argumen.

Jika target dan elemen tidak sama, itu adalah peristiwa yang disebarkan.

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />
cs01
sumber
Terima kasih sobat, ini tampaknya menjadi solusi terbersih di sini. Di samping catatan Anda harus mempertimbangkan, bahwa ini hanya cocok ketika elemen diklik adalah elemen paling atas yang sebenarnya.
Simon Mattes
0
<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header'); event.stopPropagation()">
    something inside the header
  </span>
</div>
Commonpike
sumber
0

Solusi terbaik akan ditangani dengan acara melalui fungsi javascript, tetapi untuk menggunakan solusi sederhana dan cepat menggunakan elemen html secara langsung, dan sekali bahwa "event" dan "window.event" sudah usang dan tidak didukung secara universal ( https://developer.mozilla.org/en-US/docs/Web/API/Window/event ), saya sarankan "hard code" berikut:

<div onclick="alert('blablabla'); (arguments[0] ? arguments[0].stopPropagation() : false);">...</div>
jose.serapicos
sumber