بمجرد أن بدأت أداة معالجة الحدث

اختبار سريع: ما الغرض من المعلَمة الثالثة التي تم تمريرها إلى addEventListener()؟

لا داعي للحرج إذا كنت تعتقد أنّ السمة addEventListener() أخذت معلَمتين فقط، أو ربما تتضمّن ترميزًا ثابتًا دائمًا بقيمة false، مع فهم غامض بأنّ المشكلة تتعلّق بـ... الفقاعات؟

دالة addEventListener() الأكثر قابلية للضبط

لقد قطعت طريقة addEventListener() شوطًا طويلاً منذ الأيام الأولى للويب، ويتم ضبط وظائفها الجديدة من خلال إصدار عالي الإمكانيات من تلك المعلَمة الثالثة. تتيح التغييرات الأخيرة التي تم إجراؤها على تعريف الطريقة للمطوّرين تقديم خيارات إضافية من خلال كائن إعداد، مع الحفاظ على التوافق مع الأنظمة القديمة عند توفُّر معلَمة منطقية أو عند عدم تحديد خيار.

يسعدنا الإعلان عن أنّ الإصدار 55 من Chrome يضيف توافقًا للخيار once في كائن الضبط هذا، إلى جانب خيارات passive (يتم تنفيذها في Chrome 51) وخيارات capture (تم تنفيذها في الإصدار Chrome 49). مثال:

element.addEventListener('click', myClickHandler, {
    once: true,
    passive: true,
    capture: true
});

ويمكنك مزج هذه الخيارات ومطابقتها حسب الحاجة إلى حالة الاستخدام الخاصة بك.

فوائد التنظيف خلفك

هذه هي صيغة استخدام خيار once الجديد، لكن ما الذي سيعود عليك من ذلك؟ باختصار، فهي توفّر لك أداة معالجة حدث تم تصميمها خصيصًا لحالات الاستخدام "تم تنفيذها" و"تم تنفيذها".

تستمر أدوات معالجة الأحداث تلقائيًا بعد أول طلب استدعائها، وهو ما تريده لبعض أنواع الأحداث، أي أزرار يمكن النقر عليها عدة مرات، على سبيل المثال. وفي ما يتعلق بالاستخدامات الأخرى، ليس من الضروري الالتزام بفترة معالجة الحدث، ويمكن أن يؤدي ذلك إلى سلوك غير مرغوب فيه إذا كان لديك استدعاء يجب تنفيذه مرة واحدة فقط. لطالما كان لدى مطوّري البرامج الصحية خيار استخدام removeEventListener() لإزالة المحتوى بشكل واضح، وذلك باتّباع أنماط مثل:

element.addEventListener('click', function cb(event) {
    // ...one-time handling of the click event...
    event.currentTarget.removeEventListener(event.type, cb);
});

إنّ الرمز المكافئ، الذي يستخدم مَعلمة once الجديدة، أكثر وضوحًا ولا يفرض عليك تتبُّع اسم الحدث (event.type في المثال السابق) أو إشارة إلى دالة الاستدعاء (cb):

element.addEventListener('click', function(event) {
    // ...one-time handling of the click event...
}, {once: true});

يمكن أن يؤدي تنظيف معالِجات الأحداث أيضًا إلى زيادة كفاءات الذاكرة من خلال إتلاف النطاق المرتبط بوظيفة معاودة الاتصال، ما يسمح بجمع أي متغيرات تم تسجيلها في هذا النطاق بشكل غير صحيح. فيما يلي مثال على ذلك حيث سيحدث فرقًا:

function setUpListeners() {
    var data = ['one', 'two', '...etc.'];

    window.addEventListener('load', function() {
    doSomethingWithSomeData(data);
    // data is now part of the callback's scope.
    });
}

بشكلٍ تلقائي، سيظل استدعاء أداة معالجة الحدث load ضِمن النطاق عند انتهاء تشغيله، على الرغم من عدم استخدامه مجددًا. بما أنّه يتم استخدام المتغيّر data داخل معاودة الاتصال، سيظل ضمن النطاق ولن يتم جمع أي بيانات غير مرغوب فيها مطلقًا. إذا تمّت إزالة طلب الاستدعاء من خلال المَعلمة once، من المحتمل أن تكون الدالة نفسها وأي عنصر يتم حفظه على نطاقها مُرشَّحًا لجمع البيانات غير الضرورية.

المتصفحات المتوافقة

يتوفر في الإصدار 55 من Chrome وFirefox 50 والإصدارات الأحدث، ومعاينة التكنولوجيا 7 والإصدارات الأحدث في Safari دعمًا أصليًا لخيار once.

توفِّر العديد من مكتبات واجهة مستخدم JavaScript طرقًا سهلة لإنشاء مستمعي الأحداث، وبعضها يتضمّن اختصارات لتحديد الأحداث التي تتم لمرة واحدة، وأبرزها هو أسلوب one() في jQuery. يتوفّر أيضًا رمز polyfill كجزء من مكتبة أندريا جيامارتشي dom4.

شكرًا

نتوجّه بالشكر إلى Ingvar ستبانيان على ملاحظاتك حول نموذج الرمز البرمجي في هذه المشاركة.