ความแตกต่างระหว่าง event.stopPropagation และ event.preventDefault คืออะไร


833

ดูเหมือนพวกเขาจะทำสิ่งเดียวกัน ...
สมัยนี้เป็นสมัยหนึ่งและเก่าหรือไม่? หรือพวกเขาสนับสนุนเบราว์เซอร์ที่แตกต่างกัน?

เมื่อฉันจัดการกับเหตุการณ์ด้วยตัวเอง (ไม่มีกรอบ) ฉันจะตรวจสอบทั้งสองอย่างเสมอและดำเนินการทั้งสองอย่างถ้ามี (ฉันยังreturn falseแต่ฉันมีความรู้สึกที่ไม่ได้ทำงานกับเหตุการณ์ที่แนบมาด้วยnode.addEventListener)

ทำไมทั้งคู่ ฉันควรตรวจสอบทั้งคู่หรือไม่ หรือมีความแตกต่างจริง ๆ ?

(ฉันรู้ว่าคำถามมากมาย แต่พวกเขาทั้งหมดเหมือนกัน =)

คำตอบ:


1014

stopPropagation หยุดเหตุการณ์จากการทำให้เดือดดาลในห่วงโซ่เหตุการณ์

preventDefault ป้องกันการกระทำเริ่มต้นที่เบราว์เซอร์ทำกับเหตุการณ์นั้น

ตัวอย่าง

ป้องกันไม่ให้

