٣ يونيو ٢٠٢٠

أحداث الماوس

في هذا الفصل سنتناول المزيد حول أحداث الماوس وخصائصها.

يرجى ملاحظة: هذه الأحداث ليست مقتصرة على "الماوس " ولكن تأتى أيضاً من أجهزة أخرى مثل الهواتف والأجهزة اللوحية، والتى يتم مضاهاتها للتوافق.

أنواع أحداث الماوس

لقد راينا بالفعل بعض هذه الأحداث:

mousedown/mouseup

:استخدام زر الماوس في النقر / تحرير النقر عن العنصر .

mouseover/mouseout
تحريك مؤشر الماوس فوق / خارج العنصر.
mousemove
يعمل هذا الحدث فعلياً مع كل حركة لمؤشر الماوس فوق العنصر.
click
يعمل بعد mousedownثم mouseup على نفس العنصر بإستخدام الزر الأيسر للماوس.
dblclick
يعمل بعد النقر مرتين على نفس العنصر خلال فترة زمنية قصيرة. نادرا ما يستخدم في الوقت الحاضر.

contextmenu

يعمل عندما يتم الضغط على زر الفأرة الأيمن. وهناك طرق أخرى لفتح قائمة السياق ، على سبيل المثال باستخدام مفتاح معين من لوحة المفاتيح ، ويمكن أيضًا استخدامه في هذه الحالة ، لذا فهو ليس بالضبط حدث للماوس .

… وهناك أيضا العديد من الأحداث الأخرى ، واللتى سنتطرق لها لاحقًا .

ترتيب الأحداث

كما ترى من القائمة السابقة ، قد يقوم إجراء المستخدم بتشغيل أكثر من حدث أو أحداث متعددة

على سبيل المثال , عند النقر على الزر الايسر فإن أول حدث يتم تشغيله mousedown, عند الضغط على الزر, ثم mouseup وبالتالي أيضا click عند تحرير النقر.

في الحالات التي يبدأ فيها إجراء واحد أحداثًا متعددة ، فإنه يتم إصلاح ترتيبها. بمعنى ، أنه يقوم باستدعاء الأحداث بالترتيب mousedownmouseupclick.

لمعاينة الأحداث بوضوح أنقر فوق الزر أدناه. جرب النقر مرتين أيضاً.

في التجربة التالية ، يتم تسجيل جميع أحداث الماوس ، وإذا كان هناك تأخير لأكثر من ثانية واحدة يتم فصلها بخط أفقي متقطع.

كما يمكننا أن نرى button الذي يسمح لنا باكتشاف زر الماوس ، كما هو موضح أدناه.

زر الماوس

تحتوي دائما الأحداث المتعلقة بالنقر على خاصية button, والتي تسمح لك بأستخدام زر الماوس.

وعادة لا نستخدم هذه الخاصية لكل من هذين الحدثين click و contextmenu , وذلك لأن الأول يحدث فقط عند النقر بزر الماوس الأيسر ، والأخير – فقط عند النقر بزر الماوس الأيمن.

من ناحية أخرى فإن, mousedown و mouseup قد تحتاج معالجتها إلى event.button, وذلك لأن هذه الأحداث من الممكن أن تعمل على أى زر لذا فإن button يتيح لك التمييز بين “زر الماوس الأيمن” و “زر الماوس الأيسر”.

القيم المحتملة لـ event.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 تم ايقافها, لذا لا يجب إستخدامها.

مفاتيح التعديل: shift, alt, ctrl و meta

تتضمن جميع أحداث الماوس معلومات عند الضغط على مفاتيح التعديل

خصائص الحدث :

  • shiftKey: Shift
  • altKey: Alt (أو Opt لنظام تشغيل Mac)
  • ctrlKey: Ctrl
  • metaKey: Cmd لنظام Mac

تكون القيمة true   إذا تم الضغط على المفتاح المقابل أثناء الحدث.

على سبيل المثال, الزر أدناه يعمل فقط عند الضغط على Alt+Shift ثم النقر :

<button id="button">Alt+Shift+أنقر علي!</button>

