لقد كانت الأحداث دائمًا واحدة من أقوى الكائنات في JavaScript. توفر JavaScript طريقتين، addEventListener و AttachEvent، لربط الأحداث بعقد DOM، كما يقوم jquery بتغليفها وتوفير طريقة ربط متوافقة مع المتصفحات المختلفة. الآن، هذه الطريقة التقليدية لربط الأحداث بها العيوب التالية:
1. قد تحتاج إلى ربط الكثير من EventHanders.
إذا كان هناك 100 صف في جدول بالصفحة، فيجب ربط حدث النقر بكل صف. ثم يجب ربط 100 EventHandlers، مما يضع عبئًا كبيرًا على أداء الصفحة لأنه يلزم إنشاء المزيد من الذاكرة لتخزين هذه المعالجات.
2. لا يمكن إضافة الحدث بعد الارتباط بعقدة DOM.
إذا كان الكود الموجود على الصفحة كما يلي:
انسخ رمز الكود كما يلي:
$("#dv").bind('click',function(){alert('test');});
$(body).append('<div id="dv">اختبار</div>')
لا يمكن لعنصر div المُضاف لاحقًا تشغيل أحداث النقر.
من أجل حل هاتين المشكلتين، قدمت جافا سكريبت وكيل الحدث (وكيل الحدث). أولاً، دعونا نفهم آلية الفقاعات في JS.
تدعم جميع المتصفحات بشكل أساسي فقاعات الأحداث. عند تشغيل حدث ما على عقدة DOM، سيتم نشر الحدث حتى العقدة الجذرية للمستند. نظرًا لأنه سيتم تسليم جميع أحداث العقدة في النهاية إلى العقدة الجذرية للمستند، إذا ربطنا الحدث مباشرة بالعقدة الجذرية للمستند (عقدة المستند)، ثم استخدمنا Event.target لتحديد العقدة التي تسببت في الحدث، فهل سيقلل ذلك كثيرًا معالجات الأحداث ماذا عن الربط؟
يتم تنفيذ الطريقة المباشرة في jquery رسميًا بناءً على هذا المبدأ، فلننفذ نسخة بسيطة من الطريقة المباشرة:
انسخ رمز الكود كما يلي:
$.fn.mylive=function(eventType,fn){
var that=this.selector;
$(المستند).bind(eventType,function(event){
فار ماتش=$(event.target).أقرب(ذلك)
إذا (تطابق. الطول!== 0){
fn.apply($(event.target),[event]);
}
})
}
$("#tb td").mylive('click',function(event){
تنبيه (event.target.innerHTML)؛
});
فار tb='<table id="tb"> /
<tr> /
<td>العمود الأول</td>/
<td>العمود الثاني</td>/
<td>العمود الثالث</td>/
</tr>/
</table>';
$("body").append(tb);
في الطريقة المباشرة، يرتبط الحدث بعقدة المستند، ويطابق $(event.target). Closest(that) العنصر الذي أدى إلى تشغيل الحدث بالفعل. في العرض التوضيحي، قمنا بربط حدث النقر لكل TD تمت إضافته لاحقًا. عندما ننقر على TDs مختلفة، نجد أن مربعات المطالبة النصية المقابلة لها ستظهر.
تعوض الطريقة المباشرة عيبي طريقة ربط الحدث التقليدية المذكورة سابقًا. لكن الطريقة الحية لا تزال تعاني من عيوبها. أنظر إلى هذا الكود:
انسخ رمز الكود كما يلي:
$("#tb td").mylive('click',function(event){
تنبيه (event.target.innerHTML)؛
});
سيقوم أولاً باجتياز المستند بأكمله بناءً على محدد jquery، والعثور على جميع عناصر #tb td، وتخزينها ككائنات. ومع ذلك، في طريقة التنفيذ المباشر، لا يتم استخدام هذه الكائنات، ولكن يتم استخدام "#td td" فقط كسلسلة لمطابقة مصدر الحدث. وهذا يزيد بشكل كبير من الاستهلاك غير الضروري.
فهل هناك أي طريقة لتحسين هذا الوضع؟ يتم توفير طريقة الوكيل المفوض في jQuery، الذي يدعم ربط الأحداث بعناصر محددة، وليس المستندات فقط. لنفهم مبدأه، فلننفذ نسخة بسيطة من المفوض:
انسخ رمز الكود كما يلي:
$(body).append('<div id="dv"></div>');
$.fn.mydelegate=function(selector,eventType,fn){
$(هذا).bind(eventType,function(event){
فار ماتش=$(event.target).أقرب(selector);
إذا (تطابق. الطول!== 0){
fn.apply($(event.target),[event]);
}
});
}
$("#dv").mydelegate('td','click',function(event){
تنبيه (event.target.innerHTML)؛
});
فار tb='<table id="tb"> /
<tr> /
<td>العمود الأول</td>/
<td>العمود الثاني</td>/
<td>العمود الثالث</td>/
</tr>/
</table>';
$("dv").append(tb);
لا يحتاج الأسلوب mydeletage إلى الحصول على كافة كائنات td، بل يحتاج فقط إلى كائنات div التي يرتبط بها الحدث. وهذا أفضل من الطريقة المباشرة من حيث كفاءة التنفيذ.
هذه مجرد مقدمة للسماح للجميع بفهم مبدأ وكيل الحدث. يعد تنفيذ البث المباشر والمفوض في jquery أكثر تعقيدًا.