จะหยุดการเผยแพร่กิจกรรมด้วยแอตทริบิวต์ inline onclick ได้อย่างไร


313

พิจารณาสิ่งต่อไปนี้:

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

ฉันจะทำให้มันเป็นแบบนั้นได้อย่างไรเมื่อผู้ใช้คลิกที่สแปนมันจะไม่เริ่มการdivคลิกของเหตุการณ์

คำตอบ:


272

ใช้event.stopPropagation ()

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

สำหรับ IE: window.event.cancelBubble = true

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

11
ไม่มีสิ่งเช่นวัตถุเหตุการณ์ใน FireFox
Robert C. Barth

6
วัตถุเหตุการณ์เป็นพารามิเตอร์ของการโทรกลับ อันที่จริงไม่มีสิ่งดังกล่าวเป็นวัตถุเหตุการณ์ใน IE เพราะวัตถุนี้สามารถเข้าถึงได้ผ่าน window.event แทนที่จะเป็นพารามิเตอร์ของฟังก์ชัน :-)
วินเซนต์โรเบิร์ต

66
นี่เป็นเพียงความผิด - ตัวจัดการ onclick แบบอินไลน์ไม่ได้รับเหตุการณ์ที่ส่งผ่านเป็นอาร์กิวเมนต์ วิธีการแก้ไขที่ถูกต้องคือ Gareths ด้านล่าง
Benubird

2
ใน Firefox คุณสามารถเข้าถึงเหตุการณ์ตัวแปรในสคริปต์แบบอินไลน์ แต่ window.event ไม่สามารถใช้ได้ <div onclick = "การแจ้งเตือน (เหตุการณ์);"> </div>
มอร์แกนเฉิง

1
eventดูเหมือนว่าจะมีให้ในกิจกรรมแบบอินไลน์ใน IOS Safari เช่นกัน
Yuval A.

210

มีสองวิธีในการรับวัตถุเหตุการณ์จากภายในฟังก์ชัน:

  1. อาร์กิวเมนต์แรกในเบราว์เซอร์ที่สอดคล้องกับ W3C (Chrome, Firefox, Safari, IE9 +)
  2. วัตถุ window.event ใน Internet Explorer (<= 8)

หากคุณต้องการสนับสนุนเบราว์เซอร์รุ่นเก่าที่ไม่ปฏิบัติตามคำแนะนำของ W3C โดยทั่วไปภายในฟังก์ชันคุณจะต้องใช้สิ่งต่อไปนี้:

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

ซึ่งจะตรวจสอบรายการแรกจากนั้นอีกรายการและจัดเก็บรายการใดก็ตามที่พบภายในตัวแปรเหตุการณ์ อย่างไรก็ตามในตัวจัดการเหตุการณ์แบบอินไลน์ไม่มีeวัตถุที่จะใช้ ในกรณีดังกล่าวคุณจะต้องใช้ประโยชน์จากargumentsคอลเลกชันที่มีอยู่เสมอและอ้างถึงชุดของอาร์กิวเมนต์ที่สมบูรณ์ที่ส่งไปยังฟังก์ชัน:

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

อย่างไรก็ตามโดยทั่วไปแล้วคุณควรหลีกเลี่ยงตัวจัดการเหตุการณ์แบบอินไลน์หากคุณต้องการสิ่งที่ซับซ้อนเช่นการหยุดการเผยแพร่ การเขียนตัวจัดการเหตุการณ์ของคุณแยกจากกันและการแนบไปยังองค์ประกอบเป็นความคิดที่ดีกว่ามากในระยะกลางและระยะยาวทั้งสำหรับการอ่านและการบำรุงรักษา


11
จากการฟังแบบอินไลน์คุณสามารถผ่านวัตถุเหตุการณ์เช่นนั้นในการทำงานonclick="foo(event)" function foo(event){/* do stuff with event */}สามารถใช้งานได้ทั้ง IE และ W3C
RobG

5
ว่า "น้อยกว่าหรือเท่ากับแปด" ค่อนข้าง ... ไม่ชัดเจน
TechNyquist

8
สิ่งนี้ไม่ได้ตอบคำถาม
jcomeau_ictx

1
คำตอบที่เรียบร้อยสำหรับคำถามอื่น : - /
Arel

80

โปรดทราบว่า window.event ไม่ได้รับการสนับสนุนใน FireFox และดังนั้นจึงต้องมีบางอย่างตามบรรทัดต่อไปนี้:

e.cancelBubble = true

หรือคุณสามารถใช้มาตรฐาน W3C สำหรับ FireFox:

e.stopPropagation();

หากคุณต้องการจินตนาการคุณสามารถทำสิ่งนี้ได้:

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

    //IE9 & Other Browsers
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    //IE8 and Lower
    else {
      e.cancelBubble = true;
    }
}

12
และเพื่อให้มันทำงานได้เราต้องเรียกสิ่งนี้เช่นนี้ว่า:<div onclick="myEventHandler(event);">
DarkDust

1
อาจเป็น "เหตุการณ์ || window.event"
Pointy

1
ถ้า (e.cancelBubble) ไม่ได้มีลักษณะที่เหมาะสมกับผมคุณตั้งค่าเป็นจริงถ้ามันมีอยู่แล้วจริง
Guillaume86

e.cancelBubbleส่งคืน false ใน IE! ไม่สามารถเข้าถึงe.cancelBubble = true;คำแนะนำได้ ใช้เงื่อนไขของ SoftwareARM แทน !!
mauretto