<script>
  button.onclick = function(event) {
    if (event.altKey && event.shiftKey) {
      alert('مرحى!');
    }
  };
</script>
إنتبه: نظام Mac عادة نستخدم Cmd بدلا من Ctrl

في نظامى التشغيل Windows و Linux توجد مفاتيح التعديل Alt, Shift و Ctrl. بينما نظام تشغيل Mac هناك آخر: Cmd, يتوافق مع خاصية metaKey.

في معظم التطبيقات, عندما Windows/Linux بستخدم Ctrl, على Mac نستخدم Cmd.

وهذا يعنى: عندما يقوم مستخدم Windows بالضغط على Ctrl+Enter أو Ctrl+A, فإن مستخدم Mac يضغط على Cmd+Enter أو Cmd+A, وهكذا.

لذا إذا أردنا دعم مجموعات مثل Ctrl+ النقر, فمن المنطقي بالنسبة لنظام Mac نستخدم Cmd+ النقر. وهذا يكون أكثر راحة لمستخدمي Mac .

حتى اذا أردنا إجبار مستخدمي Mac بإستخدام Ctrl+ النقر – فهذا يعد صعباً.وتكمن المشكلة في : أن النقر الأيسر مع المفتاح Ctrl تكون بمثابة right-click على MacOS, وبالتالى تقوم بتشغيل حدث contextmenu , وليس click كما في Windows/Linux.

ولذلك إذا أردنا أن يشعر المستخدمين لجميع أنظمة التشغيل بالراحة , بإستخدامهم ctrlKey فإنه ينبغي علينا التحقق من metaKey.

بالنسبة لترميز – JS فإنه يجب علينا التحقق مما إذا كان if (event.ctrlKey || event.metaKey).

هناك أيضا أجهزة هواتف محمولة

وجود لوحة مفاتيح أمر جيد كإضافة الى سير العمل. فإذا كان الزائر يستخدمها – فلا بأس.

ولكن إذا لم يكن أجهزتهم بها – فلابد أن تكون هناك طريقة للعمل بدون مفاتيح التعديل.

الأحداثيات: clientX/Y, pageX/Y

جميع أحداث الماوس توفر إحداثيات بطريقتين:

  1. نسبي-للنافذة: clientX و clientY.
  2. نسبي-للمستند: pageX و pageY.

وقد غطينا بالفعل الإختلاف بينهما في فصل الإحداثيات.

بإختصار , الأحداثيات النسبية-للمستند pageX/Y يتم حسابها من الزاوية العلويه اليسرى للمستند, ولا تتغير أو تتأثر عند تمرير الصفحة, بينما clientX/Y تحسب من الواوية العلوية اليسرى للنافذة الحالية. وعندما يتم تمرير الصفحة , فإنها تتغير.

على سبيل المثال, إذا كان لدينا نافذة بحجم 500x500, ومؤشر الماوس في الزاوية العلوية اليسرى , فإن clientX و clientY تكون 0, بغض النظر عن أى تمرير للصفحة.

وإذا كان مؤشر الماوس في المنتصف, فإن clientX و clientY تكون 250, بغض النظر عن مكانه في المستند. وهي تتشابه مع position:fixed في هذا الجانب.

حرك الماوس فوق حقل الإدخال لرؤية clientX/clientY (هذا المثال موجود في iframe, لذا فإن الأحداثيات مرتبطة بهذا iframe):

<input onmousemove="this.value=event.clientX+':'+event.clientY" value="حرك الماوس فوقي">

منع الإختيار في الماوس

النقر المزدوج بزر الماوس له تأثير جانبي قد يكون غير ملائم في بعض الواجهات: فهو يحدد النص.

على سبيل المثال, يؤدي النقر المزدوج على النص أدناه إلى تحديده بالإضافة إلى معالجنا:

<span ondblclick="alert('dblclick')">أنقر مرتين علي</span>

إذا قمت بالضغط مع الإستمرار على زر الماوس الأيسر, ودون تحرير الزر , “إضغط مع الإستمرار على الماوس”,فسيكون هناك أيضًا تحديد , وقد يكون على غير ما تريد.

