أثناء عملية التطوير الأمامية ، نواجه في كثير من الأحيان مشكلة إضافة الأحداث إلى عناصر الصفحات. هناك أيضًا العديد من أساليب JS لإضافة الأحداث ، بما في ذلك إضافة مباشرة إلى بنية الصفحة ، وبعض طرق مراقبة الأحداث JS. نظرًا لأن كل متصفح لديه آليات مختلفة لمراقبة أحداث فقاعة الأحداث ، فإن Browser فقط لديه فقاعات أحداث فقط ولا توجد آلية لمراقبة الأحداث ، وقضية التوافق في الاستماع إلى الأحداث هي أكبر مشكلة:
1. اكتب طريقة الحدث مباشرة على بنية الصفحة
وظيفة eventFun () {//console.log(this) ؛ } <input type = "button" onClick = "eventFun ()" value = "button"/> // هذا يتضمن مشكلة في هذا النطاق. EventFun هي أيضا وظيفة عالمية هنا. الكائن هو [نافذة الكائن] ، وهذا يشير إلى النافذة.لحل مشكلة النطاق هذه ، يمكنك استخدام طريقة إضافة متغيرات الحدث إلى الوظيفة العالمية ، وتمرير هذا الكائن كمعلمة إلى الوظيفة داخل بنية الصفحة
<type type = "button" onClick = "eventFun2 (this)" value = "button2"/> function eventFun2 (eve) {// هنا يتم تمرير كائن الحدث كمعلمة إلى الطريقة العالمية eve.name = "allex" ؛ window.name = "Robin" ؛ console.log (this) ؛ // [womk window] console.log (eve) ؛ // [object htmlinputelement] console.log (this.name) ؛ // robin console.log (eve.name) ؛ // Alexvar self = eve ؛ console.log (this.name) ؛ // robin console.log (self.name) ؛ // Alex Alert (window.name) ؛ تنبيه (self.name) ؛ }2. استخدام طريقة تعيين القيمة لسمات الحدث هو وسيلة للربط بالأحداث ، ولكن الحد من هذه الطريقة هو أنه يمكن فقط ربط طريقة واحدة للأحداث. إذا كانت الارتباطات المتعددة مرتبطة ، فسوف تسود طريقة واحدة.
htmlelementobject.onclick = fucntion () {// استخدم هذه الطريقة لتعيين قيمة لسمات الحدث ، سيشير هذا المؤشر إلى كائن النافذة ، وليس كائن الحدث ، لذلك هذه الطريقة هي مرجع
// JS Code fun1 () ؛ fun2 () ؛ fun3 () ؛ console.log (this) ؛ // window.object} function dosomething () {// js code} htmlelementobject.onclick = dosomething ؛ // استخدم هذا النموذج من قيمة تعيين سمات كائن الحدث ، ويشير المؤشر هذا إلى وحدة تنفيذ الحدث.3. انتشار الحدث - الفقاعة والتقاط
يحدد معيار حدث DOM تيارين للأحداث ، وهما مختلفان بشكل كبير وقد يكون له تأثير كبير على التطبيق الخاص بك. هذين تيارات الحدث هما الالتقاط والفقاعة. مثل العديد من تقنيات الويب ، قامت Netscape و Microsoft بتنفيذها بشكل مختلف قبل أن تصبح قياسية. اختارت Netscape تنفيذ تدفقات الأحداث التقاط ، بينما قامت Microsoft بتطبيق تدفقات أحداث الفقاعات. لحسن الحظ ، قررت W3C استخدام كلتا الطريقتين مجتمعة ، ومعظم المتصفحات الجديدة تتبع هاتين طريقتين لتدفق الحدث.
بشكل افتراضي ، تستخدم الأحداث تدفقات أحداث الفقاعات ، ولا يتم استخدام أي تدفقات أحداث التقاط. ومع ذلك ، في Firefox و Safari ، يمكنك تحديد بشكل صريح استخدام تدفقات الأحداث التقاط عن طريق تمرير معلمة useCapture عند تسجيل الحدث وتحديد هذه المعلمة إلى True.
دفق حدث فقاعة
عندما يتم تشغيل حدث ما على عنصر DOM ، على سبيل المثال ، ينقر المستخدم على الماوس على عقدة اسم العميل ، سيتبع الحدث مختلف أسماء الأصل الموروثة التي تمر بها العقدة عبر التسلسل الهرمي لعقدة DOM بأكمله حتى تواجه عقدة يتم إرفاقها بمعالج نوع الحدث. في هذا الوقت ، الحدث هو حدث Onclick. يمكن إنهاء الفقاعات من الأحداث في أي وقت أثناء عملية الفقاعات. في المتصفحات التي تتوافق مع معايير W3C ، يمكنك استدعاء طريقة StopPropagation () على كائن الحدث ، وفي Internet Explorer ، يمكنك تعيين سمة CancelBubble لكائن الحدث إلى True. إذا لم يتم إيقاف الحدث ، فسيتم فقاعة الحدث عبر DOM حتى يصل إلى جذر المستند.
التقاط تدفق الحدث
تبدأ معالجة الحدث من جذر مستوى DOM ، بدلاً من العنصر المستهدف الذي يؤدي إلى حدوث الحدث ، ويتم تمرير الحدث بالتسلسل من جميع عناصر الأجداد للعنصر المستهدف. في هذه العملية ، يتم التقاط الأحداث من خلال العديد من العناصر المشتقة الموروثة من جذر المستند إلى عنصر هدف الحدث. إذا قام مستمع الحدث بتعيين سمة usecapture إلى True عند التسجيل ، فيمكن تعيينها إلى أي عنصر خلال هذه الفترة للتعامل مع الحدث ؛ خلاف ذلك ، سيتم تمرير الأحداث لاحقًا إلى العنصر التالي على مسار العنصر المشتق حتى العنصر المستهدف. بعد أن يصل الحدث إلى العنصر المستهدف ، سيتم بعد ذلك فقاعة من خلال عقدة DOM.
طريقة ربط الأحداث الحديثة
بالنسبة للدرس السابق ، فإن استخدام ربط الحدث التقليدي له العديد من العيوب ، مثل عدم القدرة على تسجيل معالجات الأحداث المتعددة في نفس الحدث للكائن. والمتصفحات و W3C لا تخلو من التفكير في ذلك ، لذلك في المتصفحات الحديثة ، لديهم أساليبهم الخاصة لربط الأحداث.
W3C DOM
OBJ.AdDeventListener (EVTYPE ، FN ، USECAPTURE) - يوفر W3C طريقة لإضافة وظائف معالجة الأحداث. OBJ هو الكائن لإضافة أحداث ، evtype هو نوع الحدث ، بدون بادئة ، FN هو وظيفة معالج الأحداث ، إذا كانت useCapture صحيحة ، يتم تنفيذ وظيفة معالج الأحداث في مرحلة الالتقاط ، وإلا يتم تنفيذه في مرحلة الفقاعة
OBJ.RemoveVentListener (EVTYPE ، FN ، USECAPTURE)-يوفر W3C طريقة لحذف وظائف معالجة الأحداث
Microsoft IE طريقة
OBJ.attachevent (Evtype ، FN) - الطريقة التي توفرها IE لإضافة وظائف معالجة الأحداث. OBJ هو الكائن لإضافة الأحداث ، Evtype هو نوع الحدث ، مع On Prefix ، FN هي وظيفة معالج الأحداث ، أي لا تدعم التقاط الحدث
Obj.Detachevent (Evtype ، Fn ،) - IE يوفر طريقة لحذف وظيفة معالجة الأحداث ، يحتوي Evtype على البادئة
طريقة لدمج كليهما
وظيفة addEvent (obj ، evtype ، fn ، usecapture) {if (obj.addeventListener) {obj.addeventListener (evtype ، fn ، usecapture) ؛ } آخر {obj.attachevent ("on"+evtype ، fn) ؛ // ie لا يدعم التقاط الحدث} آخر {obj ["on"+evtype] = fn ؛ // في الواقع ، لن يكون هذا الموقف}} delevent (obj ، evtype ، fn ، usecapture) OBJ.RemoveEventListener (Evtype ، FN ، Usecapture) ؛ } آخر {obj.detachevent ("on"+evtype ، fn) ؛ } آخر {obj ["on"+evtype] = null ؛ }}هناك مشكلة في طريقة إرفاق IE ، وهي أنه عند استخدام الملحق ، هذا يشير إلى النافذة ، وليس OBJ! بالطبع ، هناك حل لهذا!
ولكن هناك مشكلة أخرى مع طريقة ملحق IE. يمكن تسجيل نفس الوظيفة مع نفس الكائن ونفس الحدث عدة مرات. الحل: التخلي عن طريقة ملحق IE! لا تدعم طريقة المرفقات تحت IE التقاط ، والتي لا تختلف كثيرًا عن تسجيل الأحداث التقليدية (باستثناء ربط معالجات الأحداث المتعددة) ، وطريقة ملحق IE لديها مشكلة تسرب الذاكرة!
addevent ، نسخة ديليفينت الحديثة
<! doctype html public "-// w3c // dtd xhtml 1.0 transitional // en" xmlns = "http://www.w3.org/1999/xhtml"> <head> <meta http-equiv = "content-type" content = "text/html ؛ charset = utf-8"/> <title> js الاستماع </title> <style> td {fort: 12px ؛ border-bottom: 1px solid #efefefef ؛} < /style> < /head> <body> <div id = "outele" style = "padding: 10px ؛ border: 1px solid #b2b2b2 ؛ background: #efefefef ؛ onClick = "eventFun2 (this) ؛" id = "button2" value = "button2" /> <br /> <input type = "button" id = "button3" value = "button3" /> <br /> <input type = "button" id = "button4" value = "button4" /> <br /> <table id = "htmdeletable" style = 1px sold #b2b2 ؛ id = "1111"> <td> 111111111111111111111111111111111111 </td> <tr> <tr id = "22222" ID = "3333333333333333333333333333333333333 </td> </tr> <tr id = "44444"> <td> 44444444444444444444444444444444444444444444444444444444444444444444444444444444444444 444444444444444444444444444444444444444444444444444444441 </TR> <tr id = "55555555555555555555555555 </td> </tr> </table> </viv> <script language =" javaScript "type =" text/javaScript "> eventFun () {// 1. اكتب مباشرة طريقة JS على وحدة Console.log (هذا) ؛ // وهذا ينطوي على مشكلة في هذا النطاق. EventFun هي وظيفة عالمية ، والكائن هو نافذة ، وهذا يشير إلى تنبيه النوافذ (هذا) ؛ } وظيفة eventFun2 (EVE) {// هنا تمرر كائن الحدث كمعلمة إلى الطريقة العالمية eve.name = "alex" ؛ // window.name = "Robin" ؛ console.log (this) ؛ // [WORPOR WINDOW] Console.log (eve) ؛ // [Object htmlinputelement] console.log (this.name) ؛ // robin console.log (eve.name) ؛ // Alex var self = eve ؛ console.log (this.name) ؛ // robin console.log (self.name) ؛ // Alex Alert (window.name) ؛ تنبيه (self.name) ؛ } وظيفة eventFun3 () {// 1. اكتب مباشرة طريقة JS على وحدة Console.log (هذا) ؛ // وهذا ينطوي على مشكلة في هذا النطاق. EventFun هي وظيفة عالمية ، والكائن هو نافذة ، وهذا يشير إلى window console.log (this.id) ؛ تنبيه (هذا) ؛ تنبيه (هذا) ؛ تنبيه (this.id) ؛ // var outeleobj = eventUtil. $ ("Outele") ؛ // removeEvent (OuteleObj ، "Click" ، eventFun3) ؛ } /* var eventUtil = {} ؛ EventUtil. $ = function (id) {return document.getElementById (id) ؛ } eventUtil.openmes = eventFun3 ؛ EventUtil.AdDeventHandle = function (EventTarget ، EventType ، EventHandle) {// تحديد عنصر الكائن ، نوع الحدث للاستماع إلى الحدث ، وظيفة الحدث if (EventTarget.attachevent) {eventTarget.attachevent ("On" On "eventType ، eventHandle) ؛ } if if (eventTarget.AdDeventListener) {eventTarget.AdDeventListener (EventType ، EventHandle ، false)} آخر {eventTarget ["on" + eventType] = null ؛ }} ؛ EventUtil.deleeventHandle = function (EventTarget ، EventType ، EventHandle) {// تحديد عنصر الكائن ، نوع الحدث للاستماع إلى الحدث ، وظيفة الحدث if (EventTarget.detachevent) {Alert ("on"+eventType) ؛ تنبيه ("ON"+EventHandle) ؛ EventTarget.detachevent ("ON"+EventType ، EventHandle) ؛ } آخر إذا (EventTarget.RemoveEventListener) {eventTarget.RemoveEventListener (EventType ، EventHandle ، false)} آخر {eventTarget ["ON" + eventType] = null ؛ }} ؛*/ var eventUtil = {$: function (id) {return document.getElementById (id) ؛ } ، but4fun: function () {console.log (this) ؛ this.addeventHandle () ؛ } ، eventFun3: function () {console.log (this) ؛ تنبيه (هذا) ؛ DELEVENT (OBJ ، EVTYPE ، FN ، USECAPTURE) ؛ }} /*** استخدم addeventListener ، excloyevent لوظيفة الاستماع addEvent (obj ، evtype ، fn ، usecapture) {if (obj.addeventListener) {obj.addeventListener (evtype ، fn ، usecapture) ؛ } آخر إذا (obj.attachevent) {obj.attachevent ("on"+evtype ، function () {fn.call (obj) ؛}) ؛ } else {obj ["on"+evtype] = fn ؛ // في الواقع ، لن يكون هذا الموقف موجودًا}} delevent (obj ، evtype ، fn ، usecapture) {if (obj.removeVentListener) } آخر إذا (obj.detachevent) {obj.detachevent ("on"+evtype ، fn) ؛ } آخر {obj ["on"+evtype] = null ؛ }} الوظيفة addEvent (OBJ ، EVTYPE ، FN ، USECAPTURE) {if (obj.addeventListener) {// يتم إعطاء الأولوية لمخطط تسجيل الأحداث W3C OBJ.AdDeventListener (EVTYPE ، FN ، !! usecapture) ؛ } آخر {// عندما لا يتم دعم AddEventListener (أي) ، نظرًا لأن IE لا يدعم الالتقاط في نفس الوقت ، فمن الأفضل استخدام ربط الحدث التقليدي إذا (! // _ يتم استخدام سمة EventHandles لحفظ المراجع لجميع معالجات الأحداث // المصنفة حسب نوع الحدث if (! OBJ .__ eventHandles [evType]) {// في المرة الأولى التي يتم فيها تسجيل حدث OBJ .__ eventHandles [evType] = {} ؛ إذا تم تسجيل (obj ["on"+evtype]) {// تم تسجيل وظيفة معالجة الأحداث بالطريقة التقليدية قبل (OBJ .__ eventHandles [evType] [0] = obj ["On"+Evtype]) .__ eventid = 0 ؛ OBJ ["on"+evtype] = addevent.execeventHandles ؛ // عندما يحدث حدث ما ، يعبر ExeceventHandles الجدول OBJ .__ EventHandles [Evtype] وتنفيذ الوظيفة فيه}}} addevent .__ eventHandlesCounter = 1 ؛ صحيح ؛} evt = evt || window.event ؛ var fns = this .__ eventHandles [evt.type] ؛ لـ (var i in fns) {fns [i] .call (this) ؛ }} ؛ /* وظيفة delevent (obj ، evtype ، fn ، usecapture) {if (obj.removeVentListener) {// أولاً استخدم طريقة W3C لإزالة وظيفة معالج الأحداث obj.removeVentListener (evtype ، fn ، !! } آخر {if (obj .__ eventHandles) {var fns = obj .__ eventHandles [evtype] ؛ if (fns) {delete fns [fn .__ eventId] ؛}}}}} FixEvent (evt) {// لم يتم تنفيذ وظيفة fixevent بشكل منفصل. يجب أن يكون لها معلمة كائن الحدث ، وسيتم تنفيذها فقط عندما يحدث الحدث! أفضل طريقة هي دمجها في execeventhandles من وظيفة addevent if (! evt.target) {evt.target = evt.srclement ؛ evt.preventDefault = fixevent.preventDefault ؛ evt.StopPropagation = fixEvent.StopPropagation ؛ if (evt.type == "mouseover") {evt.RELEDTARGET = evt.fromelement ؛ } آخر إذا (evt.type == "mouseout") {evt.releledTarget = evt.ToElement ؛ } evt.charcode = (evt.type == "keypress")؟ evt.keycode: 0 ؛ evt.EventPhase = 2 ؛ // ie يعمل فقط في مرحلة الفقاعة evt.timestamp = (تاريخ جديد ()). } fixevent.preventDefault = function () {this.returnvalue = false ؛ // هذا يشير هنا إلى كائن حدث معين ، وليس fixevent} ؛ fixEvent.StopPropagation = function () {this.cancelBubble = true ؛ } ؛*///console.log(eventutil.$("button3")) ؛//return سمة الكائن لوظيفة EventUtil //eventutil.$("button3").onclick= eventfun ؛ // 2. استخدم طريقة تعيين القيم إلى سمة حدث الكائن لتحقيق الاستماع للأحداث //eventutil.$("button3").onclick= eventfun2 ؛ // عند إضافة طرق متعددة إلى سمة الحدث ، يكون الأخير هو // = function () {function getById (id) {return document.getElementById (id) ؛ } ؛ // كتبها دين إدواردز ، 2005 // مع مدخلات من Tino Zijdel ، Matthias Miller ، Diego Perini // http://dean.edwards.name/weblog/2005/10/add-event/ function addevent (element ، type ، handler) {if (element.adeventlistener) } آخر {// تعيين كل معالج حدث معرف فريد إذا (! معالج. $$ guid) معالج. $$ guid = addevent.guid ++ ؛ // إنشاء جدول التجزئة لأنواع الأحداث للعنصر if (! element.events) element.events = {} ؛ // إنشاء جدول تجزئة من معالجات الأحداث لكل زوج عنصري/زوج معالجات var = element.events [type] ؛ if (! معالجات) {معالجات = element.events [type] = {} ؛ // قم بتخزين معالج الأحداث الحالي (إذا كان هناك واحد) إذا (element ["on" + type]) {معالجات [0] = element ["on" + type] ؛ }} // قم بتخزين معالج الأحداث في معالجات جدول التجزئة [Handler. $$ guid] = Handler ؛ // تعيين معالج حدث عالمي للقيام بكل عنصر العمل ["ON" + type] = HandleVent ؛ }} ؛ // عداد يستخدم لإنشاء addevent.guid = 1 ؛ وظيفة إزالة (عنصر ، نوع ، معالج) {if (element.removeeventListener) {element.removeeventListener (type ، handler ، false) ؛ } آخر {// حذف معالج الحدث من جدول التجزئة if (element.events && element.events [type]) {delete element.events [type] [handler. $$ guid] ؛ }}} ؛ دالة مقبض (حدث) {var returnValue = true ؛ // الاستيلاء على كائن الحدث (أي يستخدم كائن حدث عالمي) حدث = حدث || FixEvent (((this.OwnerDocument || this.document || this) .ParentWindow || window) .event) ؛ // احصل على إشارة إلى جدول تجزئة معالجات الأحداث var = this.events [event.type] ؛ // تنفيذ كل معالج أحداث لـ (var i in Handlers) {this. $$ handlevent = معالجات [i] ؛ if (this. $$ handlevent (event) === false) {returnValue = false ؛ }} returnvalue ؛ } ؛ وظيفة FixEvent (الحدث) {// إضافة أساليب الحدث القياسية W3C Event.PreventDefault = FixEvent.preventDefault ؛ event.stopPropagation = fixevent.stoppropagation ؛ حدث العودة ؛ } ؛ fixevent.preventDefault = function () {this.returnvalue = false ؛ } ؛ fixEvent.StopPropagation = function () {this.cancelBubble = true ؛ } ؛ وظيفة tableDevent () {} ؛ إرجاع {add: addevent ، إزالة: removeEvent ، $: getByid}}} () ؛ var outeleObj = eventUtil. $ ("outele") ؛ . //eventutil.add(OuteleObj ،"click"-eventfun3) ؛ var inpectObj = eventUtil. $ ("button4") ؛ var tablelee = eventUtil. $ ("htmleletable") ؛ var tabtrele = tableleele.getElementsByTagName ("tr") ؛ EventUtil.add (Tablelele ، "Click" ، eventFun3) ؛ لـ (i = 0 ؛ i <tabtrele.length ؛ i ++) {eventutil.add (tabtrele [i] ، "click" ، eventFun3) ؛ } eventutil.remove (Tablelele ، "Click" ، eventFun3) ؛ // method method event eventutil.add (tablele ، "click" ، eventfun3) ؛ // eventutil.add (inputObj ، "Click" ، eventFun3) ؛ //eventutil.remove(OuteleObj ،"click"-eventfun3) ؛ //console.log(addevent) ؛ // addevent (inputObj ، "Click" ، eventFun3 ، true) ؛ // Delevent (OuteleObj ، "Click" ، eventFun3 ، false) ؛ </script> </body> </html>ملاحظة: نحن هنا نوفر لك أداة عبر الإنترنت حول أحداث JS ، والتي تلخص أنواع الأحداث الشائعة الاستخدام ووظائف JS:
قائمة كاملة من أحداث ووظائف JavaScript:
http://tools.vevb.com/table/javaScript_event