كانت الإشارة إلى الأشياء على الويب أمرًا بسيطًا. كان لديك ماوس، وقمت بتحريكه وفي بعض الأحيان ضغطت على الأزرار، وهذا كل شيء. كل ما لم يكن الماوس كجهاز واحد، وكان المطورون يعرفون بالضبط ما ينبغي الاعتماد عليه.
على الرغم من ذلك، لا يعني البساطة بالضرورة أن تكون جيدة. بمرور الوقت، زاد الطلب من المهم ألا يكون كل شيء (أو يدعي أنه) ماوس: كان من الممكن أقلامًا حساسة للضغط ومتوافقة مع الإمالة، من أجل حرية إبداعية مذهلة؛ هل يمكنك استخدِم أصابعك، لذا كل ما تحتاج إليه هو الجهاز ويدك. ومرحبًا، لماذا عدم استخدام أكثر من إصبع واحد أثناء النظر إليها؟
كانت لدينا أحداث لمس لفترة من الوقت لمساعدتنا في ذلك، لكنها واجهة برمجة تطبيقات منفصلة تمامًا مخصصة للّمس، ما يجبرك على ترميز نموذجَي أحداث منفصلَين تريد أن تدعم كلاً من الماوس واللمس. يتم إطلاق Chrome 55 بمعيار أحدث التي توحد كلا النموذجين: أحداث المؤشر.
نموذج حدث فردي
توحِّد أحداث المؤشر نموذج إدخال المؤشر للمتصفّح، حيث يجمع بين اللمس والأقلام وأجهزة الماوس في مجموعة واحدة من الأحداث. على سبيل المثال:
document.addEventListener('pointermove',
ev => console.log('The pointer moved.'));
foo.addEventListener('pointerover',
ev => console.log('The pointer is now over foo.'));
وفي ما يلي قائمة بجميع الأحداث المتاحة، والتي من المفترض أن تبدو مألوفة تمامًا إذا إذا كنت على دراية بأحداث الماوس:
pointerover
|
دخل المؤشر إلى مربع إحاطة العنصر.
ويحدث ذلك فورًا للأجهزة التي تدعم التمرير، أو قبل
حدث pointerdown للأجهزة التي لا تحتاج إلى ذلك.
|
pointerenter
|
تشبه pointerover ، ولكن لا تظهر فقاعات وتُستخدَم.
التابعة بشكل مختلف.
تفاصيل حول المواصفات
|
pointerdown
|
دخل المؤشر في حالة الزر "نشط"، حيث يظهر زر أو الاتصال الذي يتم إنشاؤه، اعتمادًا على دلالات جهاز إدخال. |
pointermove
|
تم تغيير موضع المؤشر. |
pointerup
|
غادر المؤشر حالة الزر نشط. |
pointercancel
|
حدث شيء ما يعني أنه من غير المحتمل أن ينبعث مؤشر الماوس أي المزيد من الأحداث. هذا يعني أنه يجب عليك إلغاء أي إجراءات قيد التقدم والمضي قدمًا مرة أخرى إلى حالة إدخال محايدة. |
pointerout
|
ترك المؤشر مربع الإحاطة للعنصر أو الشاشة. أيضًا بعد
pointerup ، إذا كان الجهاز لا يتيح ميزة التمرير.
|
pointerleave
|
تشبه pointerout ، ولكن لا تظهر فقاعة تفسيرية ومقبض.
التابعة بشكل مختلف.
تفاصيل حول المواصفات
|
gotpointercapture
|
تلقّى العنصر التقاط المؤشر. |
lostpointercapture
|
المؤشر الذي كان يتم تسجيله صدرت. |
أنواع الإدخال المختلفة
بشكل عام، تتيح لك أحداث المؤشر كتابة الرمز بطريقة لا تعتمد على الإدخال،
بدون الحاجة إلى تسجيل معالِجات أحداث منفصلة لأجهزة الإدخال المختلفة.
بالطبع، ستظل بحاجة إلى الانتباه إلى الاختلافات بين أنواع الإدخالات، مثل ما إذا كان
ينطبق مفهوم التمرير. إذا كنت تريد التفريق بين أنواع أجهزة الإدخال المختلفة - فربما توفر
رموز/وظائف منفصلة للإدخالات المختلفة - ولكن يمكنك القيام بذلك من
ضمن معالِجات الأحداث نفسها باستخدام السمة pointerType
PointerEvent
من واجهة pyplot. على سبيل المثال، إذا كنت تقوم بترميز درج تنقل جانبي، فيمكنك
أن يستخدم المنطق التالي في حدث pointermove
:
switch(ev.pointerType) {
case 'mouse':
// Do nothing.
break;
case 'touch':
// Allow drag gesture.
break;
case 'pen':
// Also allow drag gesture.
break;
default:
// Getting an empty string means the browser doesn't know
// what device type it is. Let's assume mouse and do nothing.
break;
}
الإجراءات التلقائية
في المتصفّحات التي تعمل باللمس، يتم استخدام إيماءات معيّنة لإتاحة الانتقال للأعلى أو للأسفل في الصفحة أو تكبيرها أو تصغيرها أو إعادة تحميلها.
في حالة أحداث اللمس، سيظل بإمكانك تلقّي الأحداث أثناء هذه الأحداث
أثناء تنفيذ الإجراءات، على سبيل المثال، سيستمر تنشيط "touchmove
" أثناء تمرير المستخدم.
باستخدام أحداث المؤشر، كلما تم تشغيل إجراء افتراضي مثل التمرير أو التكبير،
سيظهر لك حدث pointercancel
لإعلامك بأنّ المتصفِّح قد استخدم
التحكم في المؤشر. على سبيل المثال:
document.addEventListener('pointercancel',
ev => console.log('Go home, the browser is in charge now.'));
السرعة المدمجة: يتيح هذا النموذج تحسين الأداء تلقائيًا مقارنةً بأحداث اللمس، حيث قد تحتاج إلى استخدام أدوات معالجة الأحداث السلبية لتحقيق نفس المستوى من الاستجابة.
يمكنك منع المتصفّح من التحكم من خلال
touch-action
خاصية CSS. وعند ضبطها على none
في أحد العناصر، سيتم إيقاف الكل.
من الإجراءات المحددة بواسطة المتصفح التي بدأت من هذا العنصر. ولكن هناك عدد من
قيم أخرى للتحكم الأكثر دقة، مثل pan-x
، للسماح
المتصفح للتفاعل مع الحركة على المحور س ولكن ليس على المحور ص. الإصدار 55 من Chrome
يدعم القيم التالية:
auto
|
الإعداد التلقائي: يمكن للمتصفح تنفيذ أي إجراء افتراضي. |
none
|
لا يُسمح للمتصفّح بتنفيذ أي إجراءات تلقائية. |
pan-x
|
يُسمح للمتصفّح فقط بتنفيذ الإجراء التلقائي للتمرير الأفقي. |
pan-y
|
يُسمح للمتصفّح فقط بتنفيذ الإجراء التلقائي للتمرير العمودي. |
pan-left
|
يُسمح للمتصفّح فقط بتنفيذ الإجراء التلقائي للتمرير الأفقي وتحريك الصفحة إلى اليسار فقط |
pan-right
|
يُسمح للمتصفّح فقط بتنفيذ الإجراء التلقائي للتمرير الأفقي وتحريك الصفحة إلى اليمين فقط |
pan-up
|
يُسمح للمتصفّح فقط بتنفيذ الإجراء التلقائي للتمرير العمودي ولتحريك الصفحة فقط إلى الأعلى. |
pan-down
|
يُسمح للمتصفّح فقط بتنفيذ الإجراء التلقائي للتمرير العمودي وتحريك الصفحة فقط إلى أسفل |
manipulation
|
يُسمح للمتصفّح فقط بتنفيذ إجراءات الانتقال للأعلى أو للأسفل في المحتوى وتكبيره أو تصغيره. |
التقاط المؤشر
هل سبق أن قضيت ساعة محبطة في تصحيح أخطاء mouseup
معطّلة
الحدث، حتى تدرك أن السبب وراء ذلك هو أن المستخدم يسحب الزر
خارج استهداف النقرات؟ لا؟ حسنًا، ربما أقصد أنا فقط.
ومع ذلك، لم تكن هناك طريقة جيدة حقًا لمعالجة هذه المشكلة. حَسَنًا،
يمكنك إعداد معالج mouseup
على المستند، وحفظ بعض الحالات على
تطبيقك لتتبع الأشياء. هذا ليس الحل الأكثر أنظف،
مع ذلك، لا سيما إذا كنت تنشئ مكون ويب وتحاول الحفاظ على تنظيم كل شيء
معزولة.
مع أحداث المؤشر تأتي حلاً أفضل بكثير: يمكنك التقاط المؤشر،
للتأكّد من ظهور حدث pointerup
هذا (أو أي حدث آخر مراوغ عنه)
الأصدقاء).
const foo = document.querySelector('#foo');
foo.addEventListener('pointerdown', ev => {
console.log('Button down, capturing!');
// Every pointer has an ID, which you can read from the event.
foo.setPointerCapture(ev.pointerId);
});
foo.addEventListener('pointerup',
ev => console.log('Button up. Every time!'));
دعم المتصفح
في وقت الكتابة، تتوفر أحداث المؤشر في Internet Explorer 11، Microsoft Edge وChrome وOpera ومدعوم جزئيًا في Firefox. يمكنك قائمة محدّثة على caniuse.com.
يمكنك استخدام عنصر polyfill لأحداث المؤشر من أجل وسد الثغرات. أو بدلاً من ذلك، فإن البحث عن دعم المتصفح في وقت التشغيل هو مباشر:
if (window.PointerEvent) {
// Yay, we can use pointer events!
} else {
// Back to mouse and touch events, I guess.
}
تعتبر أحداث المؤشر رائعة للتحسين التدريجي:
تعديل طرق الإعداد لإجراء عملية الفحص أعلاه، وإضافة حدث المؤشر
المعالِجات في مجموعة أدوات if
، وانقل معالِجات أحداث الماوس/اللمس إلى
حظر else
ننصحك بتجربتها وإعلامنا برأيك.