45

ใช้ฟังก์ชั่นนี้มันจะทดสอบการมีอยู่ของวิธีการที่ถูกต้อง

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

20

ฉันมีปัญหาเดียวกัน - กล่องข้อผิดพลาด js ใน IE - นี้ทำงานได้ดีในเบราว์เซอร์ทั้งหมดเท่าที่ฉันเห็น (event.cancelBubble = งานจริงใน IE)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"

1
ขอบคุณ @MSC สิ่งที่ฉันต้องการ!
DannyC

1
สคริปต์แบบอินไลน์ มันตอบคำถาม
Cesar

10

สิ่งนี้ใช้ได้สำหรับฉัน

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

คุณแน่ใจหรือไม่ว่าข้อมูลโค้ดที่แน่นอนนี้ใช้ได้กับคุณ เนื่องจากดูเหมือนว่ามีปัญหาการอ้างอิงสตริงในตัวจัดการ onclick ของ div ภายนอก ... ?!
นิโคล

7

สำหรับหน้าเว็บ ASP.NET (ไม่ใช่ MVC) คุณสามารถใช้Sys.UI.DomEventobject เป็น wrapper ของ native event ได้

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

หรือส่งเหตุการณ์เป็นพารามิเตอร์ไปยังฟังก์ชันภายใน:

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

และในบางฟังก์ชั่น:

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


2

ฉันไม่สามารถแสดงความคิดเห็นได้เนื่องจากกรรมดังนั้นฉันจึงเขียนคำตอบทั้งหมด: ตามคำตอบของ Gareth (var e = อาร์กิวเมนต์ [0] || window.event; [... ]) ฉันใช้ออนไลน์เนอร์นี้บนอินไลน์สำหรับ onclick แฮ็คอย่างรวดเร็ว:

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

ฉันรู้ว่ามันสาย แต่ฉันอยากให้คุณรู้ว่ามันใช้งานได้ในหนึ่งบรรทัด เครื่องมือจัดฟันคืนเหตุการณ์ที่มีฟังก์ชั่น stopPropagation ติดอยู่ในทั้งสองกรณีดังนั้นฉันจึงพยายามสรุปให้พวกเขาเป็นเครื่องมือจัดฟันในกรณี if และ .... :)


1

สิ่งนี้ยังใช้งานได้ - ในลิงก์ HTML ใช้ onclick พร้อมการส่งคืนเช่นนี้:

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

แล้วฟังก์ชัน comfirmClick () ควรเป็นเช่น:

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};

2
นี่ไม่ใช่สิ่งที่คำถามหมายถึง
jzonthemtn

@bird นั่นคือสิ่งที่คำถามนั้นมีความหมาย มันเป็นวิธีที่แตกต่างกัน (เก่ากว่า) ในการยกเลิกกิจกรรมจากการทำให้ต้นไม้เดือด
gion_13

@ gion_13 แต่การกระทำของคลิกไม่ใช่สิ่งที่ผู้ใช้ต้องยืนยัน ในคำถามเราต้องการให้ onclick () ของเด็กยิงเท่านั้นและไม่ใช่ onclick ของผู้ปกครอง () การใส่พรอมต์ของผู้ใช้ระหว่างสิ่งเหล่านั้นจะไม่เป็นประโยชน์ ฉันหวังว่าคุณจะเห็นความแตกต่างนี้
jzonthemtn

1
confirmไม่เกี่ยวข้อง ฉันกำลังหมายถึงค่าตอบแทน อ้างจาก: ในลิงค์ HTML ใช้ onclick พร้อมผลตอบแทนเช่นนี้
gion_13

ส่งคืนการยกเลิกที่ผิดพลาดโดยไปที่ลิงก์ แต่ไม่ได้ยกเลิกการเผยแพร่ใน Chrome ของฉัน
commonpike

1

ทำไมไม่ลองดูว่าองค์ประกอบใดที่ถูกคลิก? หากคุณคลิกที่สิ่งใดสิ่งหนึ่งwindow.event.targetจะถูกกำหนดให้กับองค์ประกอบที่ถูกคลิกและองค์ประกอบที่คลิกก็สามารถถูกส่งผ่านเป็นอาร์กิวเมนต์ได้

หากเป้าหมายและองค์ประกอบไม่เท่ากันแสดงว่าเป็นเหตุการณ์ที่เผยแพร่

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />

ขอบคุณเพื่อนนี่ดูเหมือนจะเป็นทางออกที่สะอาดที่สุดที่นี่ ในหมายเหตุด้านข้างคุณต้องพิจารณาว่าสิ่งนี้จะตรงกับเมื่อองค์ประกอบที่คลิกเป็นองค์ประกอบสูงสุดจริงเท่านั้น
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>

0

ทางออกที่ดีที่สุดจะได้รับการจัดการกับเหตุการณ์ผ่านฟังก์ชั่นจาวาสคริปต์ แต่เพื่อที่จะใช้วิธีการแก้ปัญหาที่ง่ายและรวดเร็วโดยใช้องค์ประกอบ html โดยตรงและเมื่อ "เหตุการณ์" และ "window.event" เลิกใช้แล้วและไม่ได้รับการสนับสนุนในระดับสากลhttps://developer.mozilla.org/en-US/docs/Web/API/Window/event ) ฉันขอแนะนำ "รหัสยาก" ต่อไปนี้:

<div onclick="alert('blablabla'); (arguments[0] ? arguments[0].stopPropagation() : false);">...</div>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.