ความแตกต่างระหว่างaddEventListener
และonclick
คืออะไร
var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);
รหัสข้างต้นอยู่ร่วมกันในไฟล์. js แยกต่างหากและทำงานได้อย่างสมบูรณ์
ความแตกต่างระหว่างaddEventListener
และonclick
คืออะไร
var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);
รหัสข้างต้นอยู่ร่วมกันในไฟล์. js แยกต่างหากและทำงานได้อย่างสมบูรณ์
คำตอบ:
ทั้งสองอย่างถูกต้อง แต่ไม่มีสิ่งใดที่ "ดีที่สุด" ต่อ se และอาจมีเหตุผลที่ผู้พัฒนาเลือกใช้ทั้งสองวิธี
Event Listeners (addEventListener และ attachEvent ของ IE)
Internet Explorer เวอร์ชันก่อนหน้าใช้งานจาวาสคริปต์ที่แตกต่างจากเบราว์เซอร์อื่น ๆ ด้วยรุ่นที่น้อยกว่า 9 คุณใช้วิธีattachEvent
[ doc ] เช่นนี้:
element.attachEvent('onclick', function() { /* do stuff here*/ });
ในเบราว์เซอร์อื่น ๆ ส่วนใหญ่ (รวมถึง IE 9 ขึ้นไป) คุณใช้addEventListener
[ doc ] เช่นนี้:
element.addEventListener('click', function() { /* do stuff here*/ }, false);
การใช้วิธีการนี้ ( เหตุการณ์ DOM ระดับ 2 ) คุณสามารถแนบจำนวนเหตุการณ์ได้ไม่ จำกัด ตามหลักเหตุผลกับองค์ประกอบเดียว ข้อ จำกัด เชิงปฏิบัติเพียงข้อเดียวคือหน่วยความจำฝั่งไคลเอ็นต์และข้อกังวลด้านประสิทธิภาพอื่น ๆ ซึ่งแตกต่างกันสำหรับแต่ละเบราว์เซอร์
ตัวอย่างข้างต้นแสดงถึงการใช้ฟังก์ชั่นที่ไม่ระบุชื่อ [ doc ] นอกจากนี้คุณยังสามารถเพิ่มฟังเหตุการณ์โดยใช้ฟังก์ชั่นอ้างอิง [ doc ] หรือปิด [ doc ]:
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
คุณสมบัติที่สำคัญอีกอย่างหนึ่งของaddEventListener
พารามิเตอร์สุดท้ายคือการควบคุมวิธีการที่ผู้ฟังตอบสนองต่อเหตุการณ์เดือดดาล [ doc ] ฉันได้ลองผิดลองถูกในตัวอย่างซึ่งเป็นมาตรฐานสำหรับกรณีการใช้งาน 95% ไม่มีอาร์กิวเมนต์ที่เทียบเท่าสำหรับattachEvent
หรือเมื่อใช้เหตุการณ์แบบอินไลน์
เหตุการณ์แบบอินไลน์ (HTML onclick = "" คุณสมบัติและ element.onclick)
ในเบราว์เซอร์ทั้งหมดที่รองรับจาวาสคริปต์คุณสามารถใส่ตัวฟังเหตุการณ์แบบอินไลน์ซึ่งมีความหมายในโค้ด HTML คุณอาจเคยเห็นสิ่งนี้:
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
นักพัฒนาที่มีประสบการณ์ส่วนใหญ่หลีกเลี่ยงวิธีการนี้ แต่มันก็ทำงานได้สำเร็จ มันง่ายและตรงไปตรงมา คุณไม่สามารถใช้ฟังก์ชันการปิดหรือฟังก์ชันที่ไม่ระบุตัวตนได้ที่นี่ (แม้ว่าตัวจัดการนั้นเป็นฟังก์ชันที่ไม่ระบุตัวตน) และการควบคุมขอบเขตของคุณมี จำกัด
วิธีอื่นที่คุณพูดถึง:
element.onclick = function () { /*do stuff here */ };
... เทียบเท่ากับจาวาสคริปต์แบบอินไลน์ยกเว้นว่าคุณสามารถควบคุมขอบเขตได้มากขึ้น (เนื่องจากคุณกำลังเขียนสคริปต์มากกว่า HTML) และสามารถใช้ฟังก์ชันที่ไม่ระบุชื่อการอ้างอิงฟังก์ชันและ / หรือการปิด
ข้อเสียเปรียบที่สำคัญกับเหตุการณ์แบบอินไลน์คือการที่แตกต่างจากผู้ฟังเหตุการณ์ที่อธิบายไว้ข้างต้นคุณอาจได้รับมอบหมายเหตุการณ์แบบอินไลน์เพียงครั้งเดียว เหตุการณ์แบบอินไลน์จะถูกจัดเก็บเป็นคุณลักษณะ / คุณสมบัติขององค์ประกอบ [ doc ] ซึ่งหมายความว่าสามารถเขียนทับได้
ใช้ตัวอย่าง<a>
จาก HTML ด้านบน:
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
... เมื่อคุณคลิกที่องค์ประกอบคุณจะเห็นเฉพาะ "สิ่งที่ # 2" - คุณเขียนทับคุณสมบัติแรกที่ได้รับมอบหมายonclick
ด้วยค่าที่สองและคุณเขียนทับonclick
คุณสมบัติHTML แบบอินไลน์ต้นฉบับด้วย ตรวจสอบออกที่นี่: http://jsfiddle.net/jpgah/
พูดกว้างไม่ได้ใช้เหตุการณ์แบบอินไลน์ อาจมีกรณีการใช้งานเฉพาะสำหรับมัน แต่ถ้าคุณไม่แน่ใจ 100% ว่าคุณมีกรณีการใช้งานนั้นคุณไม่ควรใช้และไม่ควรใช้เหตุการณ์แบบอินไลน์
Javascript สมัยใหม่ (เชิงมุมและที่คล้ายกัน)
เนื่องจากคำตอบนี้ถูกโพสต์ครั้งแรกเฟรมเวิร์กจาวาสคริปต์เช่น Angular ได้รับความนิยมมาก คุณจะเห็นโค้ดลักษณะนี้ในเทมเพลต Angular:
<button (click)="doSomething()">Do Something</button>
ดูเหมือนว่าเหตุการณ์แบบอินไลน์ แต่ไม่ใช่ เทมเพลตประเภทนี้จะถูกแปลงเป็นรหัสที่ซับซ้อนยิ่งขึ้นซึ่งใช้ฟังเหตุการณ์หลังฉาก ทุกสิ่งที่ฉันเขียนเกี่ยวกับเหตุการณ์ที่นี่ยังคงใช้อยู่ แต่คุณจะถูกลบออกจาก nitty gritty อย่างน้อยหนึ่งเลเยอร์ คุณควรเข้าใจถั่วและโบลต์ แต่หากแนวปฏิบัติที่ดีที่สุดของเฟรมเวิร์ก JS ของคุณเกี่ยวข้องกับการเขียนโค้ดชนิดนี้ในเทมเพลตอย่ารู้สึกว่าคุณกำลังใช้เหตุการณ์อินไลน์ - คุณไม่ใช่
ไหนดีที่สุด
คำถามคือเรื่องของความเข้ากันได้และความจำเป็นของเบราว์เซอร์ คุณต้องการแนบมากกว่าหนึ่งเหตุการณ์กับองค์ประกอบหรือไม่? ในอนาคตคุณจะ เป็นไปได้ที่คุณจะ attachEvent และ addEventListener จำเป็น ถ้าไม่ใช่เหตุการณ์แบบอินไลน์อาจดูเหมือนว่าพวกเขาทำเคล็ดลับ แต่คุณจะได้รับการเตรียมพร้อมที่ดีกว่าสำหรับอนาคตที่แม้ว่ามันอาจดูเหมือนไม่น่าเป็นไปได้ก็ตาม มีโอกาสที่คุณจะต้องย้ายไปที่ผู้ฟังเหตุการณ์ที่ใช้ JS ดังนั้นคุณอาจเพิ่งเริ่มต้นด้วย อย่าใช้เหตุการณ์แบบอินไลน์
jQuery และเฟรมเวิร์ก javascript อื่น ๆ ห่อหุ้มการใช้งานเบราว์เซอร์ที่แตกต่างกันของเหตุการณ์ DOM ระดับ 2 ในรุ่นทั่วไปเพื่อให้คุณสามารถเขียนรหัสที่สอดคล้องกับเบราว์เซอร์โดยไม่ต้องกังวลเกี่ยวกับประวัติของ IE ในฐานะกบฏ รหัสเดียวกันกับ jQuery เบราว์เซอร์ทั้งหมดและพร้อมที่จะเขย่า:
$(element).on('click', function () { /* do stuff */ });
อย่าวิ่งออกไปและได้กรอบสำหรับสิ่งนี้แม้ว่า คุณสามารถหมุนยูทิลิตี้ตัวเล็ก ๆ ของคุณเองเพื่อดูแลเบราว์เซอร์รุ่นเก่าได้อย่างง่ายดาย:
function addEvent(element, evnt, funct){
if (element.attachEvent)
return element.attachEvent('on'+evnt, funct);
else
return element.addEventListener(evnt, funct, false);
}
// example
addEvent(
document.getElementById('myElement'),
'click',
function () { alert('hi!'); }
);
ลองทำดู: http://jsfiddle.net/bmArj/
การพิจารณาทั้งหมดนั้นนอกจากว่าสคริปต์ที่คุณดูจะคำนึงถึงความแตกต่างของเบราว์เซอร์ด้วยวิธีอื่น (ในโค้ดที่ไม่แสดงในคำถามของคุณ) ส่วนที่ใช้addEventListener
จะไม่ทำงานใน IE เวอร์ชันต่ำกว่า 9
เอกสารและการอ่านที่เกี่ยวข้อง
function addEvent(e,n,f){return e.attachEvent?e.attachEvent('on'+n,f):e.addEventListener(n,f,!!0)}
<< ที่ 98 ตัวอักษรตัวนี้เล็กกว่า 40%!
ความแตกต่างที่คุณสามารถดูได้ถ้าคุณมีฟังก์ชั่นอีกสองอย่าง
var h = document.getElementById('a');
h.onclick = doThing_1;
h.onclick = doThing_2;
h.addEventListener('click', doThing_3);
h.addEventListener('click', doThing_4);
ฟังก์ชั่น 2, 3 และ 4 ทำงาน แต่ 1 ไม่ได้ นี่เป็นเพราะaddEventListener
ไม่ได้เขียนทับตัวจัดการเหตุการณ์ที่มีอยู่ในขณะที่onclick
แทนที่onclick = fn
ตัวจัดการเหตุการณ์ที่มีอยู่ใด ๆ
แน่นอนความแตกต่างที่สำคัญอื่น ๆ ก็คือมันonclick
จะใช้งานได้ตลอดเวลา แต่addEventListener
จะไม่ทำงานใน Internet Explorer ก่อนรุ่น 9 คุณสามารถใช้แบบอะนาล็อกattachEvent
(ซึ่งมีไวยากรณ์แตกต่างกันเล็กน้อย ) ใน IE <9
ในคำตอบนี้ฉันจะอธิบายสามวิธีในการกำหนดตัวจัดการเหตุการณ์ DOM
element.addEventListener()
ตัวอย่างรหัส:
element.addEventListener()
มีข้อดีหลายประการ:
element.removeEventListener()
ไสเหตุการณ์และลบพวกเขาด้วยuseCapture
พารามิเตอร์ซึ่งบ่งชี้ว่าคุณต้องการที่จะจัดการกับเหตุการณ์ของการจับภาพหรือเฟสเดือดปุด ๆ ดู: ไม่เข้าใจแอตทริบิวต์ useCapture ใน addEventListener.onevent
คุณสมบัติขององค์ประกอบ DOM จำนวนมากของการเขียนโปรแกรมจาวาสคริปต์ที่ไม่มีประสบการณ์คิดว่าชื่อเหตุการณ์เป็นตัวอย่างหรือonclick
คือไม่ได้เป็นส่วนหนึ่งของชื่อเหตุการณ์ ชื่อเหตุการณ์ที่ถูกต้องและและว่าเป็นวิธีที่ชื่อเหตุการณ์จะถูกส่งผ่านไปยังonload
on
click
load
.addEventListener()
element.onevent = function() {}
(เช่นonclick
, onload
)ตัวอย่างรหัส:
นี่เป็นวิธีการลงทะเบียนตัวจัดการเหตุการณ์ใน DOM 0 ตอนนี้หมดกำลังใจเพราะ:
onevent
คุณสมบัติกลับไปเป็นสถานะเริ่มต้น (เช่นnull
)window.onload
ตัวอย่างเช่น: window.onload = "test";
จะไม่ทำให้เกิดข้อผิดพลาดใด ๆ รหัสของคุณใช้งานไม่ได้และมันยากมากที่จะหาสาเหตุ .addEventListener()
แต่จะโยนความผิดพลาด (อย่างน้อยใน Firefox): TypeError: อาร์กิวเมนต์ที่ 2 ของ EventTarget.addEventListener ไม่ได้เป็นวัตถุonevent
แอตทริบิวต์ HTML)ตัวอย่างรหัส:
ในทำนองเดียวกันelement.onevent
มันก็หมดกำลังใจ นอกเหนือจากปัญหาที่element.onevent
มี:
Content-Security-Policy
ส่วนหัว HTTP ที่เหมาะสมเพื่อบล็อกสคริปต์แบบอินไลน์และอนุญาตสคริปต์ภายนอกจากโดเมนที่เชื่อถือได้เท่านั้น ดูนโยบายความปลอดภัยของเนื้อหาทำงานอย่างไรแม้ว่าจะonclick
ใช้ได้กับทุกเบราว์เซอร์ แต่addEventListener
ไม่สามารถใช้งานได้ใน Internet Explorer เวอร์ชันเก่าซึ่งใช้attachEvent
แทน
ข้อเสียonclick
คือสามารถมีตัวจัดการเหตุการณ์ได้เพียงคนเดียวในขณะที่อีกสองคนจะใช้การเรียกกลับที่ลงทะเบียนไว้ทั้งหมด
เท่าที่ฉันรู้เหตุการณ์ "โหลด" DOM ยังคงทำงานได้ จำกัด มาก นั่นหมายความว่ามันจะยิงสำหรับwindow object
, images
และ<script>
องค์ประกอบเช่น เช่นเดียวกันสำหรับการonload
กำหนดโดยตรง ไม่มีความแตกต่างทางเทคนิคระหว่างสองสิ่งนี้ อาจ.onload =
มีความได้เปรียบข้ามเบราว์เซอร์ที่ดีขึ้น
อย่างไรก็ตามคุณไม่สามารถกำหนดload event
ให้เป็น<div>
หรือ<span>
องค์ประกอบหรือ whatnot
addEventListener
สามารถเพิ่มหลายเหตุการณ์ในขณะที่onclick
สิ่งนี้ไม่สามารถทำได้onclick
สามารถเพิ่มเป็นHTML
แอตทริบิวต์ได้ในขณะที่addEventListener
สามารถเพิ่มได้ภายใน<script>
องค์ประกอบเท่านั้นaddEventListener
สามารถใช้อาร์กิวเมนต์ที่สามซึ่งสามารถหยุดการเผยแพร่เหตุการณ์ทั้งสองสามารถใช้เพื่อจัดการเหตุการณ์ อย่างไรก็ตามaddEventListener
ควรเป็นตัวเลือกที่ต้องการเนื่องจากสามารถทำทุกอย่างได้onclick
และอื่น ๆ อย่าใช้อินไลน์onclick
เป็นแอตทริบิวต์ HTML เนื่องจากเป็นการรวม javascript และ HTML เข้าด้วยกันซึ่งเป็นวิธีปฏิบัติที่ไม่ดี มันทำให้รหัสบำรุงรักษาน้อย
onclick
เพราะกลัวว่าจะถูกหัวเราะออกไปจากห้อง - แต่โดยปกติแล้วเหตุการณ์ต่าง ๆ จะเลวร้ายลงและมีวิธีดูแลน้อยลงในช่วงไม่กี่ปีที่ผ่านมา เรียนชอบjs-link
, js-form-validation
หรือข้อมูลคุณลักษณะที่มีdata-jspackage="init"
อยู่ในทางใด ๆ ดีกว่า ... และวิธีการ ofteen คุณจริงใช้เดือดเหตุการณ์? โดยส่วนตัวฉันชอบที่จะเขียน handler โดยไม่ตรวจสอบว่าเป้าหมายนั้นตรงกับองค์ประกอบของฉันหรือไม่ต้องหยุดการแพร่กระจายในหลาย ๆ ที่เนื่องจากข้อผิดพลาดแบบสุ่ม
ยังไม่มีการบันทึกรายละเอียดหนึ่ง: เบราว์เซอร์เดสก์ท็อปที่ทันสมัยพิจารณากดปุ่มที่แตกต่างกันเพื่อ "คลิก" สำหรับAddEventListener('click'
และonclick
โดยค่าเริ่มต้น
onclick
และAddEventListener
คลิกไฟบนคลิกซ้ายและกลางonclick
ยิงเฉพาะการคลิกซ้าย แต่การAddEventListener
คลิกจะเป็นการคลิกที่ซ้ายกลางและขวานอกจากนี้พฤติกรรมการคลิกกลางยังไม่สอดคล้องกันมากในเบราว์เซอร์เมื่อเคอร์เซอร์เลื่อนมีส่วนร่วม:
นอกจากนี้ยังเป็นที่น่าสังเกตว่าเหตุการณ์ "คลิก" สำหรับองค์ประกอบ HTML ใด ๆ ที่สามารถเลือกได้บนแป้นพิมพ์เช่นinput
ไฟบนพื้นที่หรือป้อนเมื่อองค์ประกอบถูกเลือก
Javascript มีแนวโน้มที่จะผสมผสานทุกอย่างเข้ากับวัตถุและอาจทำให้สับสน ทั้งหมดเป็นหนึ่งเป็นวิธี JavaScript
ที่สำคัญ onclick เป็นคุณลักษณะ HTML addEventListener ในทางกลับกันเป็นวิธีการในวัตถุ DOM ที่แสดงองค์ประกอบ HTML
ในวัตถุ JavaScript วิธีการเป็นเพียงคุณสมบัติที่มีฟังก์ชั่นเป็นค่าและทำงานได้กับวัตถุที่แนบมากับ (ใช้ตัวอย่างนี้)
ใน JavaScript เป็นองค์ประกอบ HTML ที่แสดงโดย DOM จะมีการแมปแอตทริบิวต์ของคุณสมบัติของมัน
นี่คือที่ที่ผู้คนสับสนเพราะ JavaScript รวมทุกอย่างไว้ในคอนเทนเนอร์เดียวหรือเนมสเปซโดยไม่มีเลเยอร์ทางอ้อม
ในเลย์เอาต์ OO ปกติ (อย่างน้อยจะรวมเนมสเปซของคุณสมบัติ / วิธีการ) คุณอาจมีลักษณะดังนี้:
domElement.addEventListener // Object(Method)
domElement.attributes.onload // Object(Property(Object(Property(String))))
มีรูปแบบต่าง ๆ เช่นสามารถใช้ getter / setter สำหรับ onload หรือ HashMap สำหรับแอตทริบิวต์ แต่ท้ายที่สุดแล้วมันจะเป็นอย่างไร JavaScript กำจัดเลเยอร์ของการอ้อมโดยคาดหวังว่าจะได้รู้ว่าอะไรคือสิ่งเหนือสิ่งอื่นใด มันรวม domElement และคุณลักษณะเข้าด้วยกัน
การจำกัดความเข้ากันได้ของคุณควรเป็นวิธีปฏิบัติที่ดีที่สุดใช้ addEventListener ในขณะที่คำตอบอื่น ๆ พูดถึงความแตกต่างในเรื่องนั้นมากกว่าความแตกต่างทางโปรแกรมพื้นฐานฉันจะทิ้งมันไป โดยพื้นฐานแล้วในโลกอุดมคติคุณควรใช้กับ * จาก HTML เท่านั้น แต่ในโลกอุดมคติยิ่งกว่านั้นคุณไม่ควรทำสิ่งนั้นจาก HTML
ทำไมวันนี้ถึงเด่น การเขียนเรียนรู้ได้ง่ายกว่าและมีแนวโน้มที่จะทำงานได้เร็วขึ้น
จุดรวมของ onload ใน HTML คือการให้การเข้าถึงเมธอดหรือฟังก์ชั่น addEventListener ตั้งแต่แรก โดยใช้ใน JS คุณจะผ่าน HTML เมื่อคุณสามารถนำไปใช้โดยตรง
สมมุติฐานคุณสามารถสร้างคุณสมบัติของคุณเอง:
$('[myclick]').each(function(i, v) {
v.addEventListener('click', function() {
eval(v.myclick); // eval($(v).attr('myclick'));
});
});
สิ่งที่ JS ทำด้วยนั้นแตกต่างจากนี้เล็กน้อย
คุณสามารถแบ่งให้เท่ากัน (สำหรับทุกองค์ประกอบที่สร้าง):
element.addEventListener('click', function() {
switch(typeof element.onclick) {
case 'string':eval(element.onclick);break;
case 'function':element.onclick();break;
}
});
รายละเอียดการใช้งานจริงอาจแตกต่างกันไปตามช่วงของการเปลี่ยนแปลงเล็กน้อยทำให้ทั้งสองแตกต่างกันเล็กน้อยในบางกรณี แต่นั่นเป็นส่วนสำคัญของมัน
มันเป็นเนื้อหาที่เข้ากันได้กับแฮ็คที่คุณสามารถปักหมุดฟังก์ชั่นให้กับแอตทริบิวต์เนื่องจากโดยค่าเริ่มต้นคือสตริงทั้งหมด
ตามMDNความแตกต่างดังต่อไปนี้:
addEventListener:
กระบวนการ EventTarget.addEventListener () วิธีการเพิ่มวัตถุที่เข้ากันได้ EventListener ระบุในรายการของฟังเหตุการณ์สำหรับประเภทเหตุการณ์ที่ระบุใน EventTarget ที่มันเรียกว่า เป้าหมายเหตุการณ์อาจเป็นองค์ประกอบในเอกสารเอกสารตัวเองหน้าต่างหรือวัตถุอื่น ๆ ที่สนับสนุนกิจกรรม (เช่น XMLHttpRequest)
เมื่อคลิก:
คุณสมบัติ onclick ส่งคืนรหัสตัวจัดการเหตุการณ์การคลิกในองค์ประกอบปัจจุบัน เมื่อใช้เหตุการณ์คลิกเพื่อกระตุ้นการดำเนินการให้พิจารณาเพิ่มการกระทำเดียวกันนี้ในเหตุการณ์การเลื่อนลงเพื่ออนุญาตให้ใช้การกระทำเดียวกันนั้นโดยผู้ที่ไม่ใช้เมาส์หรือหน้าจอสัมผัส องค์ประกอบไวยากรณ์ .click = functionRef; โดยที่ functionRef เป็นฟังก์ชั่น - มักจะเป็นชื่อของฟังก์ชั่นที่ประกาศไว้ที่อื่นหรือการแสดงออกของฟังก์ชั่น ดู "คู่มือ JavaScript: ฟังก์ชั่น" สำหรับรายละเอียด
นอกจากนี้ยังมีความแตกต่างของไวยากรณ์ในการใช้งานตามที่คุณเห็นในรหัสด้านล่าง:
addEventListener:
// Function to change the content of t2
function modifyText() {
var t2 = document.getElementById("t2");
if (t2.firstChild.nodeValue == "three") {
t2.firstChild.nodeValue = "two";
} else {
t2.firstChild.nodeValue = "three";
}
}
// add event listener to table
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);
เมื่อคลิก:
function initElement() {
var p = document.getElementById("foo");
// NOTE: showAlert(); or showAlert(param); will NOT work here.
// Must be a reference to a function name, not a function call.
p.onclick = showAlert;
};
function showAlert(event) {
alert("onclick Event detected!");
}
หากคุณไม่กังวลเกี่ยวกับการสนับสนุนเบราว์เซอร์มีวิธีการอ้างอิงการอ้างอิง 'this' ในฟังก์ชันที่เรียกใช้โดยเหตุการณ์ โดยปกติแล้วมันจะชี้ไปที่องค์ประกอบที่สร้างเหตุการณ์เมื่อมีการใช้งานฟังก์ชันซึ่งไม่ได้เป็นอย่างที่คุณต้องการ ส่วนที่ยุ่งยากก็คือในเวลาเดียวกันสามารถที่จะลบ listener เหตุการณ์เดียวกันได้มากดังที่แสดงในตัวอย่างนี้: http://jsfiddle.net/roenbaeck/vBYu3/
/*
Testing that the function returned from bind is rereferenceable,
such that it can be added and removed as an event listener.
*/
function MyImportantCalloutToYou(message, otherMessage) {
// the following is necessary as calling bind again does
// not return the same function, so instead we replace the
// original function with the one bound to this instance
this.swap = this.swap.bind(this);
this.element = document.createElement('div');
this.element.addEventListener('click', this.swap, false);
document.body.appendChild(this.element);
}
MyImportantCalloutToYou.prototype = {
element: null,
swap: function() {
// now this function can be properly removed
this.element.removeEventListener('click', this.swap, false);
}
}
รหัสข้างต้นทำงานได้ดีใน Chrome และอาจมีบางอย่างที่ทำให้การ "ผูก" เข้ากันได้กับเบราว์เซอร์อื่น
การใช้ตัวจัดการอินไลน์เข้ากันไม่ได้กับนโยบายความปลอดภัยของเนื้อหาดังนั้นaddEventListener
วิธีการจึงปลอดภัยกว่าจากมุมมองนั้น แน่นอนว่าคุณสามารถเปิดใช้งานตัวจัดการแบบอินไลน์ด้วยunsafe-inline
แต่ตามชื่อที่แนะนำมันไม่ปลอดภัยเนื่องจากจะทำให้จาวาสคริปทั้งหมดของจาวาสคริปต์โจมตีที่ CSP ป้องกัน
มันควรจะเป็นไปได้ที่จะขยายการฟังโดยสร้างต้นแบบ (ถ้าเรามีการอ้างอิงถึงมันและไม่ใช่ฟังก์ชันที่ไม่ระบุชื่อ) - หรือเรียก 'onclick' การเรียกไปยังไลบรารีฟังก์ชัน (ฟังก์ชันที่เรียกใช้ฟังก์ชันอื่น ๆ )
ชอบ
elm.onclick = myFunctionList
function myFunctionList(){
myFunc1();
myFunc2();
}
นี่หมายความว่าเราไม่ต้อง chenge การโทรแบบ onclick เพียงแค่เปลี่ยนฟังก์ชั่น myFunctionList () เพื่อทำสิ่งที่เราต้องการ แต่สิ่งนี้ทำให้เราไม่ต้องควบคุมเฟส / การจับฟองดังนั้นควรหลีกเลี่ยงเบราว์เซอร์ใหม่
ในกรณีที่มีคนค้นหากระทู้นี้ในอนาคต ...
element.onclick = function () {/ * do stuff * /}
element.addEventListener ('คลิก', ฟังก์ชัน () {/ * ทำสิ่ง * /}, เท็จ);
เห็นได้ชัดว่าพวกเขาทำสิ่งเดียวกัน: ฟังเหตุการณ์คลิกและเรียกใช้ฟังก์ชันการเรียกกลับ อย่างไรก็ตามมันไม่เทียบเท่ากัน หากคุณต้องการเลือกระหว่างสองสิ่งนี้จะช่วยให้คุณทราบว่าอันไหนดีที่สุดสำหรับคุณ
ความแตกต่างที่สำคัญคือonclick เป็นเพียงสถานที่ให้บริการและชอบคุณสมบัติของวัตถุทั้งหมดถ้าคุณเขียนในมากกว่าหนึ่งครั้งก็จะถูกเขียนทับ ด้วยaddEventListener ()แทนเราสามารถทำได้ง่ายๆผูกตัวจัดการเหตุการณ์กับองค์ประกอบและเราสามารถเรียกมันได้ทุกครั้งที่เราต้องการโดยไม่ต้องกังวลกับคุณสมบัติที่ถูกเขียนทับ ตัวอย่างแสดงที่นี่
ลองมัน: https://jsfiddle.net/fjets5z4/5/
ในตอนแรกฉันถูกล่อลวงให้ใช้ onclick ต่อไปเพราะมันสั้นกว่าและดูง่ายกว่า ... และในความเป็นจริง แต่ฉันไม่แนะนำให้ใช้อีกต่อไป มันเหมือนกับการใช้ JavaScript แบบอินไลน์ การใช้บางอย่างเช่น - นั่นคือ inline JavaScript - หมดกำลังใจอย่างมากในปัจจุบัน (CSS แบบอินไลน์ก็ไม่ได้รับการสนับสนุนเช่นกัน แต่เป็นหัวข้ออื่น)
อย่างไรก็ตามฟังก์ชั่น addEventListener () แม้จะเป็นมาตรฐาน แต่ก็ไม่สามารถใช้งานได้ในเบราว์เซอร์รุ่นเก่า (Internet Explorer ต่ำกว่ารุ่น 9) และนี่เป็นข้อแตกต่างที่สำคัญอีกประการหนึ่ง หากคุณต้องการสนับสนุนเบราว์เซอร์โบราณเหล่านี้คุณควรทำตามวิธีที่คลิก แต่คุณสามารถใช้ jQuery (หรือหนึ่งในทางเลือก): ช่วยให้งานของคุณง่ายขึ้นและลดความแตกต่างระหว่างเบราว์เซอร์ดังนั้นจึงช่วยให้คุณประหยัดเวลาได้มาก
var clickEvent = document.getElementByID("onclick-eg");
var EventListener = document.getElementByID("addEventListener-eg");
clickEvent.onclick = function(){
window.alert("1 is not called")
}
clickEvent.onclick = function(){
window.alert("2 is not called")
}
EventListener.addEventListener("click",function(){
window.alert("1 is called")
})
EventListener.addEventListener("click",function(){
window.alert("2 is also called")
})
addEventListener
ให้คุณตั้งค่าตัวจัดการหลายตัว แต่ไม่รองรับใน IE8 หรือต่ำกว่า
IE มีattachEvent
แต่ก็ไม่เหมือนกันทุกประการ
บริบทที่อ้างอิงโดย'this'
คำสำคัญใน JavasSript นั้นแตกต่างกัน
ดูรหัสต่อไปนี้:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<input id="btnSubmit" type="button" value="Submit" />
<script>
function disable() {
this.disabled = true;
}
var btnSubmit = document.getElementById('btnSubmit');
btnSubmit.onclick = disable();
//btnSubmit.addEventListener('click', disable, false);
</script>
</body>
</html>
มันง่ายอะไรจริงๆ เมื่อคุณคลิกปุ่มปุ่มจะถูกปิดใช้งานโดยอัตโนมัติ
ครั้งแรกเมื่อคุณพยายามเชื่อมต่อเหตุการณ์ด้วยวิธีนี้button.onclick = function(),
เหตุการณ์ onclick จะถูกเรียกใช้โดยการคลิกปุ่มอย่างไรก็ตามปุ่มจะไม่ถูกปิดใช้งานเนื่องจากไม่มีการเชื่อมโยงอย่างชัดเจนระหว่าง button.onclick และ onclick ตัวจัดการเหตุการณ์ หากคุณดีบักเห็น'this'
วัตถุคุณสามารถเห็นมันอ้างถึง'window'
วัตถุ
ประการที่สองหากคุณแสดงความคิดเห็นbtnSubmit.onclick = disable();
และไม่
แสดงความคิดเห็น//btnSubmit.addEventListener('click', disable, false);
คุณจะเห็นว่าปุ่มถูกปิดใช้งานเพราะด้วยวิธีนี้จะมีการเชื่อมโยงอย่างชัดเจนระหว่างเหตุการณ์ button.onclick และตัวจัดการเหตุการณ์ onclick หากคุณแก้ปัญหาในฟังก์ชั่นปิดการใช้งานคุณสามารถดู'this'
อ้างอิงถึงbutton control
มากกว่าwindow
มากกว่า
นี่คือสิ่งที่ฉันไม่ชอบเกี่ยวกับ JavaScript ซึ่งไม่สอดคล้องกัน Btw หากคุณใช้ jQuery ( $('#btnSubmit').on('click', disable);
) จะใช้การรวมที่ชัดเจน
btnSubmit.onclick = disable;
(กำหนดฟังก์ชั่นไม่ใช่เรียกมัน) จากนั้นในทั้งสองกรณีthis
จะอ้างถึงองค์ประกอบปุ่ม
onclick นั้นเป็น addEventListener ที่ทำหน้าที่เป็นพิเศษเมื่อองค์ประกอบถูกคลิก ดังนั้นมีประโยชน์เมื่อคุณมีปุ่มที่ใช้งานง่ายเช่นปุ่มเครื่องคิดเลข addEventlistener สามารถใช้สำหรับสิ่งต่างๆมากมายเช่นการดำเนินการเมื่อ DOM หรือเนื้อหาทั้งหมดถูกโหลดคล้ายกับ window.onload แต่มีการควบคุมมากขึ้น
หมายเหตุคุณสามารถใช้มากกว่าหนึ่งเหตุการณ์กับอินไลน์หรืออย่างน้อยโดยใช้ onclick โดยแยกแต่ละฟังก์ชันด้วยเซมิโคลอนเช่นนี้ ....
ฉันจะไม่เขียนฟังก์ชันแบบอินไลน์เนื่องจากคุณอาจมีปัญหาในภายหลังและมันจะยุ่งเหยิง imo เพียงใช้เพื่อเรียกฟังก์ชั่นที่ทำไว้แล้วในไฟล์สคริปต์ของคุณ
คุณใช้อันไหนฉันคิดว่าจะขึ้นอยู่กับสิ่งที่คุณต้องการ addEventListener สำหรับการดำเนินงานที่ซับซ้อนและ onclick ง่าย ฉันเคยเห็นบางโครงการไม่ได้แนบองค์ประกอบเฉพาะกับองค์ประกอบและจะใช้ตัวจัดกิจกรรมระดับโลกที่จะตรวจสอบว่ามีการแตะที่ปุ่มและทำงานบางอย่างขึ้นอยู่กับสิ่งที่กด Imo ที่อาจนำไปสู่ปัญหาที่ฉันคิดและแม้ว่าจะมีขนาดเล็กน่าจะเป็นทรัพยากรที่สูญเปล่าหากผู้จัดกิจกรรมที่ต้องจัดการกับการคลิกแต่ละครั้ง
function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }