ทุกคนสามารถอธิบายการมอบหมายเหตุการณ์ใน JavaScript ได้หรือไม่และมีประโยชน์อย่างไร
ทุกคนสามารถอธิบายการมอบหมายเหตุการณ์ใน JavaScript ได้หรือไม่และมีประโยชน์อย่างไร
คำตอบ:
การมอบหมายเหตุการณ์ DOM เป็นกลไกในการตอบสนองต่อเหตุการณ์ UI ผ่านผู้ปกครองทั่วไปเดียวมากกว่าเด็กแต่ละคนผ่านความมหัศจรรย์ของเหตุการณ์ "เดือดปุด ๆ " (การเผยแพร่เหตุการณ์ aka)
เมื่อมีการเรียกใช้เหตุการณ์ในองค์ประกอบรายการต่อไปนี้จะเกิดขึ้น :
เหตุการณ์ถูกส่งไปยังเป้าหมาย
EventTarget
และผู้ฟังกิจกรรมใด ๆ ที่พบว่ามีการเปิดใช้งาน จากนั้นเหตุการณ์Bubblingจะทริกเกอร์ผู้ฟังเหตุการณ์เพิ่มเติมที่พบโดยติดตามEventTarget
ห่วงโซ่ผู้ปกครองขึ้นด้านบนตรวจสอบผู้ฟังเหตุการณ์ที่ลงทะเบียนในแต่ละ EventTarget ที่ต่อเนื่องกันDocument
การขยายพันธุ์นี้ขึ้นจะยังคงขึ้นไปถึงและรวมทั้ง
การจัดอีเวนท์เป็นพื้นฐานสำหรับการมอบหมายอีเวนต์ในเบราว์เซอร์ ตอนนี้คุณสามารถผูกตัวจัดการเหตุการณ์กับองค์ประกอบพาเรนต์เดียวและตัวจัดการนั้นจะถูกดำเนินการเมื่อใดก็ตามที่เหตุการณ์เกิดขึ้นบนโหนดลูกใด ๆ (และลูก ๆ ของพวกเขา) นี่คือการมอบหมายกิจกรรม นี่คือตัวอย่างของมันในทางปฏิบัติ:
<ul onclick="alert(event.type + '!')">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
ด้วยตัวอย่างนั้นถ้าคุณต้องคลิกที่<li>
โหนดลูกใด ๆคุณจะเห็นการแจ้งเตือน"click!"
ถึงแม้ว่าจะไม่มีตัวจัดการการคลิกที่ถูกผูกไว้กับที่<li>
คุณคลิก หากเราผูกพันคุณonclick="..."
แต่ละคน<li>
จะได้รับผลกระทบที่เหมือนกัน
แล้วประโยชน์คืออะไร
ลองนึกภาพตอนนี้คุณจำเป็นต้องเพิ่ม<li>
รายการใหม่ไปยังรายการด้านบนผ่านการจัดการ DOM:
var newLi = document.createElement('li');
newLi.innerHTML = 'Four';
myUL.appendChild(newLi);
โดยไม่ต้องใช้การมอบหมายเหตุการณ์คุณจะต้อง "rebind" "onclick"
ตัวจัดการเหตุการณ์ไปยัง<li>
องค์ประกอบใหม่เพื่อให้มันทำหน้าที่เช่นเดียวกับพี่น้อง ด้วยการมอบหมายกิจกรรมคุณไม่จำเป็นต้องทำอะไร เพียงเพิ่มใหม่<li>
ลงในรายการและคุณทำเสร็จแล้ว
สิ่งนี้ยอดเยี่ยมมากสำหรับเว็บแอปที่มีตัวจัดการเหตุการณ์เชื่อมโยงกับองค์ประกอบหลายอย่างซึ่งองค์ประกอบใหม่จะถูกสร้างขึ้นและ / หรือลบออกใน DOM ด้วยการมอบหมายเหตุการณ์จำนวนของการผูกเหตุการณ์สามารถลดลงอย่างมากโดยการย้ายพวกเขาไปยังองค์ประกอบหลักทั่วไปและรหัสที่สร้างองค์ประกอบใหม่แบบไดนามิกได้ทันทีสามารถแยกออกจากตรรกะของการเชื่อมโยงตัวจัดการเหตุการณ์ของพวกเขา
ประโยชน์อีกประการหนึ่งสำหรับการมอบหมายเหตุการณ์คือการลดจำนวนหน่วยความจำทั้งหมดที่ใช้โดยตัวรับฟังเหตุการณ์ลดลง (เนื่องจากจำนวนการเชื่อมโยงเหตุการณ์ลดลง) มันอาจไม่ได้สร้างความแตกต่างมากนักสำหรับหน้าเล็ก ๆ ที่ขนถ่ายบ่อยครั้ง (เช่นผู้ใช้ไปยังหน้าต่าง ๆ บ่อยครั้ง) แต่สำหรับแอปพลิเคชันที่มีอายุการใช้งานยาวนานอาจมีความสำคัญ มีบางสถานการณ์ที่ยากต่อการติดตามเมื่อองค์ประกอบถูกลบออกจาก DOM ยังคงเรียกร้องหน่วยความจำ (เช่นพวกเขารั่วไหล) และบ่อยครั้งที่หน่วยความจำรั่วนี้ถูกผูกไว้กับเหตุการณ์ที่มีผลผูกพัน ด้วยการมอบหมายกิจกรรมคุณมีอิสระที่จะทำลายองค์ประกอบของเด็ก ๆ โดยไม่เสี่ยงที่จะลืม "แยก" ผู้ฟังเหตุการณ์ของพวกเขา (เนื่องจากผู้ฟังอยู่ที่บรรพบุรุษ) การรั่วไหลของหน่วยความจำประเภทนี้สามารถถูกเก็บไว้ได้ (ถ้าไม่ถูกกำจัดซึ่งยากที่จะทำในบางครั้ง IE กำลังมองหาคุณอยู่)
นี่คือตัวอย่างโค้ดที่ดีกว่าของการมอบหมายเหตุการณ์:
focus
และblur
กิจกรรม (ซึ่งไม่ทำให้เกิดฟอง)<li>
ควรหยุดได้<ul>
อย่างไร หากคำถามของฉันยังไม่ชัดเจนหรือต้องการเธรดแยกต่างหากฉันยินดีที่จะบังคับ
การมอบหมายกิจกรรมช่วยให้คุณหลีกเลี่ยงการเพิ่มตัวรับฟังเหตุการณ์ในโหนดที่ระบุ ผู้ฟังเหตุการณ์จะถูกเพิ่มเข้าไปในพาเรนต์เดียว ผู้ฟังเหตุการณ์นั้นจะวิเคราะห์เหตุการณ์ที่เกิดขึ้นเพื่อค้นหารายการที่ตรงกันในองค์ประกอบย่อย
ตัวอย่าง JavaScript:
สมมติว่าเรามีองค์ประกอบ UL หลักที่มีองค์ประกอบย่อยหลายประการ:
<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>
สมมติว่ามีบางสิ่งที่จำเป็นต้องเกิดขึ้นเมื่อองค์ประกอบลูกแต่ละอันถูกคลิก คุณสามารถเพิ่มผู้ฟังเหตุการณ์แยกกันในแต่ละองค์ประกอบ LI แต่จะเกิดอะไรขึ้นถ้าองค์ประกอบ LI ถูกเพิ่มและลบออกจากรายการบ่อยครั้ง การเพิ่มและลบผู้ฟังเหตุการณ์จะเป็นฝันร้ายโดยเฉพาะอย่างยิ่งหากการเพิ่มและลบรหัสอยู่ในสถานที่ต่าง ๆ ภายในแอปของคุณ ทางออกที่ดีกว่าคือการเพิ่มฟังเหตุการณ์ไปยังองค์ประกอบ UL หลัก แต่ถ้าคุณเพิ่มฟังเหตุการณ์ไปที่ผู้ปกครองคุณจะรู้ได้อย่างไรว่าองค์ประกอบใดถูกคลิก
ง่าย: เมื่อเหตุการณ์เกิดฟองอากาศจนถึงองค์ประกอบ UL คุณตรวจสอบคุณสมบัติเป้าหมายของวัตถุเหตุการณ์เพื่อรับการอ้างอิงไปยังโหนดที่คลิกจริง นี่คือตัวอย่าง JavaScript พื้นฐานที่แสดงการมอบหมายเหตุการณ์:
// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
// List item found! Output the ID!
console.log("List item ", e.target.id.replace("post-"), " was clicked!");
}
});
เริ่มต้นด้วยการเพิ่มฟังเหตุการณ์คลิกเพื่อองค์ประกอบหลัก เมื่อผู้เรียกเหตุการณ์ถูกเรียกใช้ให้ตรวจสอบองค์ประกอบเหตุการณ์เพื่อให้แน่ใจว่าเป็นประเภทขององค์ประกอบที่จะตอบสนอง ถ้ามันเป็นองค์ประกอบ LI บูม: เรามีสิ่งที่เราต้องการ! หากไม่ใช่องค์ประกอบที่เราต้องการเหตุการณ์ก็สามารถถูกละเว้นได้ ตัวอย่างนี้ค่อนข้างง่าย - UL และ LI เป็นการเปรียบเทียบแบบตรงไปตรงมา ลองทำอะไรที่ยากขึ้น มามี DIV พาเรนต์กับลูก ๆ หลาย ๆ คน แต่สิ่งที่เราใส่ใจคือแท็ก A พร้อมคลาส classA CSS
// Get the parent DIV, add click listener...
document.getElementById("myDiv").addEventListener("click",function(e) {
// e.target was the clicked element
if(e.target && e.target.nodeName == "A") {
// Get the CSS classes
var classes = e.target.className.split(" ");
// Search for the CSS class!
if(classes) {
// For every CSS class the element has...
for(var x = 0; x < classes.length; x++) {
// If it has the CSS class we want...
if(classes[x] == "classA") {
// Bingo!
console.log("Anchor element clicked!");
// Now do something here....
}
}
}
}
});
การมอบหมายเหตุการณ์โดมเป็นสิ่งที่แตกต่างจากคำนิยามของวิทยาศาสตร์คอมพิวเตอร์
มันหมายถึงการจัดการเหตุการณ์เดือดดาลจากองค์ประกอบหลายอย่างเช่นเซลล์ตารางจากวัตถุแม่เช่นตาราง มันสามารถทำให้โค้ดง่ายขึ้นโดยเฉพาะเมื่อเพิ่มหรือลบองค์ประกอบและบันทึกหน่วยความจำบางส่วน
คณะผู้แทนเป็นเทคนิคที่วัตถุแสดงพฤติกรรมบางอย่างไปสู่ภายนอก แต่ในความเป็นจริงได้มอบหมายความรับผิดชอบในการใช้พฤติกรรมนั้นไปยังวัตถุที่เกี่ยวข้อง เสียงนี้ในตอนแรกคล้ายกับรูปแบบพร็อกซี แต่มีจุดประสงค์ที่แตกต่างกันมาก การมอบหมายเป็นกลไกที่เป็นนามธรรมซึ่งรวบรวมพฤติกรรมของวัตถุ (เมธอด)
พูดโดยทั่วไป: ใช้การมอบหมายเป็นทางเลือกในการสืบทอด การสืบทอดเป็นกลยุทธ์ที่ดีเมื่อมีความสัมพันธ์ใกล้ชิดระหว่างวัตถุพ่อแม่และลูกอย่างไรก็ตามมรดกคู่วัตถุใกล้ชิดมาก บ่อยครั้งที่การมอบหมายเป็นวิธีที่ยืดหยุ่นกว่าในการแสดงความสัมพันธ์ระหว่างชั้นเรียน
รูปแบบนี้เรียกว่า "พร็อกซีเชน" รูปแบบการออกแบบอื่น ๆ อีกมากมายใช้การมอบหมาย - รัฐรูปแบบกลยุทธ์และผู้เข้าชมขึ้นอยู่กับมัน
หากมีองค์ประกอบหลายอย่างในหนึ่งพาเรนต์และคุณต้องการจัดการเหตุการณ์ที่เกิดขึ้นกับมัน - อย่าผูกตัวจัดการกับแต่ละองค์ประกอบ ให้ผูกตัวจัดการเดียวกับพาเรนต์และรับลูกจาก event.target ไซต์นี้ให้ข้อมูลที่เป็นประโยชน์เกี่ยวกับวิธีใช้การมอบหมายเหตุการณ์ http://javascript.info/tutorial/event-delegation
การมอบหมายกิจกรรมกำลังจัดการกับเหตุการณ์ที่ทำให้เกิดฟองโดยใช้ตัวจัดการเหตุการณ์บนองค์ประกอบคอนเทนเนอร์ แต่จะเปิดใช้งานพฤติกรรมของตัวจัดการเหตุการณ์เท่านั้นหากเหตุการณ์เกิดขึ้นบนองค์ประกอบภายในคอนเทนเนอร์ที่ตรงกับเงื่อนไขที่กำหนด สิ่งนี้สามารถทำให้การจัดการเหตุการณ์บนองค์ประกอบภายในคอนเทนเนอร์ง่ายขึ้น
ตัวอย่างเช่นสมมติว่าคุณต้องการจัดการการคลิกในเซลล์ตารางใด ๆ ในตารางขนาดใหญ่ คุณทำได้เขียนลูปเพื่อเชื่อมต่อตัวจัดการคลิกไปยังแต่ละเซลล์ ... หรือคุณสามารถเชื่อมโยงตัวจัดการคลิกบนตารางและใช้การมอบหมายเหตุการณ์เพื่อเรียกใช้เฉพาะเซลล์ตารางเท่านั้น (และไม่ใช่ส่วนหัวของตารางหรือช่องว่างภายใน แถวรอบเซลล์ ฯลฯ )
นอกจากนี้ยังมีประโยชน์เมื่อคุณจะเพิ่มและลบองค์ประกอบออกจากคอนเทนเนอร์เนื่องจากคุณไม่ต้องกังวลกับการเพิ่มและลบตัวจัดการเหตุการณ์ในองค์ประกอบเหล่านั้น เพียงแค่เกี่ยวเหตุการณ์บนภาชนะและจัดการเหตุการณ์เมื่อมันฟอง
ต่อไปนี้เป็นตัวอย่างง่ายๆ (โดยเจตนาจะให้คำอธิบายแบบอินไลน์): การจัดการการคลิกที่td
องค์ประกอบใด ๆในตารางคอนเทนเนอร์:
// Handle the event on the container
document.getElementById("container").addEventListener("click", function(event) {
// Find out if the event targeted or bubbled through a `td` en route to this container element
var element = event.target;
var target;
while (element && !target) {
if (element.matches("td")) {
// Found a `td` within the container!
target = element;
} else {
// Not found
if (element === this) {
// We've reached the container, stop
element = null;
} else {
// Go to the next parent in the ancestry
element = element.parentNode;
}
}
}
if (target) {
console.log("You clicked a td: " + target.textContent);
} else {
console.log("That wasn't a td in the container table");
}
});
table {
border-collapse: collapse;
border: 1px solid #ddd;
}
th, td {
padding: 4px;
border: 1px solid #ddd;
font-weight: normal;
}
th.rowheader {
text-align: left;
}
td {
cursor: pointer;
}
<table id="container">
<thead>
<tr>
<th>Language</th>
<th>1</th>
<th>2</th>
<th>3</th>
</tr>
</thead>
<tbody>
<tr>
<th class="rowheader">English</th>
<td>one</td>
<td>two</td>
<td>three</td>
</tr>
<tr>
<th class="rowheader">Español</th>
<td>uno</td>
<td>dos</td>
<td>tres</td>
</tr>
<tr>
<th class="rowheader">Italiano</th>
<td>uno</td>
<td>due</td>
<td>tre</td>
</tr>
</tbody>
</table>
ก่อนที่จะเข้าไปดูรายละเอียดของสิ่งนั้นขอเตือนตัวเองว่ากิจกรรม DOM ทำงานอย่างไร
เหตุการณ์ DOM ถูกส่งจากเอกสารไปยังองค์ประกอบเป้าหมาย ( เฟสการจับภาพ ) จากนั้นต่อมน้ำจากองค์ประกอบเป้าหมายกลับไปที่เอกสาร ( เฟสการทำให้เป็นฟอง ) กราฟิกนี้ในข้อมูลจำเพาะเหตุการณ์ DOM3เก่า(ตอนนี้ถูกแทนที่แล้ว แต่กราฟิกยังคงใช้ได้) แสดงได้ดี:
ไม่ทุกเหตุการณ์ฟอง click
แต่ส่วนใหญ่ทำรวมทั้ง
ความคิดเห็นในตัวอย่างโค้ดด้านบนอธิบายการทำงานของมัน matches
ตรวจสอบเพื่อดูว่าองค์ประกอบตรงกับตัวเลือก CSS หรือไม่ แต่แน่นอนคุณสามารถตรวจสอบว่ามีบางสิ่งที่ตรงกับเกณฑ์ของคุณด้วยวิธีอื่น ๆ หรือไม่ถ้าคุณไม่ต้องการใช้ตัวเลือก CSS
รหัสนั้นเขียนขึ้นเพื่อเรียกใช้แต่ละขั้นตอนอย่างละเอียด แต่ในเบราว์เซอร์ที่ทันสมัย (และใน IE หากคุณใช้ polyfill) คุณสามารถใช้closest
และcontains
แทนที่จะวนซ้ำ:
var target = event.target.closest("td");
console.log("You clicked a td: " + target.textContent);
} else {
console.log("That wasn't a td in the container table");
}
ตัวอย่างสด:
closest
ตรวจสอบองค์ประกอบที่คุณเรียกใช้เพื่อดูว่าตรงกับตัวเลือก CSS ที่กำหนดหรือไม่และส่งคืนองค์ประกอบเดียวกันนั้นหรือไม่ ถ้าไม่มันจะตรวจสอบองค์ประกอบหลักเพื่อดูว่ามันตรงกันและส่งกลับผู้ปกครองถ้าใช่; ถ้าไม่มันจะตรวจสอบผู้ปกครองของผู้ปกครอง ฯลฯ ดังนั้นจึงพบองค์ประกอบ "ใกล้ที่สุด" ในรายการบรรพบุรุษที่ตรงกับตัวเลือก เนื่องจากอาจผ่านองค์ประกอบคอนเทนเนอร์รหัสด้านบนใช้contains
เพื่อตรวจสอบว่าพบองค์ประกอบที่ตรงกันหรือไม่มันอยู่ในคอนเทนเนอร์ - เนื่องจากโดยการเชื่อมโยงเหตุการณ์บนคอนเทนเนอร์คุณได้ระบุว่าคุณต้องการจัดการองค์ประกอบภายในคอนเทนเนอร์นั้นเท่านั้น .
กลับไปที่ตัวอย่างตารางของเราซึ่งหมายความว่าถ้าคุณมีตารางภายในเซลล์ตารางมันจะไม่ตรงกับเซลล์ตารางที่มีตาราง:
โดยพื้นฐานแล้วการเชื่อมโยงองค์ประกอบเข้าด้วยกัน .click
ใช้กับ DOM ปัจจุบันในขณะที่.on
(โดยใช้การมอบหมาย) จะยังคงใช้ได้สำหรับองค์ประกอบใหม่ที่เพิ่มใน DOM หลังจากการเชื่อมโยงเหตุการณ์
สิ่งที่ดีกว่าที่จะใช้ฉันจะบอกว่ามันขึ้นอยู่กับกรณี
ตัวอย่าง:
<ul id="todo">
<li>Do 1</li>
<li>Do 2</li>
<li>Do 3</li>
<li>Do 4</li>
</ul>
.Click กิจกรรม:
$("li").click(function () {
$(this).remove ();
});
กิจกรรม. on:
$("#todo").on("click", "li", function () {
$(this).remove();
});
โปรดทราบว่าฉันได้แยกตัวเลือกใน. on ฉันจะอธิบายว่าทำไม
ให้เราสมมติว่าหลังจากสมาคมนี้ให้เราทำสิ่งต่อไปนี้:
$("#todo").append("<li>Do 5</li>");
นั่นคือที่ที่คุณจะสังเกตเห็นความแตกต่าง
หากกิจกรรมมีการเชื่อมโยงผ่าน. คลิกภารกิจ 5 จะไม่เชื่อฟังเหตุการณ์คลิกดังนั้นจะไม่ถูกลบออก
หากมีการเชื่อมโยงผ่าน. on โดยมีตัวเลือกแยกต่างหากก็จะเชื่อฟัง
เพื่อให้เข้าใจถึงการมอบหมายเหตุการณ์ก่อนอื่นเราต้องรู้ว่าทำไมและเมื่อใดที่เราต้องการหรือต้องการการมอบหมายกิจกรรม
อาจมีหลายกรณี แต่ให้หารือเกี่ยวกับกรณีใช้งานใหญ่สองกรณีสำหรับการมอบหมายเหตุการณ์ 1. กรณีแรกคือเมื่อเรามีองค์ประกอบที่มีองค์ประกอบย่อย ๆ มากมายที่เราสนใจในกรณีนี้แทนที่จะเพิ่มตัวจัดการเหตุการณ์ให้กับองค์ประกอบย่อยทั้งหมดเราเพียงแค่เพิ่มองค์ประกอบหลักแล้วกำหนด องค์ประกอบลูกเหตุการณ์ถูกไล่ออก
2. กรณีการใช้งานที่สองสำหรับการมอบหมายเหตุการณ์คือเมื่อเราต้องการให้ตัวจัดการเหตุการณ์แนบกับองค์ประกอบที่ยังไม่ได้อยู่ใน DOM เมื่อโหลดหน้าเว็บของเรา แน่นอนว่าเพราะเราไม่สามารถเพิ่มตัวจัดการเหตุการณ์ให้กับสิ่งที่ไม่ได้อยู่ในหน้าของเราดังนั้นในกรณีที่เราไม่ได้เข้ารหัส
สมมติว่าคุณมีรายการ 0, 10 หรือ 100 รายการใน DOM เมื่อคุณโหลดหน้าของคุณและมีอีกหลายรายการที่รออยู่ในมือของคุณเพื่อเพิ่มในรายการ ดังนั้นจึงไม่มีวิธีแนบตัวจัดการเหตุการณ์สำหรับองค์ประกอบในอนาคตหรือองค์ประกอบเหล่านั้นยังไม่ได้เพิ่มใน DOM และยังอาจมีรายการจำนวนมากดังนั้นจึงไม่มีประโยชน์ที่จะมีตัวจัดการเหตุการณ์หนึ่งตัวแนบอยู่กับแต่ละรายการ ของพวกเขา.
การมอบหมายกิจกรรม
เอาล่ะดังนั้นเพื่อที่จะพูดคุยเกี่ยวกับการมอบหมายเหตุการณ์แนวคิดแรกที่เราต้องพูดถึงคือการจัดอีเวนท์
การทำ bubbling ของเหตุการณ์: bubbling ของ เหตุการณ์หมายความว่าเมื่อมีเหตุการณ์ถูกเรียกใช้หรือถูกเรียกใช้ในองค์ประกอบ DOM บางตัวอย่างเช่นโดยการคลิกที่ปุ่มของเราที่นี่ในภาพด้านล่างจากนั้นเหตุการณ์เดียวกันที่แน่นอนจะถูกเรียกใช้ในองค์ประกอบหลักทั้งหมด
เหตุการณ์ถูกยิงครั้งแรกที่ปุ่ม แต่จากนั้นจะถูกยิงในองค์ประกอบหลักทั้งหมดทีละครั้งดังนั้นมันจะยิงในย่อหน้าไปยังส่วนองค์ประกอบหลักและจริง ๆ แล้วขึ้นไปบนต้นไม้ DOM จนกระทั่งองค์ประกอบ HTML ซึ่งเป็นรูต ดังนั้นเราจึงบอกว่าเหตุการณ์ระเบิดขึ้นภายในต้นไม้ DOM และนั่นคือเหตุผลที่เรียกว่าเดือดปุด ๆ
องค์ประกอบเป้าหมาย:องค์ประกอบที่เหตุการณ์ถูกยิงครั้งแรกที่เรียกว่าองค์ประกอบเป้าหมายดังนั้นองค์ประกอบที่ทำให้เกิดเหตุการณ์ที่เกิดขึ้นจะเรียกว่าองค์ประกอบเป้าหมาย ในตัวอย่างข้างต้นของเราที่นี่แน่นอนว่าปุ่มที่ถูกคลิก ส่วนที่สำคัญคือองค์ประกอบเป้าหมายนี้ถูกเก็บไว้เป็นคุณสมบัติในวัตถุเหตุการณ์ซึ่งหมายความว่าองค์ประกอบหลักทั้งหมดที่เหตุการณ์จะเริ่มทำงานจะทราบองค์ประกอบเป้าหมายของเหตุการณ์ดังนั้นเมื่อมีการเริ่มกิจกรรมครั้งแรก
สิ่งนี้นำเราไปสู่การมอบหมายกิจกรรมเพราะหากเหตุการณ์นั้นเกิดขึ้นในต้นไม้ DOM และถ้าเรารู้ว่าเหตุการณ์ถูกไล่ออกเราสามารถแนบตัวจัดการเหตุการณ์เข้ากับองค์ประกอบหลักและรอเหตุการณ์ที่จะเกิดขึ้นและเราสามารถ จากนั้นทำสิ่งที่เราตั้งใจจะทำกับองค์ประกอบเป้าหมายของเรา เทคนิคนี้เรียกว่าการมอบหมายกิจกรรม ในตัวอย่างนี้ที่นี่เราสามารถเพิ่มตัวจัดการเหตุการณ์ให้กับองค์ประกอบหลัก
เอาล่ะอีกครั้งการมอบหมายกิจกรรมคือการไม่ตั้งค่าตัวจัดการเหตุการณ์ในองค์ประกอบดั้งเดิมที่เราสนใจ แต่เพื่อแนบไปกับองค์ประกอบหลักและโดยทั่วไปจะจับเหตุการณ์ที่นั่นเพราะมันทำให้เกิดฟองขึ้น จากนั้นเราสามารถดำเนินการกับองค์ประกอบที่เราสนใจในการใช้คุณสมบัติองค์ประกอบเป้าหมาย
ตัวอย่าง: ตอนนี้สมมติว่าเรามีสองรายการในหน้าของเราหลังจากเพิ่มรายการในรายการเหล่านั้นโดยทางโปรแกรมเราต้องการลบหนึ่งรายการหรือมากกว่าจากรายการเหล่านั้น การใช้การมอบหมายเหตุการณ์ทำให้เราสามารถบรรลุเป้าหมายของเราได้อย่างง่ายดาย
<div class="body">
<div class="top">
</div>
<div class="bottom">
<div class="other">
<!-- other bottom elements -->
</div>
<div class="container clearfix">
<div class="income">
<h2 class="icome__title">Income</h2>
<div class="income__list">
<!-- list items -->
</div>
</div>
<div class="expenses">
<h2 class="expenses__title">Expenses</h2>
<div class="expenses__list">
<!-- list items -->
</div>
</div>
</div>
</div>
</div>
การเพิ่มรายการในรายการเหล่านั้น:
const DOMstrings={
type:{
income:'inc',
expense:'exp'
},
incomeContainer:'.income__list',
expenseContainer:'.expenses__list',
container:'.container'
}
var addListItem = function(obj, type){
//create html string with the place holder
var html, element;
if(type===DOMstrings.type.income){
element = DOMstrings.incomeContainer
html = `<div class="item clearfix" id="inc-${obj.id}">
<div class="item__description">${obj.descripiton}</div>
<div class="right clearfix">
<div class="item__value">${obj.value}</div>
<div class="item__delete">
<button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
</div>
</div>
</div>`
}else if (type ===DOMstrings.type.expense){
element=DOMstrings.expenseContainer;
html = ` <div class="item clearfix" id="exp-${obj.id}">
<div class="item__description">${obj.descripiton}</div>
<div class="right clearfix">
<div class="item__value">${obj.value}</div>
<div class="item__percentage">21%</div>
<div class="item__delete">
<button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
</div>
</div>
</div>`
}
var htmlObject = document.createElement('div');
htmlObject.innerHTML=html;
document.querySelector(element).insertAdjacentElement('beforeend', htmlObject);
}
ลบรายการ:
var ctrlDeleteItem = function(event){
// var itemId = event.target.parentNode.parentNode.parentNode.parentNode.id;
var parent = event.target.parentNode;
var splitId, type, ID;
while(parent.id===""){
parent = parent.parentNode
}
if(parent.id){
splitId = parent.id.split('-');
type = splitId[0];
ID=parseInt(splitId[1]);
}
deleteItem(type, ID);
deleteListItem(parent.id);
}
var deleteItem = function(type, id){
var ids, index;
ids = data.allItems[type].map(function(current){
return current.id;
});
index = ids.indexOf(id);
if(index>-1){
data.allItems[type].splice(index,1);
}
}
var deleteListItem = function(selectorID){
var element = document.getElementById(selectorID);
element.parentNode.removeChild(element);
}
ผู้รับมอบสิทธิ์ใน C # จะคล้ายกับตัวชี้ฟังก์ชันใน C หรือ C ++ การใช้ผู้รับมอบสิทธิ์อนุญาตให้โปรแกรมเมอร์เขียนแค็ปซูลการอ้างอิงไปยังวิธีการภายในวัตถุผู้รับมอบสิทธิ์ วัตถุผู้รับมอบสิทธิ์นั้นสามารถส่งผ่านไปยังรหัสที่สามารถเรียกวิธีการอ้างอิงโดยไม่ต้องรู้เวลารวบรวมวิธีการที่จะถูกเรียก
ดูลิงค์นี้ -> http://www.akadia.com/services/dotnet_delegates_and_events.html
การมอบหมายกิจกรรมใช้คุณสมบัติสองอย่างที่มักถูกมองข้ามของเหตุการณ์ JavaScript: การสร้างเหตุการณ์และองค์ประกอบเป้าหมายเมื่อมีเหตุการณ์ที่เกิดขึ้นกับองค์ประกอบเช่นการคลิกเมาส์ที่ปุ่มเหตุการณ์เดียวกันจะถูกเรียกใช้บนบรรพบุรุษขององค์ประกอบนั้น . กระบวนการนี้เรียกว่า bubbling ของเหตุการณ์ เหตุการณ์ที่เกิดขึ้นฟองอากาศจากองค์ประกอบที่กำเนิดไปด้านบนของต้นไม้ DOM
ลองนึกภาพตาราง HTML ที่มี 10 คอลัมน์และ 100 แถวที่คุณต้องการให้บางสิ่งเกิดขึ้นเมื่อผู้ใช้คลิกที่เซลล์ตาราง ตัวอย่างเช่นฉันเคยทำให้แต่ละเซลล์ของตารางขนาดนั้นสามารถแก้ไขได้เมื่อคลิก การเพิ่มตัวจัดการเหตุการณ์ให้กับแต่ละ 1000 เซลล์จะเป็นปัญหาด้านประสิทธิภาพที่สำคัญและอาจเป็นสาเหตุของการรั่วไหลของหน่วยความจำที่เบราว์เซอร์ล้มเหลว คุณสามารถเพิ่มตัวจัดการเหตุการณ์เพียงหนึ่งตัวในองค์ประกอบตารางแทนเหตุการณ์การคลิกและกำหนดเซลล์ที่ถูกคลิกแทน
แนบผู้ฟังเหตุการณ์เข้ากับองค์ประกอบหลักที่จะยิงเมื่อมีเหตุการณ์เกิดขึ้นในองค์ประกอบลูก
การเผยแพร่เหตุการณ์เมื่อเหตุการณ์เคลื่อนผ่าน DOM จากชายด์ไปยังองค์ประกอบพาเรนต์นั่นเรียกว่าการเผยแพร่เหตุการณ์เนื่องจากกิจกรรมเผยแพร่หรือย้ายผ่าน DOM
ในตัวอย่างนี้เหตุการณ์ (onclick) จากปุ่มจะถูกส่งผ่านไปยังย่อหน้าหลัก
$(document).ready(function() {
$(".spoiler span").hide();
/* add event onclick on parent (.spoiler) and delegate its event to child (button) */
$(".spoiler").on( "click", "button", function() {
$(".spoiler button").hide();
$(".spoiler span").show();
} );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<p class="spoiler">
<span>Hello World</span>
<button>Click Me</button>
</p>