در این بخش به جزئیاتی دربارهی رویدادهای موس و خصوصیات آنها میپردازیم.
توجه داشته باشید: این رویدادها نه تنها بواسطه “دستگاههای موس”، بلکه بواسطه دستگاههای شبیهسازی شده تلفن و تبلت نیز روی بدهند.
انواع رویدادهای موس
ما قبلا با چند مورد از این رویدادها آشنا شدهایم:
mousedown/mouseup
- دکمه موس کلیک/رها میشود.
mouseover/mouseout
- اشارهگر موس روی/بیرون عنصر میرود.
mousemove
- هر حرکت موس روی عنصر این رویداد را فرامیخواند.
click
- درصورتی که کلید چپ موس استفاده شود، این رویداد بعد از
mousedown
و سپسmouseup
روی یک عنصر فراخوانده میشود. dblclick
- زمانی که دو کلیک روی یک عنصر در بازه زمانی کوتاهی انجام شود فراخوانده میشود. امروزه به ندرت استفاده میشود.
contextmenu
- زمانی که کلید راست موس فشرده روی یک عنصر فشرده شود فراخوانده میشود. راههای دیگری برای باز کردن منوی زمینه وجود دارد. برای مثال استفاده از یک کلید مخصوص در کیبورد این رویداد را نیز فراخوانی میکند، پس این دقیقا یک رویداد موس نیست.
…چندین رویداد دیگر وجود دارند که بعدا آنهارا برسی میکنیم.
ترتیب رویدادها
همانطور که در لیست بالاهم مشاهده کردید، یک عمل کاربر میتواند باعث فراخوانی چند رویداد شود.
برای مثال، یک کلیک چپ ابتدا mousedown
را فراخوانی میکند، هنگامی که کلید فشرده میشود، سپس mouseup
و click
زمانی که کلید رها میشود.
در مواقعی که یک عمل از سمت کاربر باعث فراخوانی چند رویداد شود، ترتیب آنها ثابت خواهد بود. به این معنی که کنترلکنندهها به ترتیب mousedown
→ mouseup
→ click
صدا زده خواهند شد.
روی دکمه زیر کلیک کنید تا رویدادها را ببینید. دابل کلیک را هم امتحان کنید.
در قسمت آزمایشی زیر همه رویدادهای موس (mouse) چاپ میشوند، و اگر بیش از ۱ ثانیه فاصله زمانی بین آنها باشد، توسط یک خط افقی جدا میشوند.
همچنین میتوانیم یک خاصیت button
مشاهده کنیم که به ما این امکان را میدهد تا کلید موس را شناسایی کنیم که در قسمت پایین شرح داده شده.
کلید موس
رویدادهای مربوط به کلیککردن همیشه یک خاصیت button
خواهند داشت، که به ما این امکان را میدهد کلید موس را دقیقا تشخیص دهیم.
ما معمولا این خاصیت را برای رویدادهای click
و contextmenu
استفاده نمیکنیم، زیرا اولی فقط با کلیک چپ، و دومی با کلیک راست اتفاق میافتد.
از طرف دیگر، کنترلکنندههای mousedown
و mouseup
ممکن است به event.button
نیاز پیدا کنند، زیرا این رویدادها به واسطه هر کلیدی اتفاق میافتند، پس button
این امکان را میدهد تا “کلیک کلید راست” و “کلیک کلید چپ” موس را تشخیص دهیم.
مقادیر قابل قبول برای event.button
:
event.button |
وضعیت کلید |
---|---|
0 | کلید چپ (اصلی) |
1 | کلید وسط (کمکی) |
2 | کلید راست (ثانوی) |
3 | کلید X1 (عقب) |
4 | کلید X2 (جلو) |
بیشتر موسها فقط کلید چپ و راست را دارند، پس مقادیر احتمالی 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
: ShiftaltKey
: Alt (یا Opt برای مک)ctrlKey
: CtrlmetaKey
: Cmd برای مک
مقادیر آنها در صورتی که کلید اشارهشده در حین رویداد فشرده شده بود، true
است.
برای مثال، کلید زیر تنها روی Alt+Shift+کلیک کار میکند:
<button id="button">روی من Alt+Shift+کلیک کنید</button>
<script>
button.onclick = function(event) {
if (event.altKey && event.shiftKey) {
alert('هووورا!');
}
};
</script>
Cmd
بجایCtrl
خواهد بودروی ویندوز و لینوکس کلیدهای اصلاحکننده Alt, ShiftوCtrlوجود خواهد داشت. روی مک یک کلید دیگر نیز وجود دارد: Cmd, متناظر خاصیت metaKey
.
در بیشتر اپلیکیشنها هنگامی که در ونیدوز/لینوکس از Ctrl استفاده میشود، روی مک Cmd خواهد بود.
به این معنی که: وقتی یک کاربر ویندوز کلید Ctrl+Enter یا Ctrl+A را میفشارد، یک کاربر مک باید Cmd+Enter یا Cmd+A را فشار دهد، مشابه برای بقیه کلیدها.
پس اگر میخواهیم ترکیبی مانند Ctrl+کلیک را پشتیبانی کنیم، پس برای مک باید از Cmd+کلیک استفاده کنیم. این ترکیب برای کاربران مک راحتتر خواهد بود.
حتی اگر میخواستیم که کاربر مک را وادار کنیم که از Ctrl+کلیک استفاده کند، دشوار خواهد بود. مشکل این است که: یک چپ-کلیک با Ctrl همانند یک right-click شناخته میشود، و رویداد contextmenu
اتفاق میافتد، نه اینکه مانند ویندوز/لینوکس رویداد click
اتفاق بیفتد.
پس اگر میخواهیم که کاربران همه سیستمهای عامل احساس راحتی داشته باشند، پس همراه ctrlKey
باید metaKey
را نیز چک کنیم.
در کد جاوااسکریپت به این معنی است که میخواهیم if (event.ctrlKey || event.metaKey)
را چک کنیم.
ترکیبهای کلیدهای کیبورد به عنوان یک قابلیت اضافه خوب هستند. اگر کاربر از کیبورد استفاده کند، کار میکنند.
اما اگر دستگاه آنها کیبورد نداشته باشد، پس باید راهی برای زندگی کردن بدون از کلیدهای اصلاحکننده باشد.
مختصات: clientX/Y, pageX/Y
همه رویدادهای موس مختصاتی را به دو صورت در اختیار ما قرار میدهند:
- مربوط به پنجره:
clientX
وclientY
. - مربوط به سند:
pageX
وpageY
.
ما قبلا درباره تفاوت آنها در بخش Coordinates صحبت کردهایم.
به اختصار، مختصات مربوط به سند 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="موس را روی من ببر">
جلوگیری از انتخاب در هنگام mousedown
دابل کلیک موس یک اثر جانبی دارد که در بعضی از رابطههای کاربری ممکن است مزاحم باشد: متن را انتخاب میکند.
برای مثال، دابل کلیک کردن روی متن زیر آنرا انتخاب میکند که در کنترلکندده ما تعریف نشده:
<span ondblclick="alert('dblclick')">من را دوبار کلیک کن</span>
اگر یک نفر کلید چپ موس را فشار دهد، بدون رها کردن آن، اشارهگر موس را جابجا کند، بیشتر اوقات متن را انتخاب میکند که ممکن است باب میل ما نباشد.
راه های مختلفی برای جلوگیری از آن انتخاب وجود دارد، که میتوانید در بخش Selection و Range مشاهده کنید.
منطقیترین راه در این مورد به خصوص این است که از رفتار پیشفرض مرورگر هنگام mousedown
جلوگیری کنیم. این کد از انتخاب هر دو اینها جلوگیری میکند:
قبل...
<b ondblclick="alert('کلیک!')" onmousedown="return false">
من را دوبار کلیک کن
</b>
...بعد
اکنون قسمت پررنگ، هنگام دابل کلیک قابل انتخاب نیست و کلیک چپ روی آن، انتخاب کردن متن را آغاز نمیکند.
توجه داشته باشید: متن داخل آن هنوز قابل انتخاب است. هرچند، انتخاب نباید از روی خود متن، بلکه از قبل یا بعد آن آغاز شود. معمولا کاربران با این رفتار مشکلی ندارند.
اگر میخواهیم که انتخاب شدن متنرا به منظور محافظت کردن از اطلاعات صفحه در مقابل کپی شدن انجام دهیم، میتوانیم از یک رویداد دیگر استفاده کینم: oncopy
.
<div oncopy="alert('کپی کردن ممنوع!');return false">
کاربر عزیز,
کپی کردن برای شما ممنوع شده است.
هرچند اگر که اچتیامال یا جاوااسکریپت بلد هستید، میتوانید هرچه نیاز دارید از سورس صفحه پیدا کنید.
</div>
اگر تلاش کنید که اطلاعات متنی داخل <div>
را کپی کنید، کار نمیکند، زیرا از رفتار پیشفرض مرورگر در هنگام oncopy
جلوگیری شده.
قاعدتا کاربر به سورس اچتیامال صفحه دسترسی دارد، و میتواند هر اطلاعاتی که بخواهد از آنجا بردارد، اما هرکسی نمیداند چطور این کار انجام میشود.
خلاصه
رویدادهای موس این خصوصیاترا دارند:
-
کلید:
button
. -
کلیدهای اصلاحکننده (
true
اگر فشار دادهشوند):altKey
,ctrlKey
,shiftKey
وmetaKey
(مک).- اگر میخواهید که Ctrl را کنترل کنید، کاربران مکرا فراموش نکنید،آنها معمولا از Cmd استفاده میکند. پس بهتر این است که
if (e.metaKey || e.ctrlKey)
چک شود.
- اگر میخواهید که Ctrl را کنترل کنید، کاربران مکرا فراموش نکنید،آنها معمولا از Cmd استفاده میکند. پس بهتر این است که
-
مختصات مربوط به پنجره:
clientX/clientY
. -
مختصاب مربوط به سند:
pageX/pageY
.
رفتار پیشفرض مروگر در هنگام mousedown
انتخاب متن است. اگر این برای رابط کاربری شما مناسب نیست، پس باید از آن جلوگیری شود.
در بخش بعدی ما با جزئیات بیشتری درباره رویدادهایی که حرکت اشارهگر موسرا دنبال میکنند، و همچنین با چگونگی شناسایی تغییرات عنصر زیر آن آشنا خواهیم شد.
نظرات
<code>
استفاده کنید، برای چندین خط – کد را درون تگ<pre>
قرار دهید، برای بیش از ده خط کد – از یک جعبهٔ شنی استفاده کنید. (plnkr، jsbin، codepen…)