$("#but").click(function (event) {
  event.preventDefault()
})
$("#foo").click(function () {
  alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

stopPropagation

$("#but").click(function (event) {
  event.stopPropagation()
})
$("#foo").click(function () {
  alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

ด้วยตัวจัดการคลิกของstopPropagationเท่านั้นที่ถูกเรียกในขณะที่ตัวจัดการคลิก 'ไม่เคย firesbuttondiv

โดยที่ถ้าคุณใช้งานpreventDefaultเฉพาะการกระทำเริ่มต้นของเบราว์เซอร์จะหยุดลง แต่ตัวจัดการการคลิกของ div ยังคงทำงานอยู่

ด้านล่างนี้เป็นเอกสารเกี่ยวกับคุณสมบัติเหตุการณ์ DOM และวิธีการจาก MDN:

สำหรับ IE9 และ FF คุณสามารถใช้ PreventDefault & stopPropagation

เพื่อรองรับ IE8 และต่ำกว่าแทนที่stopPropagationด้วยcancelBubbleและแทนที่preventDefaultด้วยreturnValue


ดังนั้นพวกเขาแตกต่างกันมาก? IE มีสองวิธีเหตุการณ์ที่แตกต่างกันหรือไม่ (พวกเขาอาจเหมือนกันหรือไม่?) มันแปลกที่เฟรมเวิร์กทำทั้งสองอย่างในevent.stopฟังก์ชั่นของพวกเขา... นอกจากนี้แปลก ๆ ที่ฉันไม่เคยมีปัญหากับมัน ฉันใช้ฟองมาก ขอบคุณสำหรับตัวอย่าง!
Rudie

@Rudie แสดงความคิดเห็นในการสนับสนุนเบราว์เซอร์
Raynos

7
มันเป็นมูลค่า noting (ในกรณีที่คุณไม่ได้ดูที่เอกสาร MSDN) ที่cancelBubbleและreturnValueมีทั้งคุณสมบัติ (ดังนั้นควรจะตั้งค่าcancelBubble = true;) และที่preventDefaultและstopPropagationวิธีการ (ดังนั้นควรจะเรียกว่าpreventDefault();)
freefaller

1
@Raynos เพียงหนึ่งโน้ต: event.stopPropagation () ไม่เพียง แต่จะหยุดเหตุการณ์ไม่ให้เดือดร้อนจากห่วงโซ่เหตุการณ์ แต่ยังหยุดการเผยแพร่เหตุการณ์ในเฟสการจับภาพ ( developer.mozilla.org/en-US/docs/Web/ API / กิจกรรม / stopPropagation )
Yuci

1
มันจะเป็นประโยชน์ที่จะรู้ว่าสิ่งที่ดำเนินการเริ่มต้นสำหรับการคลิกที่ปุ่มเพื่อให้สามารถให้เหตุผลเกี่ยวกับสาเหตุที่ไม่ได้ทำงานแบบเดียวกับstopDefault() stopPropagation()หากการกระทำเริ่มต้นไม่ได้เรียกonclickวิธีมันคืออะไร?
d512

249

คำศัพท์

จากquirksmode.org :

การจับภาพเหตุการณ์

เมื่อคุณใช้การจับภาพเหตุการณ์

               | |
--------------- | | -----------------
| องค์ประกอบ 1 | | |
| ----------- | | ----------- |
| | element2 \ / | |
| ------------------------- |
| การจัดกิจกรรม
-----------------------------------

ตัวจัดการเหตุการณ์ของ element1 ยิงก่อนตัวจัดการเหตุการณ์ขององค์ประกอบ 2 จะยิงครั้งสุดท้าย

เหตุการณ์เดือดปุด ๆ

เมื่อคุณใช้เดือดปุด ๆ เหตุการณ์

               / \
--------------- | | -----------------
| องค์ประกอบ 1 | | |
| ----------- | | ----------- |
| | element2 | | | |
| ------------------------- |
| BUBBLING ของกิจกรรม
-----------------------------------

ตัวจัดการเหตุการณ์ขององค์ประกอบ 2 ยิงก่อนตัวจัดการเหตุการณ์ขององค์ประกอบ 1 จะยิงครั้งสุดท้าย

เหตุการณ์ใด ๆ ที่เกิดขึ้นในแบบจำลองเหตุการณ์ W3C ถูกจับครั้งแรกจนกว่าจะถึงองค์ประกอบเป้าหมายแล้วฟองอากาศขึ้นมาอีกครั้ง

                 | | / \
----------------- | | - | | -----------------
| องค์ประกอบ 1 | | | | |
| ------------- | | - | | ----------- |
| | element2 \ / | | | |
| -------------------------------- |
| รูปแบบเหตุการณ์ W3C
------------------------------------------

อินเตอร์เฟซ

จากw3.orgเพื่อจับภาพเหตุการณ์ :

หากการจับภาพEventListenerประสงค์ที่จะป้องกันไม่ให้มีการดำเนินการกับเหตุการณ์เพิ่มเติมอาจเรียกstopPropagationวิธีการ Eventอินเทอร์เฟซ วิธีนี้จะป้องกันการส่งต่อเหตุการณ์แม้ว่าการEventListenersลงทะเบียนเพิ่มเติมในระดับลำดับชั้นเดียวกันจะยังคงได้รับเหตุการณ์ เมื่อstopPropagation มีการเรียกใช้เมธอดของกิจกรรมแล้วการโทรไปยังเมธอดนั้นจะไม่มีผลเพิ่มเติม หากไม่มีผู้จับกุมเพิ่มเติมและ stopPropagationไม่ได้ถูกเรียกเหตุการณ์จะทำให้เกิดความเหมาะสมEventListenersกับเป้าหมาย

สำหรับเหตุการณ์เดือดปุด ๆ :

ตัวจัดการเหตุการณ์ใด ๆ อาจเลือกที่จะป้องกันการเผยแพร่เหตุการณ์ต่อไปโดยการเรียกstopPropagationวิธีการของEventอินเทอร์เฟซ หากมีการ EventListenerเรียกวิธีนี้จะมีการเรียกใช้เพิ่มเติมทั้งหมดEventListenersในปัจจุบันEventTargetแต่การหยุดเดือดจะหยุดในระดับนั้น stopPropagationต้องใช้การโทรเพียงครั้งเดียวเพื่อป้องกันการเดือดปุด ๆ

สำหรับการยกเลิกกิจกรรม :

ยกเลิกสามารถทำได้โดยการเรียกEvent's preventDefault วิธี หากมีการEventListenersโทรหนึ่งครั้งขึ้นไปpreventDefaultในระหว่างขั้นตอนการไหลของเหตุการณ์การกระทำเริ่มต้นจะถูกยกเลิก

ตัวอย่าง

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

HTML:

<div id="a">
  <a id="b" href="http://www.google.com/" target="_blank">Google</a>
</div>
<p id="c"></p>

JavaScript:

var el = document.getElementById("c");

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
}

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
}

function bubblingOnClick1(ev) {
    el.innerHTML += "DIV event bubbling<br>";
}

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
}

// The 3rd parameter useCapture makes the event listener capturing (false by default)
document.getElementById("a").addEventListener("click", capturingOnClick1, true);
document.getElementById("b").addEventListener("click", capturingOnClick2, true);
document.getElementById("a").addEventListener("click", bubblingOnClick1, false);
document.getElementById("b").addEventListener("click", bubblingOnClick2, false);

ตัวอย่างที่ 1 : ผลลัพธ์ในผลลัพธ์

DIV event capture
A event capture
A event bubbling
DIV event bubbling

ตัวอย่างที่ 2 : การเพิ่มstopPropagation()ไปยังฟังก์ชัน

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.stopPropagation();
}

ผลลัพธ์ในผลลัพธ์

DIV event capture

ผู้ฟังเหตุการณ์ป้องกันการเผยแพร่เหตุการณ์ลงและเพิ่มเติม อย่างไรก็ตามมันไม่ได้ป้องกันการกระทำเริ่มต้น (การเปิดแท็บใหม่)

ตัวอย่างที่ 3 : การเพิ่มstopPropagation()ไปยังฟังก์ชัน

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
    ev.stopPropagation();
}

หรือฟังก์ชั่น

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
    ev.stopPropagation();
}

ผลลัพธ์ในผลลัพธ์

DIV event capture
A event capture
A event bubbling

นี่เป็นเพราะทั้งสองฟังเหตุการณ์มีการลงทะเบียนในเป้าหมายเหตุการณ์เดียวกัน ตัวรับฟังเหตุการณ์ป้องกันการเผยแพร่เหตุการณ์ขึ้นไปอีก อย่างไรก็ตามพวกเขาไม่ได้ป้องกันการกระทำเริ่มต้น (การเปิดแท็บใหม่)

ตัวอย่างที่ 4 : การเพิ่มpreventDefault()ไปยังฟังก์ชันใด ๆ ตัวอย่างเช่น

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.preventDefault();
}

ป้องกันแท็บใหม่ไม่ให้เปิด


23
ขอขอบคุณสำหรับความแตกต่างที่ลึกซึ้งยิ่งขึ้นระหว่างการจับภาพและการเดือดปุด ๆ ในขณะที่คำตอบอื่น ๆ จะเน้นเฉพาะความกังวลของ jQuery
floribon

@floribon บอกว่าคุณไม่มีความตั้งใจที่จะรุกราน raynos สำหรับคำตอบของเขา
Mahi

3
@Mahi อะไร ฉันแค่บอกข้อเท็จจริงคำตอบที่ยอมรับคือการใช้ jQuery ซึ่ง OP ไม่ได้สันนิษฐานดังนั้นสำหรับฉันมันไม่ใช่คำตอบที่แท้จริง ตอนนี้เป็นเพียงข้อเท็จจริงทางเทคนิคไม่มีอะไรที่เป็นส่วนตัวและไม่มีใครถูกทำให้ขุ่นเคือง
floribon

2
คำตอบของคุณเป็นระบบและแสดงให้เห็นอย่างชัดเจนว่าเกิดอะไรขึ้น ตอนแรกฉันไม่ต้องการรบกวนคุณและทำการเปลี่ยนแปลงคำตอบของคุณด้วยตัวเองเพราะฉันคิดว่ามันอาจจะดีขึ้นเล็กน้อยเพื่อความชัดเจน คำตอบนี้จะอธิบายรูปแบบของเหตุการณ์ให้กับผู้เริ่มต้นและด้วยเหตุนี้ฉันคิดว่าความช่วยเหลือเล็กน้อยที่เราสามารถมอบให้กับผู้เริ่มต้นใช้งานได้ยาวนาน ข้อเสนอแนะการแก้ไขของฉันถูกปฏิเสธโดยอาร์กิวเมนต์ทั่วไปซึ่งฉันไม่เห็นด้วย หากคุณ @Ashkan รู้สึกว่าการเปลี่ยนแปลงเล็กน้อยเหล่านี้สามารถช่วยปรับปรุงคำตอบได้โปรดรวมไว้ด้วย
mucaho

68

กลับเท็จ


return false; ทำ 3 สิ่งแยกกันเมื่อคุณเรียกว่า:

  1. event.preventDefault() - มันหยุดพฤติกรรมเริ่มต้นของเบราว์เซอร์
  2. event.stopPropagation() - มันป้องกันเหตุการณ์จากการแพร่กระจาย (หรือ "เดือดปุด ๆ ") DOM
  3. หยุดการเรียกกลับและส่งคืนทันทีเมื่อถูกเรียก

โปรดทราบว่าพฤติกรรมนี้แตกต่างจากตัวจัดการเหตุการณ์ปกติ (ไม่ใช่ jQuery) ซึ่งสะดุดตา return falseไม่หยุดเหตุการณ์จากการเดือดปุด ๆ

ป้องกันไม่ให้ ();


preventDefault(); ทำสิ่งหนึ่ง: มันหยุดพฤติกรรมเริ่มต้นของเบราว์เซอร์

ควรใช้เมื่อใด


เรารู้ว่าสิ่งที่พวกเขาทำ แต่เมื่อใช้พวกเขา? ขึ้นอยู่กับสิ่งที่คุณต้องการจะทำให้สำเร็จ ใช้preventDefault();หากคุณต้องการ“ เพียง” ป้องกันพฤติกรรมเบราว์เซอร์เริ่มต้น ใช้ return false เมื่อคุณต้องการป้องกันพฤติกรรมเบราว์เซอร์เริ่มต้นและป้องกันไม่ให้เหตุการณ์แพร่กระจาย DOM ในสถานการณ์ส่วนใหญ่ที่คุณจะใช้ผลตอบแทนที่เป็นเท็จ preventDefault()สิ่งที่คุณต้องการจริงๆคือ

ตัวอย่าง:


ลองทำความเข้าใจกับตัวอย่าง:

เราจะเห็นตัวอย่าง JAVASCRIPT บริสุทธิ์

ตัวอย่างที่ 1:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

เรียกใช้รหัสข้างต้นคุณจะเห็นไฮเปอร์ลิงก์'คลิกที่นี่เพื่อเยี่ยมชม stackoverflow.com'ตอนนี้ถ้าคุณคลิกที่ลิงค์แรกคุณจะได้รับการแจ้งเตือนจาวาสคริปต์ลิงค์คลิกถัดไปคุณจะได้รับการแจ้งเตือนจาวาสคริปต์div คลิกและทันทีที่คุณจะถูกเปลี่ยนเส้นทางไป stackoverflow.com

ตัวอย่างที่ 2:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.preventDefault();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

เรียกใช้รหัสข้างต้นคุณจะเห็นไฮเปอร์ลิงก์ 'คลิกที่นี่เพื่อเยี่ยมชม stackoverflow.com' ตอนนี้ถ้าคุณคลิกที่ลิงค์แรกคุณจะได้รับการแจ้งเตือนจาวาสคริปต์ลิงค์คลิกถัดไปคุณจะได้รับการแจ้งเตือนจาวาสคริปต์div คลิกถัดไปคุณจะเห็นไฮเปอร์ลิงค์ ' คลิกที่นี่เพื่อเยี่ยมชม stackoverflow.com 'แทนที่ด้วยข้อความ' ป้องกันการคลิกเหตุการณ์ 'และคุณจะไม่ถูกเปลี่ยนเส้นทางไปยัง stackoverflow.com นี่เป็นเพราะ> ถึง event.preventDefault () วิธีการที่เราใช้เพื่อป้องกันการคลิกการกระทำเริ่มต้นที่จะถูกเรียก

ตัวอย่างที่ 3:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.stopPropagation();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('div Clicked');
  }
</script>

ครั้งนี้ถ้าคุณคลิกที่ลิงค์ฟังก์ชั่น executeParent () จะไม่ถูกเรียกและคุณจะไม่ได้รับการแจ้งเตือน javascript div คลิกที่ เวลานี้ นี่เป็นเพราะเรามีการป้องกันการแพร่กระจายไปยังผู้ปกครอง div โดยใช้วิธีการ event.stopPropagation () ถัดไปคุณจะเห็นไฮเปอร์ลิงก์ 'คลิกที่นี่เพื่อเยี่ยมชม stackoverflow.com' แทนที่ด้วยข้อความ 'เหตุการณ์การคลิกกำลังจะถูกดำเนินการ' และทันทีคุณจะถูกเปลี่ยนเส้นทางไปยัง stackoverflow.com นี่เป็นเพราะเราไม่ได้ป้องกันการคลิกเริ่มต้นจากการเรียกครั้งนี้โดยใช้วิธี event.preventDefault ()

ตัวอย่างที่ 4:

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.preventDefault();
    event.stopPropagation();
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
  }

  function executeParent() {
    alert('Div Clicked');
  }
</script>

หากคุณคลิกที่ลิงค์ฟังก์ชั่น executeParent () จะไม่ถูกเรียกใช้และคุณจะไม่ได้รับการแจ้งเตือนจาวาสคริปต์ นี่เป็นเพราะเรามีการป้องกันการแพร่กระจายไปยังผู้ปกครอง div โดยใช้วิธีการ event.stopPropagation () ถัดไปคุณจะเห็นไฮเปอร์ลิงก์ 'คลิกที่นี่เพื่อเยี่ยมชม stackoverflow.com' แทนที่ด้วยข้อความ 'ป้องกันการคลิกเหตุการณ์' และคุณจะไม่ถูกเปลี่ยนเส้นทางไปยัง stackoverflow.com นี่เป็นเพราะเราได้ป้องกันไม่ให้การกระทำการคลิกเริ่มต้นเรียกตอนนี้โดยใช้วิธี event.preventDefault ()

ตัวอย่างที่ 5:

เพื่อกลับเท็จฉันมีสามตัวอย่างและดูเหมือนว่าจะทำสิ่งเดียวกันแน่นอน (เพิ่งกลับเท็จ) แต่ในความเป็นจริงผลลัพธ์ที่ได้ค่อนข้างแตกต่างกัน นี่คือสิ่งที่เกิดขึ้นจริงในแต่ละข้อ

กรณี:

  1. การส่งคืนfalseจากตัวจัดการเหตุการณ์แบบอินไลน์ป้องกันไม่ให้เบราว์เซอร์นำทางไปยังที่อยู่ลิงก์ แต่จะไม่หยุดเหตุการณ์จากการเผยแพร่ผ่าน DOM
  2. การส่งคืนfalseจากตัวจัดการเหตุการณ์ jQuery ป้องกันไม่ให้เบราว์เซอร์นำทางไปยังที่อยู่ลิงก์และจะหยุดเหตุการณ์ไม่ให้แพร่กระจายผ่าน DOM
  3. การคืนค่าfalseจากตัวจัดการเหตุการณ์ DOM ปกติไม่ได้ทำอะไรเลย

จะเห็นตัวอย่างทั้งสาม

  1. Inline return false

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='return false'>Click here to visit stackoverflow.com</a>
</div>
<script>
  var link = document.querySelector('a');

  link.addEventListener('click', function() {
    event.currentTarget.innerHTML = 'Click event prevented using inline html'
    alert('Link Clicked');
  });


  function executeParent() {
    alert('Div Clicked');
  }
</script>

  1. การคืนค่าเท็จจากตัวจัดการเหตุการณ์ jQuery

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <a href='https://stackoverflow.com'>Click here to visit stackoverflow.com</a>
</div>
<script>
  $('a').click(function(event) {
    alert('Link Clicked');
    $('a').text('Click event prevented using return FALSE');
    $('a').contents().unwrap();
    return false;
  });
  $('div').click(function(event) {
    alert('Div clicked');
  });
</script>

  1. การคืนค่า false จากตัวจัดการเหตุการณ์ DOM ปกติ

<div onclick='executeParent()'>
  <a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a>
</div>
<script>
  function executeChild() {
    event.currentTarget.innerHTML = 'Click event prevented'
    alert('Link Clicked');
    return false
  }

  function executeParent() {
    alert('Div Clicked');
  }
</script>

หวังว่าตัวอย่างเหล่านี้ชัดเจน ลองใช้งานตัวอย่างเหล่านี้ทั้งหมดในไฟล์ html เพื่อดูว่าทำงานอย่างไร


1
ตัวอย่างที่ดี แต่น่าจะดีกว่านี้หากไม่มี jQuery เนื่องจาก jQuery ปลอมวัตถุในเหตุการณ์จึงแตกต่างกันในทางเทคนิค
Rudie

1
@Rudie ฉันอัปเดตคำตอบและลบ jquery ออกจากนั้นและเพิ่มตัวอย่างสำหรับ return false
Keval Bhatt

17

นี่คือคำพูดจากที่นี่

event.preventDefault

เมธอด PreventDefault ป้องกันเหตุการณ์จากการทำหน้าที่การทำงานเริ่มต้น ตัวอย่างเช่นคุณจะใช้ PreventDefault บนองค์ประกอบ A เพื่อหยุดการคลิกองค์ประกอบนั้นออกจากหน้าปัจจุบัน:

//clicking the link will *not* allow the user to leave the page 
myChildElement.onclick = function(e) { 
    e.preventDefault(); 
    console.log('brick me!'); 
};

//clicking the parent node will run the following console statement because event propagation occurs
logo.parentNode.onclick = function(e) { 
    console.log('you bricked my child!'); 
};

