تفويض الاحداث Event delegation


السلام عليكم و رحمه الله تعالى و بركاته

تفويض الاحداث هو تكنيك يستخدم لنزع المستمع إلى الحدث Event listener من عنصر ما و إعطائه إلى عنصر اخر يحتويه فى شجره ال DOM ، انظر الى المثال البسيط التالى الذى لا يحتوى على تفويض للحدث

<ul>
<li id="g" onclick="doSomething()" >Google</li>
<li id="y" onclick="doSomething()">YahOO!</li>
<li id="a" onclick="doSomething()">Amazon</li>
<li id="m" onclick="doSomething()">Micrsosoft</li>
</ul>

جميه العناصر من نوع li تحتوى على مستمع للحدث click ، سواء قمت بتسجيل الحدث inline من داخل كود HTML او قمت بتجسيله عن طريق جافاسكربت ، فإن عاده تسجيل مستمع حدث لكل عنصر اعتبرها عاده سيئه و تؤثر على كفائه و اداء التطبيق و يجب تجنبها ، الأفضل من ذلك كله فى استخدام تكنيك تفويض الاحداث عن طريق تسجيل مستمع حدث لعنصر الذى يحتوى هذه العناصر و فى المثال الاعلى فإن تسجيل الحدث للعنصر ul الخيار المناسب ، كما يوضح الكود التالى :

<ul onclick="doSomething()">
<li id="g" >Google</li>
<li id="y" >YahOO!</li>
<li id="a" >Amazon</li>
<li id="m" >Micrsosoft</li>
</ul>

عندما يتم الضغط على Google او YahOO او اى عنصر اخر ، فإن الحدث سيصعد شجره ال DOM عن طريق Event Propagation و يبحث عن اى مستمع للحدث حتى يتم تنفيذه ، فى المثال الاعلى سيتم تنفيذ الداله doSomething و بذلك قمنا بمحو اربع مستعمات للحدث –  فى بعض التطبيقات الكبيره ربما تمحر الف مستمع من يدرى – ، اما عن الكود الذى داخل doSomething انظر للمثال البسيط التالى سأشرحه بالتفصيل :

function doSomething(event){
    var event = event || window.event;
    var elem = event.target || event.srcElement;
    var elemID = elem.id;
    switch(elemID){
        case "g":
            // do something for Google
        case "y":
            // do something for YahOO!
        case "a":
            // do something for Amazon
        case "m":
            // do something for Microsoft 
     }
}

الوظيفه doSomwthing تقبل الكائن event كما تنص توصيات W3C الذى يحتوى على معلومات عن الحدث الذى وقع ، لكن انترنت اكسبلورر المتصفح الوحيد الذى يقوم بإنشاء كائن event يحتوى على معلومات عن الحدث فى ال global object و لذلك لزم اضافه هذه السطر للحصول على مرجع للكائن event الصحيح :

var event = event || window.event;

توصيات W3C تنص على ان العنصر الذى وقع خلاله الحدث متاح فى event.target اما انترنت اكسبلورر من خلال event.srcElement لذلك لزم اضافه هذا السطر :

var elem = event.target || event.srcElement;

اخيرا احصل على id العنصر الذى وقع عنده الحدث لأنه يميز كل عنصر عن الاخر unique :

var elemID = elem.id;

ثم اقوم بفحص قيمه ال id من خلال switch و عمل مايلزم على اساس كل id .

فى المثال السابق تكنيك تفويض الاحداث اقتصر على القائمه ul ، لكن ماذا عن التطبيق كله – الصفحه كلها – ؟ يمكنك محو جميع مستمعى الاحداث لعناصر التطبيق كله و تسجيل مستمع حدث واحد للوثيقه document ، و فلتره العناصر اما من خلال ال id او من خلال class على حسب المنطق logic الذى يعمل من خلاله تطبيقك ، و بذلك كفائه و اداء التطبيق سيقفز قفزه كبيره جدا ، اتذكر محاضره سمعتها من سلسله Yahoo developer theater مبرمج يتحدث على ان التطبيق يحتوى على مستمعين اثنين للحدث واحد لل click و الاخر لل mousemove و بذلك تمكنوا من زياده الاداءه و تقليل الكود :