هناك عدة طرق لمنع التحديد , بإمكانك أن تقرأ عنها في فصل Selection and Range.

في هذه الحالة ، فإن الطريقة الأكثر منطقية هي منع إجراء المتصفح من mousedown. وسيؤدي هذا الى الغاء كل هذه التحديدات:

قبل...
<b ondblclick="alert('Click!')" onmousedown="return false">
  أنقر مرتين علي
</b>
...بعد

الآن لم يتم تحديد العنصر بالخط العريض بنقرات مزدوجة ، ولن يؤدي الضغط على الزر الأيسر عليه إلى بدء التحديد.

يرجى ملاحظة أن النص الموجود بداخله لا يزال قابلاً للتحديد. ومع ذلك ، يجب ألا يبدأ التحديد في النص نفسه ، ولكن قبله أو بعده. عادة هذا جيد للمستخدمين.

منع النسخ
إذا أردنا تعطيل التحديد لحماية محتوى صفحتنا من لصق النسخ ، فيمكننا استخدام حدث آخر
oncopy.
<div oncopy="alert('Copying forbidden!');return false">
عزيزي المستخدم،
 النسخ ممنوع لك.
 إذا كنت تعرف JS أو HTML ، فيمكنك الحصول على كل شيء من مصدر الصفحة.
</div>

إذا حاولت نسخ جزء من النص في <div>, فلن ينجح ذلك, لأن الإجراء الافتراضي oncopy ممنوع.

من المؤكد أن المستخدم لديه حق الوصول إلى مصدر HTML-للصفحة, ويمكنه أخذ المحتوى من هناك, ولكن لا يعرف الجميع كيفية القيام بذلك.

ملخص

تتميز أحداث الماوس بالخصائص التالية:

  • زر: button.

  • مفاتيح التعديل (true إذا تم الضغط عليه): altKey, ctrlKey, shiftKey و metaKey (Mac).

  • إذا كنت تريد التعامل معها Ctrl, لذا لا تنسى Mac مستخدمي , عادة ما يستخدم Cmd, لذلك من الأفضل التحقق if (e.metaKey || e.ctrlKey).

  • إحداثيات النافذة: clientX/clientY.

  • إحداثيات المستند: pageX/pageY.

الإجراء الافتراضي للحدث mousedown هو تحديد النص, إذا كان من المرجح أن يتدخل في الواجهة يمكنك إلغاؤه.

في الفصل التالي ، سنرى المزيد من التفاصيل حول الأحداث التي تتبع حركة المؤشر وكيفية تتبع تغييرات العناصر تحت المؤشر

مهمه

قم بإنشاء قائمة يمكن فيها تحديد العناصر , مثل الموجودة بمدير الملفات.

  • عند النقر فوق عنصر في القائمة يتم تحديد هذا العنصر فقط (إضافة الفئةs .selected), وإلغاء تحديد العناصر الأخرى.
  • إذا تم النقر مع Ctrl (Cmd لنظام Mac), يتم التحديد على العنصر ، ولكن لا يتم تغيير بقية العناصر

مثال توضيحي:

P.S. ملاحظة: في هذه المهمة ، تحتوي جميع عناصر القائمة على نص فقط. لا توجد علامات متداخلة

P.P.S. منع اختيار النص الأصلي للمتصفح على النقرات.

افتح sandbox للمهمه.

خريطة الدورة التعليمية

التعليقات

إقرأ هذا قبل أن تضع تعليقًا…
  • إذا كان لديك اقتراحات أو تريد تحسينًا - من فضلك من فضلك إفتح موضوعًا فى جيتهاب أو شارك بنفسك بدلًا من التعليقات.
  • إذا لم تستطع أن تفهم شيئّا فى المقال - وضّح ماهو.
  • إذا كنت تريد عرض كود استخدم عنصر <code> ، وللكثير من السطور استخدم <pre>، ولأكثر من 10 سطور استخدم (plnkr, JSBin, codepen…)