ในขณะที่องค์ประกอบการทำงานเริ่มต้นขององค์ประกอบถูกปิดกั้นเหตุการณ์ยังคงเพิ่มขึ้น DOM

Event.stopPropagation

เมธอดที่สอง stopPropagation อนุญาตให้ฟังก์ชันการทำงานเริ่มต้นของเหตุการณ์เกิดขึ้น แต่ป้องกันไม่ให้เหตุการณ์แพร่กระจาย:

//clicking the element will allow the default action to occur but propagation will be stopped...
myChildElement.onclick = function(e) { 
    e.stopPropagation();
    console.log('prop stop! no bubbles!'); 
};

//since propagation was stopped by the child element's onClick, this message will never be seen!
myChildElement.parentNode.onclick = function(e) { 
    console.log('you will never see this message!'); 
};

stopPropagation ได้อย่างมีประสิทธิภาพหยุดองค์ประกอบผู้ปกครองจากการรู้เกี่ยวกับเหตุการณ์ที่กำหนดในลูกของมัน

ในขณะที่วิธีการหยุดที่เรียบง่ายช่วยให้เราสามารถจัดการกับเหตุการณ์ได้อย่างรวดเร็วสิ่งสำคัญคือให้คิดถึงสิ่งที่คุณต้องการให้เกิดขึ้นจริงด้วยการเดือดปุด ๆ ฉันพนันได้เลยว่านักพัฒนาทุกคนต้องการจริงๆคือป้องกันเริ่มต้น 90% ของเวลา! เหตุการณ์ "หยุด" ไม่ถูกต้องอาจทำให้คุณมีปัญหามากมาย ปลั๊กอินของคุณอาจไม่ทำงานและปลั๊กอินบุคคลที่สามของคุณอาจถูกปิดกั้น หรือแย่กว่านั้นคือ - รหัสของคุณจะแบ่งการทำงานอื่น ๆ บนเว็บไซต์


2

Event.preventDefault- หยุดพฤติกรรมเริ่มต้นของเบราว์เซอร์ ตอนนี้สิ่งที่เป็นพฤติกรรมเริ่มต้นของเบราว์เซอร์มา สมมติว่าคุณมีแท็กจุดยึดและมีแอตทริบิวต์ href และแท็กจุดยึดนี้ซ้อนอยู่ภายในแท็ก div ที่มีเหตุการณ์คลิก พฤติกรรมเริ่มต้นของแท็กสมอคือเมื่อคลิกที่แท็กสมอมันควรจะนำทาง แต่สิ่งที่ event.preventDefault ทำคือมันหยุดการนำทางในกรณีนี้ แต่มันไม่เคยหยุดการเกิดเหตุการณ์หรือการเพิ่มของเหตุการณ์เช่น

<div class="container">
 <a href="#" class="element">Click Me!</a>
</div>

$('.container').on('click', function(e) {
 console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  console.log('element was clicked');
});

ผลจะเป็นอย่างไร

"องค์ประกอบถูกคลิก"

"คลิกคอนเทนเนอร์แล้ว"

ตอนนี้ event.StopPropation จะหยุดเดือดของเหตุการณ์หรือการเพิ่มของเหตุการณ์ ตอนนี้มีตัวอย่างข้างต้น

$('.container').on('click', function(e) {
  console.log('container was clicked');
});

$('.element').on('click', function(e) {
  e.preventDefault(); // Now link won't go anywhere
  e.stopPropagation(); // Now the event won't bubble up
 console.log('element was clicked');
});

ผลลัพธ์จะเป็น

"องค์ประกอบถูกคลิก"

สำหรับข้อมูลเพิ่มเติมอ้างอิงลิงค์นี้ https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/


1

event.preventDefault(); หยุดการกระทำเริ่มต้นขององค์ประกอบที่เกิดขึ้น

event.stopPropagation(); ป้องกันเหตุการณ์จากการทำให้ทรี DOM สูงขึ้นทำให้ป้องกันตัวจัดการพาเรนต์ไม่ได้รับการแจ้งเตือนของเหตุการณ์

ตัวอย่างเช่นหากมีลิงก์ที่มีวิธีการคลิกแนบอยู่ภายในDIVหรือFORMที่มีวิธีการคลิกแนบอยู่ด้วยจะเป็นการป้องกันไม่ให้วิธีการDIVหรือFORMคลิกเริ่มทำงาน


-3

$("#but").click(function(event){
console.log("hello");
  event.preventDefault();
 });


$("#foo").click(function(){
 alert("parent click event fired !");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.