document.onclick = clickHandler;
document.onmousemove = moveHandler;

طبعا clickHandler و moveHandler يحتويان على كود يشابه الكود بداخل doSomething و لكن يختلف قليلا على حسب منطق التطبيق .

خارج النص : يمكنك الان عمل تطبيقات لموبايلات النوكيا التى تعمل على نظام تشغيل S60 بإستخدام HTML/CSS/JavaScript من خلال منصه WRT، و قدمت شركه Aptana اضافه لبرنامج ابتانا تساعدك فى ذلك ، فعلا جافاسكربت فى كل مكان .

الأوسمة: , ,

7 تعليقات to “تفويض الاحداث Event delegation”

  1. almhajer Says:

    صحيح كماذكرت اخي وحسب ماقاله مطوري ياهو وانا استخدمه لعمليات السحب
    حيث اني اضيف كود يقوم بسحب كل العناصر طبعا واذا دمج مع كيوري لعدة عناصر تقوم بسحبها تخيل كم يتم توفير كود وبخاصة الاكواد المكررة في المنصات السحب والالقاء والشفافية وغيرها
    بارك الله فيك ودمت سالما

  2. خالد Says:

    بارك الله فيك معلومة فعلاً قيمة، ولكن هل تستخدم مكاتب الجافا سكربت مثل هذه التقنية؟

  3. almhajer Says:

    برضو عندي سؤالين
    لماذ ايتم استخدام كالتالي ومافالفائدة منه
    e=!!s;

    push=[].push;
    وشكرا جزيلا

    • mostafa farghaly Says:

      @مهاجر:لا ادرى من اى جئت بهم يا مهاجر ، لكن مش مشكله
      !!S تحول ال S إلى boolean
      اما
      push= [].push
      فانها تنشأ مرجع للوظيفه
      push من وظائف ال Array

      @خالد : اول من ادرج تكنيك التفويض فى اطر العمل هو اطار بروتوتايب ثم اتبعه باقى المكاتب مثل جكويرى و غيره ، اقرأ توثيق دوال الاحداث لمزيد من المعلومات

  4. almhajer Says:

    شكرا اخ مصطفى انا جلبتهم من كود جاك كيوري
    الاولى استعوبتها ولكن الثانية حاولت اني استخدمها ولكن مانفعت ويياي
    ياريت اذا عندك اطلاع تدرجه بكود شاكرا لك حسن التعاون
    والله بيحفظك

    • mostafa farghaly Says:

      function User(name){
      this.name=name;
      }
      User.prototype = {
      push:[].push,
      }

      var me = new User(“mostafa”);
      me.push(“go”);
      me.push(“do”);
      me.push(“fo”)
      alert(me.length); //3
      alert(me[1]); //do
      alert(me[me.length]); // the lash added element “fo”

      لاحظ ان me لا يوجد بها الخاصيه length ، لكن بعد ان اضفت للبروتوتبيب push:[].push اصبح الان لديها الخاصيه length و this داخل push اصحبت تشير للكائن me ، خارج الموضوع : functionName.length يجلب لك عدد العبارت التى تمرر للوظيفه عند تعريف الوظيفه .
      User.length==1

  5. almahjer Says:

    يعطيك العافية وسلمت يمناك

أضف تعليقاً

إملأ الحقول أدناه بالمعلومات المناسبة أو إضغط على إحدى الأيقونات لتسجيل الدخول:

WordPress.com Logo

أنت تعلق بإستخدام حساب WordPress.com. تسجيل خروج   / تغيير )

صورة تويتر

أنت تعلق بإستخدام حساب Twitter. تسجيل خروج   / تغيير )

Facebook photo

أنت تعلق بإستخدام حساب Facebook. تسجيل خروج   / تغيير )

Google+ photo

أنت تعلق بإستخدام حساب Google+. تسجيل خروج   / تغيير )

Connecting to %s


%d مدونون معجبون بهذه: