سنتناول في هذا المقال أحداث الفأرة وخاصّياتها بمزيد من التفصيل.
يُرجى التنبه: لا تأتي هذه الأحداث فقط من "الأجهزة ذوات الفأرة"، ولكن من أجهزة أخرى أيضًا مثل الهواتف والأجهزة اللوحيّة، حيث تُحاكى فيها هذه الأحداث لتحقيق التوافق.
أنواع أحداث الفأرة
سبق وأن رأينا بعض هذه الأحداث:
-
mousedown/mouseup
: يحدث عندما يُنقر / يُحرَّر زرّ الفأرة فوق عنصر ما. -
mouseover/mouseout
: يحدث عندما يبلغ / يغادر مؤشّر الفأرة عنصرا ما. -
mousemove
: يحدث كلّما تحرّك مؤشّر الفأرة فوق عنصر ما. -
click
: يحدث بعد حدوثmousedown
ثمmouseup
فوق نفس العنصر باستخدام الزرّ الأيسر للفأرة. -
dblclick
؛ يحدث بعد النقر مرّتين على نفس العنصر خلال إطار زمنيّ قصير. يندر استخدامه هذه الأيام. -
contextmenu
: يحدث عندما يُضغط الزرّ الأيمن للفأرة. وبما أنّ هناك طرقا أخرى لفتح القائمة المنبثقة، كاستخدام زرّ خاصّ في لوحة المفاتيح مثلا، فإنّه يحدث عند ذلك أيضا، ولا يُعدّ بذلك من الأحداث المختصّة بالفأرة على وجه الدقّة.
هناك العديد من الأحداث الأخرى أيضا، سنتطرّق إليها لاحقا.
ترتيب الأحداث
مثلما يمكن أن تلاحظ في القائمة أعلاه، قد يؤدّي فعل واحد للمستخدم إلى وقوع عدّة أحداث. على سبيل المثال، يؤدّي النقر بالزرّ اﻷيسر أوّلا إلى حدوث mousedown
عند الضغط على الزرّ، ثم إلى حدوث mouseup
وclick
عند تحريره.
في الحالات التي يبتدئُ فيها فعلٌ واحد عدّةَ أحداث، فإنّ ترتيبها يكون ثابتا. بمعنى أن المعالجات نُستدعى هنا حسب الترتيب mousedown
-> mouseup
-> click
.
إليك التجربة الحيّة التالية لمثال تُسجَّل فيه جميع أحداث الفأرة، وإذا كان هناك فارق بأكثر من ثانية بينها ستُفصل بخطّ أفقيّ. يمكنك أيضا رؤية الخاصّيّة button
التي تمكّن من اكتشاف زرّ الفأرة، وسيُشرح ذلك في أسفله:
زر الفأرة
تكون للأحداث المتعلّقة بالنقر دائما الخاصّيّة button
، التي تمكّن من معرفة الزرّ الذي ضُغط بالضبط. قد لا نحتاج إلى استعمالها في العادة مع اﻷحداث click
وcontextmenu
، لأّن اﻷوّل يحدث فقط عند النقر باليسار، بينما يحدث اﻷخير فقط عند النقر باليمين. لكن في المقابل، قد تحتاج معالجات الأحداث mousedown
وmouseup
إلى الخاصّيّة event.button
، لأنّ تلك اﻷحداث قد تقع عند النقر على أيٍّ من الأزرار، فتمكّن button
من التمييز بين "mousedown اﻷيمن" و"mousedown اﻷيسر".
يمكن أن تأخذ الخاصّيّة button
القيم التالية:
حالة الزرّ |
event.button
|
---|---|
الزرّ اﻷيسر (اﻷوليّ) | 0 |
الزرّ اﻷوسط (الملحق) | 1 |
الزرّ اﻷيمن (الثانويّ) | 2 |
الزرّ X1 (الخلف) | 3 |
الزرّ X2 (اﻷمام) | 4 |
ليس لدى معظم أجهزة الفأرة سوى الزرّين اﻷيمن واﻷيسر، فتكون القيم الممكنة 0
أو 2
. تولّد اﻷجهزة اللمسيّة أيضا مثل هذه اﻷحداث عندما ينقر أحدهم عليها.
ثم إنّ هناك الخاصّيّة event.buttons
التي تعبّر عن جميع الأزرار المضغوطة حاليّا بعدد صحيح، يكون ناتج مجموع قيم تلك اﻷزرار. يندر جدّا استخدام هذه الخاصّيّة في الواقع، لكن يمكنك أن تجد المزيد من التفاصيل حولها من MDN إن حصل واحتجت لها.
تنبيه: خاصّيّة event.which
المندثرة
قد تستعمل الشيفراتُ القديمة الخاصّيّة event.which
وهي طريقة قديمة وغير قياسية للحصول على الزرّ، ويمكن أن تأخذ القيم التالية:
-
event.which == 1
-- الزرّ اﻷيسر، -
event.which == 2
-- الزرّ اﻷوسط، -
event.which == 3
-- الزرّ اﻷيمن.
حاليّا، تُعدّ event.which
مهملة (deprecated)، ولا ينبغي استعمالها.
مفاتيح التبديل: shift و alt و ctrl و meta
تحتوي جميع أحداث الفأرة على المعلومات الخاصّة بمفاتيح التبديل المضغوطة. فللكائن event
الخاصّيّات التالية:
-
shiftKey
: المفتاحShift
-
altKey
: المفتاحAlt
(أو المفتاحOpt
في ماك) -
ctrlKey
: المفتاحCtrl
-
metaKey
: المفتاحCmd
في ماك
تكون قيم هذه الخاصّيّات true
إذا كان المفتاح المقابل لها مضغوطا عند وقوع الحدث. فعلى سبيل المثال، لا يعمل الزرّ أسفله إلا عند النقر مع الضغط على المفاتيح Alt
وShift
معا:
<button id="button">Alt+Shift+Click on me!</button> <script> button.onclick = function(event) { if (event.altKey && event.shiftKey) { alert('Hooray!'); } }; </script>
تنبيه: عادة ما يُستعمل المفتاح Cmd
بدل Ctrl
في ماك
توجد في ويندوز ولينكس مفاتيح التبديل Alt
وShift
وCtrl
. كما يوجد في ماك المفتاح الإضافيّ Cmd
الذي تقابله الخاصّيّة metaKey
.
في معظم التطبيقات، عندما يُستعمل في ويندوز ولينكس المفتاح Ctrl
فإنّ في ماك يُستعمل المفتاح Cmd
. بمعنى أنّه عندما يضغط مستخدم ويندوز على المفتاحين Ctrl
وEnter
أو Ctrl
وA
، فإنّ من المفترض أن يضغط مستخدم ماك على المفتاحين Cmd
وEnter
أو Cmd
وA
، وهكذا.
فإذا أردت أن تعتمد الجمع بين Ctrl
والنقر مثلا، فمن المعقول استخدام الجمع بين Cmd
والنقر في ماك. فذلك أريح لمستخدمي ماك.
حتى وإن فضّلنا اضطرار مستخدمي ماك إلى الجمع بين Ctrl
والنقر -- ذلك صعب بعض الشيء، فإنّ المشكلة أن النقر باليسار مع الضغط على Ctrl
في نظام التشغيل ماك يُفهم على أنّه نقر باليمين، ويؤدّي إلى توليد الحدث contextmenu
، وليس click
كما في ويندوز ولينكس.
فإذا أردنا أن نحرص على راحة مستخدمي جميع أنظمة التشغيل، فينبغي أن نفحص كلتى الخاصّيتين ctrlKey
وmetaKey
. ما يعني ذلك في شيفرة جافاسكربت هو أن نتحقّق if (event.ctrlKey || event.metaKey)
.
تنبيه: هناك أيضا أجهزة محمولة
يُعدّ الجمع بين المفاتيح إضافة جيّدة في سير العمل. فإذا كان الزائر يستخدم لوحة المفاتيح، فستعمل بشكل جيّد. لكن إذ لم يكن جهازه متضمّنا لها، فلابدّ إذا من وجود سبيل للعمل دون مفاتيح التبديل.
الإحداثيات: clientX/Y وpageX/Y
تقدّم جميع أحداث الفأرة نوعين من الإحداثيّات:
-
بالنسبة إلى النافذة:
clientX
وclientY
. -
بالنسبة إلى المستند:
pageX
وpageY
.
باختصار، تُحتسب الإحداثيّات بالنسبة إلى النافذة pageX/Y
ابتداءً من الزاوية العليا من اليسار للمستند، ولا تتغيّر عند تمرير (scroll) الصفحة، بينما تُحتسب clientX/Y
ابتداءً من الزاوية العليا من اليسار للنافذة الحاليّة وتتغيّر عند تمرير الصفحة.
على سبيل المثال، إذا كانت لدينا نافذة قياسها 500x500، والفأرة موجودة في الزاوية العليا من اليسار، فإنّ قيمتا clientX
وclientY
هي 0
، مهما مُرّرت الصفحة. بينما إذا كانت الفأرة في المنتصف، فإن قيمتا clientX
وclientY
هي 250
، أيًّا كان مكانها في المستند. وهما بهذا الاعتبار متشابهتان مع position:fixed
.
حرّك الفأرة فوق حقل المُدخل لرؤية clientX/clientY
(المثال موجود داخل iframe
، لذا فإنّ الإحداثيّات منسوبة إلى iframe
).
<input onmousemove="this.value=event.clientX+':'+event.clientY" value="Mouse over me">
تجنب التحديد مع mousedown
للنقر المزدوج بالفأرة أثر جانبيّ قد يكون مزعجا في بعض الواجهات، ألا وهو تحديد النصّ. على سبيل المثال، يؤدّي النقر المزدوج على النصّ أدناه إلى تحديده بالإضافة تشغيل المعالج المسند إليه:
<span ondblclick="alert('dblclick')">Double-click me</span>
وإذا ضغط أحدهم زرّ الفأرة اﻷيمن، وحرك الفأرة دون تحريره، فسيعمل ذلك أيضا على تحديد النص، ولا يُرغب في ذلك غالبا.
هناك عدّة طرق لتجنُّب التحديد، يمكنك الاطّلاع عليها في مقال التحديد والمدى. لكن في هذه الحالة خاصّة، أنسب طريقة لذلك هي منع فعل المتصفّح عند mousedown
، ليحول ذلك دون حصول هذه التحديدات:
Before... <b ondblclick="alert('Click!')" onmousedown="return false"> Double-click me </b> ...After
لا يُحدَّد العنصر ذو الخطّ العريض الآن عند النقر المزدوج عليه، ولا يؤدّي النقر عليه باليسار إلى ابتداء تحديده أيضا. لكن يُرجى التنبّه: يبقى النصّ داخله قابلا للتحديد، إذا ابتُدئ التحديد قبل النصّ أو بعده، لا عليه مباشرة، ولا بأس في ذلك بالنسبة للمستخدمين عادة.
ملاحظة: منع النسخ
إذا أردنا أن نعطّل تحديد النصّ لحماية محتوى صفحتنا من النسخ واللصق، فيمكننا عندها استعمال حدث آخر: oncopy
.
<div oncopy="alert('Copying forbidden!');return false"> Dear user, The copying is forbidden for you. If you know JS or HTML, then you can get everything from the page source though. </div>
فلو حاولت نسخ جزء من النصّ الذي بداخل <div>
، فلن يعمل ذلك، ﻷن الفعل الافتراضيّ oncopy
قد مُنع. يمكن للمستخدم بالتأكيد الوصول إلى مصدر HTML، وأخذ المحتوى من هناك، لكن لا يُحسن الجميع فعل ذلك.
الملخص
لأحداث الفأرة الخاصّيّات التالية:
-
الزرّ:
button
. -
مفاتيح التبديل: (
true
عند الضغط عليها):altKey
وctrlKey
وshiftKey
وmetaKey
(ماك).-
إذا كنت تودّ اعتماد
Ctrl
، لا تنس مستخدمي ماك، إذ يستعملون عادةCmd
، فيُفضّل إذًا أن نتحقّقif (e.metaKey || e.ctrlKey)
.
-
إذا كنت تودّ اعتماد
-
الإحداثيّات بالنسبة للنافذة:
clientX/clientY
. -
الإحداثيّات بالنسبة للمستند:
pageX/pageY
.
فعل المتصفح الافتراضيّ عند mousedown
هو تحديد النصّ، فإذا لم يكن مناسبا في الواجهة، ينبغي منعه.
في المقال التالي سنتناول المزيد من التفاصيل حول اﻷحداث التي تلي حركة المؤشّر وكيفية تتبّع تغيير العناصر التي تحته.
التمارين
قائمة قابلة للتحديد
اﻷهمية: 5
أنشئ قائمة تكون عناصرها قابلة للتحديد، كما في مديري الملفّات.
-
بالنقر على عنصر من القائمة يُحدَّد ذلك العنصر فقط (بإضافة الصنف
selected.
) ويزال التحديد عن بقيّة العناصر. -
إذا تمّ النقر مع المفتاح
Ctrl
(Cmd
بالنسبة لماك)، فإنّ التحديد ينقلب (toggled) في ذلك العنصر، ولا تتغيّر بقيّة العناصر.
يمكن مشاهدة المثال من هنا.
ملاحظة: في هذا التمرين، يمكننا افتراض أنّ عناصر القائمة مكوّنة من نصّ فقط. ليست هناك وسوم متداخلة.
ملاحظة أخرى: امنع تحديد المتصفّح اﻷصيل للنصوص عند النقر عليها.
أنجز التمرين في البيئة التجريبية
الحل
ترجمة -وبتصرف- للمقال Mouse events من سلسلة Browser: Document, Events, Interfaces لصاحبها Ilya Kantor
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.