رویدادهای ماوس
صفحهای که فقط چیزی نشان میدهد یک سند است و صفحهای که به کلیک جواب میدهد یک برنامه. در این درس میبینید که چطور تابعی از سلام را به رویداد ماوس وصل کنید، مکان اشارهگر را بخوانید، و دوازده رویداد ماوس چه تفاوتی با هم دارند. هر نمونه زیر خودش در پیشنمایش اجرا میشود.
دادن رویدادگیر به یک عنصر
رویدادگیر (handler) تابعی است که مرورگر هنگام رخ دادن چیزی برای یک عنصر صدا میزند. در سلام آن را با ویژگیای میدهید که نامش نام رویداد است: کلیک = ... روی دکمه میگوید وقتی دکمه کلیک شد چه بشود (در HTML این onclick است). رویدادی که نامش دو کلمه است فاصله میگیرد، مثل همهی جاهای زبان صفحه: دو کلیک، حرکت ماوس، منوی زمینه. مقدار ویژگی را به چهار شکل میتوانید بنویسید.
واردسازی دام
ناپایا تعداد := 0
تابع نامدار():
تعداد += 1
دام.تنظیم متن(دام.با شناسه("out")، "تابع نامدار، کلیک " + تعداد)
پایان
تابع بارخداد(رخداد: صحیح۶۴):
دام.تنظیم متن(دام.با شناسه("out")، "تابع با رویداد، مکان اشارهگر در x برابر " + دام.رویداد افقی(رخداد))
پایان
صفحه:
عنوان = "چهار راه برای کار با کلیک"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
سراسری: گزینشگر = "button" فاصله = "8px 14px" فضا = "0 0 8px 8px" اندازه قلم = "1rem" پایان
پاراگراف: شناسه = "out" محتوا = "یکی از دکمهها را بزنید." پایان
دکمه: کلیک = نامدار محتوا = "تابع نامدار" پایان
دکمه: کلیک = بارخداد محتوا = "تابع با رویداد" پایان
دکمه: کلیک = (): دام.تنظیم متن(دام.با شناسه("out")، "لامبدا") پایان محتوا = "لامبدا" پایان
دکمه: کلیک = "this.textContent = 'رشتهی جاوااسکریپت اینجا بود'" محتوا = "رشتهی JS" پایان
پایانهر شکل برای کاری خوب است.
- تابع نامدار که بالای بلوک
صفحه:تعریف شده است. وقتی کد از یک سطر بیشتر میشود یا دو عنصر آن را به اشتراک میگذارند از آن استفاده کنید. تابع میتواند بیپارامتر باشد، مثلنامدار، یا یک پارامتر از نوعصحیح۶۴داشته باشد، مثلبارخداد. این پارامتر خود رویداد را میگیرد و آن را به کمکتابعهایی میدهید که از رویداد میخوانند:دام.رویداد افقی(رخداد)ودام.رویداد عمودی(رخداد)برای مکان اشارهگر،دام.هدف رویداد(رخداد)برای عنصری که زده شد، ودام.جلوگیری پیش فرض(رخداد)ودام.توقف انتشار(رخداد)برای عوض کردن کاری که مرورگر بعد از این میکند. - لامبدا که همانجا به شکل
(): ... پایاننوشته میشود. برای یکی دو دستور کوتاهترین راه است. در ویژگی صفحه لامبدا پارامتر ندارد، پس رویداد را نمیبیند. وقتی رویداد لازم دارید تابع نامدار بنویسید. - رشتهی جاوااسکریپت مثل
"this.textContent = 'سلام'". این رشته همانطور که هست در HTML کپی میشود، پس درونشthisخود عنصر است وeventخود رویداد. فقط برای کارهای خیلی کوچک که کمکتابعهای سلام پوششان نمیدهند به کار میآید.
تابعهایی که به سلام مینویسید به جاوااسکریپت ترجمه میشوند و در یک اسکریپت در پایان صفحه قرار میگیرند. مرورگر تابعی را که در onclick="..." نام برده شده با جستوجو در window پیدا میکند، پس مترجم هر رویدادگیر را همانجا هم ذخیره میکند. خودتان چیزی برای آن نمینویسید، ولی دلیلش این است که رویدادگیر باید یک تابع سادهی صفحه باشد و مثلاً یک متد نباشد. نام رویدادگیر را ترجیحاً یک کلمهی ساده بگذارید. نام با نیمفاصله هم کار میکند و خواناییاش را حفظ میکند، ولی نامی که فاصله دارد را نمیشود در ویژگی رویداد نوشت.
حالت برنامه، مثلاً یک شمارنده، در یک متغیر ناپایا بالای صفحه میماند. رویدادگیر آن را عوض میکند و مقدار تازه را با دام.تنظیم متن در صفحه مینویسد. مترجم کار شما را وارسی میکند: دام.با شناسه("x") باید شناسهای را بگوید که در همان صفحه هست (خطای E138)، و رویداد باید نام تابعی را بدهد که وجود دارد (خطای E137).
رویدادگیر را همنام یک تابع آماده نکنید. مرورگر نامی را که در ویژگی میآید اول روی خود عنصر پیدا میکند، بعد روی فرمش، بعد روی سند و آخر روی پنجره. تابعی به نام clear، open، close، write، reset، submit، focus، click یا name از تابع آمادهی همان نام شکست میخورد و انگار هیچ اتفاقی نمیافتد. بدتر از این، پنجره خاصیتهای فقطخواندنی مثل closed، status، top و length دارد، و رویدادگیری با یکی از این نامها کل اسکریپت صفحه را با خطا متوقف میکند و هیچ رویدادگیری کار نمیکند. اگر نام انگلیسی میگذارید چیزی مثل clear_board یا open_menu انتخاب کنید.
اسکریپت صفحه فقط کمکتابعهای دام و کد خودتان را میشناسد. کمکتابعهایی که بیش از رساندن یک فراخوانی کار میکنند، مثل دام.تصادفی صحیح، و بستههای دیگر مثل ریاضی در آن نیستند. دام.تصادفی() عددی از ۰ تا کمتر از ۱ میدهد، پس (دام.تصادفی() * 85.0) برگردان صحیح۶۴ یک عدد درست از ۰ تا ۸۴ است.
کلیک: شمردن و کلید زدن
کلیک وقتی رخ میدهد که کاربر دکمهی اصلی ماوس را روی عنصر فشار میدهد و رها میکند، و همچنین وقتی کسی با صفحهکلید روی دکمهی فوکوسدار Enter یا فاصله میزند. پس رویداد مناسب هر چیزی است که مثل دکمه کار میکند. آن را روی یک دکمه واقعی بگذارید، نه روی جعبه: به دکمه میشود با Tab رسید و به جعبه نه.
شمارندهی زیر عددش را در شمار نگه میدارد. هر رویدادگیر یک لامبدا است که متغیر را عوض میکند و نوشتن را صدا میزند، تابع کوچکی که عدد را در سرتیتر میگذارد. دو بخش، یعنی حالت و کدی که آن را میکشد، از هم جدا میمانند، و این عادتی است که باید اول یاد بگیرید.
واردسازی دام
ناپایا شمار := 0
تابع نوشتن:
دام.تنظیم متن(دام.با شناسه("n")، "" + شمار)
پایان
صفحه:
عنوان = "شمارندهی کلیک"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" ترازمتن = وسط پایان
سرتیتر: شناسه = "n" اندازه = 1 محتوا = "0" اندازه قلم = "4rem" فضا = "0 0 12px 0" پایان
دکمه: شناسه = "plus" کلیک = (): شمار += 1 نوشتن() پایان محتوا = "+۱" فاصله = "8px 18px" اندازه قلم = "1.1rem" پایان
دکمه: شناسه = "reset" کلیک = (): شمار = 0 نوشتن() پایان محتوا = "از نو" فاصله = "8px 18px" اندازه قلم = "1.1rem" فضا = "0 8px 0 0" پایان
پایاننمونهی دوم متغیر لازم ندارد، چون خود صفحه حالت را به یاد دارد: دام.تعویض کلاس کلاسی را که عنصر ندارد اضافه میکند و اگر دارد برمیدارد. ظاهر هر حالت در CSS و در یک عنصر ظاهر سفارشی (style) نوشته شده و اسکریپت فقط کلاس را عوض میکند. ویژگی گذار (transition) باعث میشود تغییر به جای پریدن، آرام انجام شود.
واردسازی دام
صفحه:
عنوان = "چراغ"
ظاهر سفارشی: محتوا = "#room.on { background: #fde68a; color: #422006 } #room.on .bulb { background: #f59e0b }" پایان
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
جعبه:
شناسه = "room"
پس زمینه = "#1e293b"
رنگ = "#e2e8f0"
فاصله = 24
گردی کادر = 12
ترازمتن = وسط
گذار = "background 0.3s"
جعبه: کلاس = "bulb" عرض = 60 ارتفاع = 60 فضا = "0 auto 12px" پس زمینه = "#475569" گردی کادر = "50%" پایان
دکمه: شناسه = "switch" کلیک = (): دام.تعویض کلاس(دام.با شناسه("room")، "on") پایان محتوا = "کلید" فاصله = "6px 16px" پایان
پایان
پایاندو کلیک، دکمههای دیگر و منوی زمینه
دو کلیک بعد از دو کلیک پشت سر هم روی یک عنصر رخ میدهد. مرورگر همان دو رویداد کلیک معمولی را هم اول میفرستد، پس رویدادگیر کلیک روی همان عنصر دو بار اجرا میشود و بعد دو کلیک میرسد. برای یک عنصر دو کار متفاوت روی کلیک و دو کلیک نگذارید. کلیک کمکی کلیک هر دکمه به جز دکمهی اصلی است. شمارهی button در رویداد میگوید کدام: ۰ دکمهی اصلی، ۱ دکمهی وسط، ۲ دکمهی راست، و ۳ و ۴ دکمههای پیش و پس بعضی ماوسها. منوی زمینه وقتی رخ میدهد که کاربر منوی زمینه بخواهد: راست کلیک، دکمهی منو در صفحهکلید یا Shift و F10. دام.جلوگیری پیش فرض(رخداد) منوی خود مرورگر را میبندد.
واردسازی دام
ناپایا تاریخچه := ""
ناپایا سطرها := 0
تابع یادداشت(متن: رشته):
سطرها += 1
اگر سطرها بزرگتر 7:
تاریخچه = ""
سطرها = 1
پایان
تاریخچه = تاریخچه + متن + "\n"
دام.تنظیم متن(دام.با شناسه("log")، تاریخچه)
پایان
تابع کمکی(رخداد: صحیح۶۴):
یادداشت("کلیک کمکی، دکمهی " + (دام.دریافت خاصیت عددی(رخداد، "button") برگردان صحیح۶۴))
پایان
تابع زمینه(رخداد: صحیح۶۴):
دام.جلوگیری پیش فرض(رخداد)
یادداشت("منوی زمینه (منوی خود مرورگر بسته شد)")
پایان
صفحه:
عنوان = "انواع کلیک"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
جعبه:
شناسه = "pad"
کلیک = (): یادداشت("کلیک") پایان
دو کلیک = (): یادداشت("دو کلیک") پایان
کلیک کمکی = کمکی
منوی زمینه = زمینه
محتوا = "اینجا کلیک کنید، دو کلیک کنید، با دکمهی وسط یا راست کلیک کنید"
فاصله = 28
پس زمینه = "#e0f2fe"
گردی کادر = 10
انتخاب کاربر = هیچ
پایان
پاراگراف: شناسه = "log" محتوا = "هنوز چیزی نشده." فضای سفید = "pre-line" کمینه ارتفاع = "10em" پایان
پایاننمونه شمارهی دکمه را با دام.دریافت خاصیت عددی(رخداد، "button") میخواند، که هر خاصیت عددی شیء رویداد را میخواند. سیاهه هفت رویداد آخر را نگه میدارد و فضای سفید = "pre-line" هر \n را در متن به سطر تازه تبدیل میکند. انتخاب کاربر = هیچ نمیگذارد دو کلیک کلمههای جعبه را انتخاب کند.
حالا میتوانید منوی خودتان را بسازید. رویدادگیر منوی زمینه کار پیشفرض را میبندد، جعبهای پنهان را به محل اشارهگر میبرد و نشانش میدهد. هر کلیک روی ناحیه آن را میبندد و هر گزینهی منو هم همینطور.
واردسازی دام
تابع بازکردن(رخداد: صحیح۶۴):
دام.جلوگیری پیش فرض(رخداد)
منو := دام.با شناسه("menu")
دام.تنظیم سبک(منو، "left"، "" + دام.رویداد افقی(رخداد) + "px")
دام.تنظیم سبک(منو، "top"، "" + دام.رویداد عمودی(رخداد) + "px")
دام.تنظیم سبک(منو، "display"، "block")
پایان
تابع بستن():
دام.تنظیم سبک(دام.با شناسه("menu")، "display"، "none")
پایان
تابع انتخاب(گزینه: رشته):
دام.تنظیم متن(دام.با شناسه("chosen")، "انتخاب شما: " + گزینه)
بستن()
پایان
صفحه:
عنوان = "منوی دلخواه"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = 0 پایان
جعبه:
شناسه = "area"
منوی زمینه = بازکردن
کلیک = بستن
فاصله = 32
کمینه ارتفاع = "260px"
پس زمینه = "#f1f5f9"
پاراگراف: محتوا = "در هر جای این ناحیه راست کلیک کنید." پایان
پاراگراف: شناسه = "chosen" محتوا = "چیزی انتخاب نشده." پایان
پایان
جعبه:
شناسه = "menu"
نمایش = هیچ
موقعیت = ثابت
پس زمینه = سفید
کادر = "1px solid #cbd5e1"
گردی کادر = 8
سایه کادر = "0 6px 18px rgba(0,0,0,0.18)"
فاصله = 4
دکمه: شناسه = "copy" کلیک = (): انتخاب("رونوشت") پایان محتوا = "رونوشت" نمایش = بلوکی عرض = "100%" پایان
دکمه: شناسه = "rename" کلیک = (): انتخاب("تغییر نام") پایان محتوا = "تغییر نام" نمایش = بلوکی عرض = "100%" پایان
دکمه: شناسه = "delete" کلیک = (): انتخاب("حذف") پایان محتوا = "حذف" نمایش = بلوکی عرض = "100%" پایان
پایان
پایانجعبهی منو موقعیت = ثابت دارد، یعنی نسبت به پنجره جا میگیرد، پس left و top را میشود مستقیم از مکان اشارهگر یعنی دام.رویداد افقی و دام.رویداد عمودی ساخت. این دو از گوشهی بالا و چپ پنجره اندازه گرفته میشوند، و جعبهی ثابت هم از همان گوشه حساب میکند.
منوی زمینهی دلخواه را فقط جایی بگذارید که چیزی اضافه میکند، مثل یک ویرایشگر یا فهرست پروندهها. راست کلیکی که کار بهدردبخوری نمیکند، یا منوی عادی را با غلطیاب و رونوشتش پنهان میکند، کاربر را اذیت میکند. هر کار منو را از راه دیگری هم در دسترس بگذارید، چون صفحهی لمسی و صفحهکلید راست کلیک ندارند.
فشردن، رها کردن و حرکت
فشردن ماوس لحظهای رخ میدهد که دکمه پایین میرود، رها کردن ماوس وقتی بالا میآید، و کلیک چیزی است که مرورگر از یک فشردن و رها کردن روی همان عنصر میسازد. حرکت ماوس تا وقتی اشارهگر حرکت میکند بارها و بارها در ثانیه رخ میدهد، پس رویدادگیرش را کوتاه نگه دارید.
مکانی که در رویداد هست از پنجره اندازه گرفته شده، ولی بیشتر وقتها آن را از یک جعبه، مثلاً بوم نقاشی، میخواهید. از جعبه بپرسید کجاست، با getBoundingClientRect، و left و top آن را کم کنید. در سلام این میشود دام.فراخوان(جعبه، "getBoundingClientRect") برای مستطیل و دام.دریافت خاصیت عددی(مستطیل، "left") برای هر عدد. نمونهی اول مکان را درون جعبهی سبز نشان میدهد و یک نقطه را با آن میبرد. نقطه رویدادهای اشارهگر = هیچ دارد تا هیچوقت سر راه اشارهگر نباشد.
واردسازی دام
تابع حرکت(رخداد: صحیح۶۴):
زمین := دام.با شناسه("pad")
مستطیل := دام.فراخوان(زمین، "getBoundingClientRect")
ایکس := (دام.رویداد افقی(رخداد) - دام.دریافت خاصیت عددی(مستطیل، "left")) برگردان صحیح۶۴
ایگرگ := (دام.رویداد عمودی(رخداد) - دام.دریافت خاصیت عددی(مستطیل، "top")) برگردان صحیح۶۴
دام.تنظیم متن(دام.با شناسه("pos")، "x " + ایکس + "، y " + ایگرگ)
نقطه := دام.با شناسه("dot")
دام.تنظیم سبک(نقطه، "left"، "" + ایکس + "px")
دام.تنظیم سبک(نقطه، "top"، "" + ایگرگ + "px")
پایان
صفحه:
عنوان = "مکان اشارهگر"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
جعبه:
شناسه = "pad"
حرکت ماوس = حرکت
موقعیت = نسبی
ارتفاع = 180
پس زمینه = "#ecfccb"
گردی کادر = 10
نشانگر = نشانهگیر
سرریز = پنهان
جعبه: شناسه = "dot" موقعیت = مطلق عرض = 12 ارتفاع = 12 فضا = "-6px 0 0 -6px" گردی کادر = "50%" پس زمینه = "#15803d" رویدادهای اشارهگر = هیچ پایان
پایان
پاراگراف: شناسه = "pos" محتوا = "ماوس را روی ناحیهی سبز حرکت دهید." پایان
پایاننمونهی بعد نقاشی میکند. یک متغیر ناپایا میگوید دکمه پایین است یا نه. فشردن ماوس آن را روشن میکند و اولین نقطه را میگذارد، حرکت ماوس تا وقتی روشن است نقطه میگذارد و رها کردن ماوس خاموشش میکند. خروج ماوس هم خاموشش میکند، چون دکمهای که بیرون از جعبه رها شود هرگز به جعبه نمیرسد. هر نقطه عنصر تازهای است که با دام.بساز ساخته و با دام.افزودن اضافه میشود، و شکل نقطهها از یک قاعدهی CSS در عنصر ظاهر سفارشی میآید.
واردسازی دام
ناپایا میکشد := نادرست
تابع شروع(رخداد: صحیح۶۴):
میکشد = درست
کشیدن(رخداد)
پایان
تابع توقف:
میکشد = نادرست
پایان
تابع کشیدن(رخداد: صحیح۶۴):
اگر میکشد:
مستطیل := دام.فراخوان(دام.با شناسه("board")، "getBoundingClientRect")
نقطه := دام.بساز("div")
دام.تنظیم ویژگی(نقطه، "class"، "dot")
دام.تنظیم سبک(نقطه، "left"، "" + (دام.رویداد افقی(رخداد) - دام.دریافت خاصیت عددی(مستطیل، "left")) + "px")
دام.تنظیم سبک(نقطه، "top"، "" + (دام.رویداد عمودی(رخداد) - دام.دریافت خاصیت عددی(مستطیل، "top")) + "px")
دام.افزودن(دام.با شناسه("board")، نقطه)
پایان
پایان
تابع پاکسازی:
دام.تنظیم اچ تی ام ال(دام.با شناسه("board")، "")
پایان
صفحه:
عنوان = "نقاشی"
ظاهر سفارشی: محتوا = ".dot { position: absolute; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: #7c3aed; pointer-events: none }" پایان
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
جعبه:
شناسه = "board"
فشردن ماوس = شروع
حرکت ماوس = کشیدن
رها کردن ماوس = توقف
خروج ماوس = توقف
موقعیت = نسبی
ارتفاع = 200
پس زمینه = "#faf5ff"
کادر = "2px dashed #c4b5fd"
گردی کادر = 10
نشانگر = نشانهگیر
سرریز = پنهان
انتخاب کاربر = هیچ
پایان
دکمه: شناسه = "clear" کلیک = پاکسازی محتوا = "پاک کن" فضا = "10px 0 0 0" فاصله = "6px 14px" پایان
پایاناین نقطه میگذارد، پس کشیدن تند فاصله باقی میگذارد. برای خط یکدست از بوم (canvas) استفاده کنید و به web/canvas نگاه کنید. الگوی فشردن، حرکت و رها کردن برای بردن یک عنصر با دست هم همین است، و درسهای بعد روی آن بنا میشوند.
ورود و خروج، عبور و بیرون رفتن
چهار رویداد میگویند اشارهگر آمده یا رفته، و دو جفتشان فرق دارند. ورود ماوس و خروج ماوس فقط برای همان عنصری رخ میدهند که روی آن گذاشتهاید: وقتی اشارهگر برای اولین بار وارد عنصر میشود، و وقتی کلاً از آن بیرون میرود. جابهجایی میان عنصر و فرزندانش حساب نمیشود. عبور ماوس و بیرون رفتن ماوس برای فرزندان هم رخ میدهند، چون از آنها بالا میآیند: رفتن از جعبهی بیرونی روی جعبهی درونی، برای جعبهی بیرونی یک بیرون رفتن میفرستد و یک عبور هم که از درونی بالا میآید. هر دو را امتحان کنید و شمارندهها را ببینید. جعبهی راست میگوید ورود 1، خروج 0 تا وقتی روی آن یا مربع درونیاش هستید، و جعبهی چپ هر قدم را میشمارد.
واردسازی دام
ناپایا ورودها := 0
ناپایا خروجها := 0
ناپایا عبورها := 0
ناپایا بیرونرفتنها := 0
تابع نوشتنالف:
دام.تنظیم متن(دام.با شناسه("count-a")، "ورود " + ورودها + "، خروج " + خروجها)
پایان
تابع نوشتنب:
دام.تنظیم متن(دام.با شناسه("count-b")، "عبور " + عبورها + "، بیرون رفتن " + بیرونرفتنها)
پایان
صفحه:
عنوان = "ورود و خروج"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
سراسری: گزینشگر = ".zone" موقعیت = نسبی ارتفاع = 90 عرض = 220 پس زمینه = "#dbeafe" گردی کادر = 10 فاصله = 10 اندازه جعبه = "border-box" پایان
سراسری: گزینشگر = ".inner" موقعیت = مطلق چپ = 10 بالا = 10 عرض = 70 ارتفاع = 70 پس زمینه = "#2563eb" رنگ = سفید گردی کادر = 8 ترازمتن = وسط پایان
جعبه:
نمایش = فلکس
شکاف = 24
پیچش آرایش = پیچیده
جعبه:
سرتیتر: اندازه = 3 محتوا = "ورود و خروج" فضا = "0 0 8px 0" پایان
جعبه:
شناسه = "a" کلاس = "zone" محتوا = "بیرونی"
ورود ماوس = (): ورودها += 1 نوشتنالف() پایان
خروج ماوس = (): خروجها += 1 نوشتنالف() پایان
جعبه: شناسه = "a-inner" کلاس = "inner" محتوا = "درونی" پایان
پایان
پاراگراف: شناسه = "count-a" محتوا = "ورود 0، خروج 0" پایان
پایان
جعبه:
سرتیتر: اندازه = 3 محتوا = "عبور و بیرون رفتن" فضا = "0 0 8px 0" پایان
جعبه:
شناسه = "b" کلاس = "zone" محتوا = "بیرونی"
عبور ماوس = (): عبورها += 1 نوشتنب() پایان
بیرون رفتن ماوس = (): بیرونرفتنها += 1 نوشتنب() پایان
جعبه: شناسه = "b-inner" کلاس = "inner" محتوا = "درونی" پایان
پایان
پاراگراف: شناسه = "count-b" محتوا = "عبور 0، بیرون رفتن 0" پایان
پایان
پایان
پایانبیشتر وقتها ورود و خروج را میخواهید: منویی که تا وقتی اشارهگر رویش است باز میماند، یک راهنمای شناور، یک برجستهسازی. عبور و بیرون رفتن را وقتی بگذارید که واقعاً از هر فرزند خبر بخواهید، مثلاً برای روشن کردن همان خانهی جدول که اشارهگر به آن میرسد.
اینجا راهنمایی را میبینید که پشت اشارهگر میآید. ورود ماوس آن را با متن درست نشان میدهد، حرکت ماوس جابهجایش میکند و خروج ماوس پنهانش میکند. راهنما ۱۴ و ۱۸ پیکسل از اشارهگر فاصله دارد، چون راهنمایی که زیر اشارهگر باشد رویدادهای آن را میگیرد و سوسو میزند. رویدادهای اشارهگر = هیچ هم از همین مشکل جلوگیری میکند.
واردسازی دام
تابع نمایاندن(متن: رشته):
راهنما := دام.با شناسه("tip")
دام.تنظیم متن(راهنما، متن)
دام.تنظیم سبک(راهنما، "display"، "block")
پایان
تابع پنهان:
دام.تنظیم سبک(دام.با شناسه("tip")، "display"، "none")
پایان
تابع دنبالکردن(رخداد: صحیح۶۴):
راهنما := دام.با شناسه("tip")
دام.تنظیم سبک(راهنما، "left"، "" + (دام.رویداد افقی(رخداد) + 14.0) + "px")
دام.تنظیم سبک(راهنما، "top"، "" + (دام.رویداد عمودی(رخداد) + 18.0) + "px")
پایان
صفحه:
عنوان = "راهنمای شناور"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
سراسری: گزینشگر = "button" فاصله = "8px 14px" فضا = "0 0 0 8px" اندازه قلم = "1rem" پایان
دکمه: شناسه = "save" محتوا = "ذخیره" ورود ماوس = (): نمایاندن("پرونده را ذخیره میکند") پایان حرکت ماوس = دنبالکردن خروج ماوس = پنهان پایان
دکمه: شناسه = "open" محتوا = "باز کردن" ورود ماوس = (): نمایاندن("پروندهای را از دیسک باز میکند") پایان حرکت ماوس = دنبالکردن خروج ماوس = پنهان پایان
دکمه: شناسه = "share" محتوا = "اشتراک" ورود ماوس = (): نمایاندن("پیوندی را برای دوستتان میفرستد") پایان حرکت ماوس = دنبالکردن خروج ماوس = پنهان پایان
جعبه: شناسه = "tip" نمایش = هیچ موقعیت = ثابت پس زمینه = "#0f172a" رنگ = سفید فاصله = "4px 10px" گردی کادر = 6 اندازه قلم = "0.85rem" رویدادهای اشارهگر = هیچ پایان
پایانهدف رویداد و حباب شدن
وقتی روی نوشتهی داخل دکمهای داخل جعبهای کلیک میکنید، رویداد اول به نوشته میرسد و بعد حباب میشود: به دکمه پیشنهاد میشود، بعد به جعبه، بعد بالاتر تا خود صفحه. هر عنصری در این مسیر که رویدادگیر کلیک دارد آن را اجرا میکند. درون رویدادگیر، دام.هدف رویداد(رخداد) عنصری است که واقعاً زده شده، حتی وقتی رویدادگیر روی یک پدر گذاشته شده باشد. به همین دلیل یک رویدادگیر روی یک فهرست میتواند به صد عنصر سرویس بدهد. دام.توقف انتشار(رخداد) را صدا بزنید و رویداد جلوتر نمیرود.
واردسازی دام
تابع بیرونی(رخداد: صحیح۶۴):
کی := دام.دریافت ویژگی(دام.هدف رویداد(رخداد)، "id")
دام.تنظیم متن(دام.با شناسه("log")، "جعبهی بیرونی کلیکی از این عنصر شنید: " + کی)
پایان
تابع ایستا(رخداد: صحیح۶۴):
دام.توقف انتشار(رخداد)
دام.تنظیم متن(دام.با شناسه("log")، "دکمهی توقفدهنده کلیک را برای خودش نگه داشت.")
پایان
صفحه:
عنوان = "حباب شدن رویداد"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
سراسری: گزینشگر = "button" فاصله = "8px 14px" فضا = "0 0 0 8px" اندازه قلم = "1rem" پایان
جعبه:
شناسه = "outer-box"
کلیک = بیرونی
فاصله = 20
پس زمینه = "#ede9fe"
گردی کادر = 10
پاراگراف: محتوا = "جعبهی بیرونی" فضا = "0 0 10px 0" پایان
دکمه: شناسه = "plain" محتوا = "دکمهی ساده" پایان
دکمه: شناسه = "stopper" کلیک = ایستا محتوا = "دکمهی توقفدهنده" پایان
تکه: شناسه = "label" محتوا = "یا این نوشته" پایان
پایان
پاراگراف: شناسه = "log" محتوا = "روی چیزی کلیک کنید." پایان
پایانجعبهی بیرونی یک رویدادگیر دارد. شناسهی هدف را با دام.دریافت ویژگی میخواند و مینویسد. دکمهی ساده رویدادگیر خودش را ندارد و باز هم به جعبه گزارش میدهد، و نوشته هم همینطور. دکمهی توقفدهنده رویدادگیری دارد که رویداد را متوقف میکند، پس جعبه هیچوقت از آن خبردار نمیشود. بیدلیل انتشار را متوقف نکنید: کد دیگری که بالاتر گوش میدهد، مثلاً منویی که با هر کلیک میخواهد بسته شود، برای آن عنصر کار نمیکند.
بیشتر رویدادها حباب میشوند. چند رویداد نه، و ورود ماوس و خروج ماوس از همین درس جزو آنها هستند. به همین دلیل با عبور و بیرون رفتن بالا متفاوت میشمارند.
چرخ ماوس
چرخ ماوس وقتی رخ میدهد که چرخ میچرخد یا دو انگشت روی صفحهی لمسی میلغزند. خاصیت deltaY رویداد وقتی منفی است که کاربر رو به بالا و از خودش دور میچرخاند، و وقتی مثبت است که رو به پایین. بهطور پیشفرض چرخ صفحه را پیمایش میکند. رویدادگیری که دام.جلوگیری پیش فرض(رخداد) را صدا بزند آن را لغو میکند، که در یک نقشه یا نمایشگر تصویر همان چیزی است که میخواهید و در یک صفحهی معمولی نباید بکنید. بیشتر مرورگرها رویدادگیر چرخ را روی پنجره، سند و بدنه غیرفعال (passive) میگیرند و لغو را نادیده میگیرند، پس رویدادگیر را روی یک عنصر بگذارید، مثل نمونه.
واردسازی دام
ناپایا بزرگنمایی := 1.0
تابع چرخش(رخداد: صحیح۶۴):
دام.جلوگیری پیش فرض(رخداد)
اگر دام.دریافت خاصیت عددی(رخداد، "deltaY") کوچکتر 0.0:
بزرگنمایی = بزرگنمایی * 1.1
وگرنه:
بزرگنمایی = بزرگنمایی / 1.1
پایان
اگر بزرگنمایی بزرگتر 3.0:
بزرگنمایی = 3.0
پایان
اگر بزرگنمایی کوچکتر 0.5:
بزرگنمایی = 0.5
پایان
درصد := (بزرگنمایی * 100.0) برگردان صحیح۶۴
دام.تنظیم سبک(دام.با شناسه("card")، "transform"، "scale(" + بزرگنمایی + ")")
دام.تنظیم متن(دام.با شناسه("level")، "بزرگنمایی " + درصد + "٪")
پایان
صفحه:
عنوان = "بزرگنمایی با چرخ ماوس"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
جعبه:
شناسه = "stage"
چرخ ماوس = چرخش
ارتفاع = 200
سرریز = پنهان
پس زمینه = "#f1f5f9"
گردی کادر = 10
نمایش = فلکس
ترازعمودی = وسط
چینش = وسط
جعبه: شناسه = "card" محتوا = "چرخ ماوس را روی من بچرخانید" فاصله = 24 پس زمینه = "#0f766e" رنگ = سفید گردی کادر = 10 پایان
پایان
پاراگراف: شناسه = "level" محتوا = "بزرگنمایی 100٪" پایان
پایانرویدادگیر در هر قدم بزرگنمایی را ۱٫۱ برابر یا تقسیم بر ۱٫۱ میکند و با دو اگر ساده آن را میان ۰٫۵ و ۳ نگه میدارد، چون اسکریپت صفحه ریاضی ندارد. نتیجه به شکل scale(...) در transform نوشته میشود. جعبهی بزرگشونده درون صحنهای با سرریز = پنهان است، پس هرچه از صحنه بیرون بزند بریده میشود و صفحه تکان نمیخورد.
کنار هم گذاشتن: بازی کلیک
این بازی همهی چیزهایی را که دیدید به کار میبرد. مربع قرمز رویدادگیر کلیک دارد که یک موفقیت میشمارد و مربع را به جای تصادفی میبرد. زمین زرد دور آن هم رویدادگیر کلیک دارد که یک خطا میشمارد. کلیک روی مربع تا زمین حباب میشود و خطا هم حساب میشد، پس رویدادگیر مربع اول دام.توقف انتشار(رخداد) را صدا میزند. مکانها به درصد داده شدهاند، پس بازی در هر پهنایی کار میکند.
واردسازی دام
ناپایا برخوردها := 0
ناپایا خطاها := 0
تابع امتیاز:
دام.تنظیم متن(دام.با شناسه("score")، "موفق " + برخوردها + "، ناموفق " + خطاها)
پایان
تابع جابجایی:
هدف := دام.با شناسه("target")
دام.تنظیم سبک(هدف، "left"، "" + ((دام.تصادفی() * 85.0) برگردان صحیح۶۴) + "%")
دام.تنظیم سبک(هدف، "top"، "" + ((دام.تصادفی() * 75.0) برگردان صحیح۶۴) + "%")
پایان
تابع زدن(رخداد: صحیح۶۴):
دام.توقف انتشار(رخداد)
برخوردها += 1
امتیاز()
جابجایی()
پایان
تابع خطا:
خطاها += 1
امتیاز()
پایان
صفحه:
عنوان = "مربع را بگیر"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
جعبه:
شناسه = "field"
کلیک = خطا
موقعیت = نسبی
ارتفاع = 220
پس زمینه = "#fef9c3"
گردی کادر = 10
سرریز = پنهان
نشانگر = نشانهگیر
جعبه: شناسه = "target" کلیک = زدن موقعیت = مطلق چپ = "40%" بالا = "30%" عرض = 44 ارتفاع = 44 پس زمینه = "#dc2626" گردی کادر = 8 نشانگر = اشارهگر پایان
پایان
پاراگراف: شناسه = "score" محتوا = "موفق 0، ناموفق 0" پایان
پایانوقتی CSS ابزار بهتری است
پیش از اینکه برای عوض کردن ظاهر چیزی عبور ماوس و بیرون رفتن ماوس بنویسید، یادتان باشد که CSS خودش از پس آن برمیآید. سبکی با پیشوند اشاره (hover) تا وقتی اشارهگر روی عنصر است اعمال میشود و مرورگر خودش آن را برمیدارد، بیآنکه کدی باشد که حالتی را فراموش کند. دو دکمهی زیر یکسان به نظر میآیند. اولی اشاره پس زمینه دارد و هر رنگ را یک بار میگوید. دومی دو رویدادگیر لازم دارد، رنگها را در اسکریپت تکرار میکند و اگر اسکریپت بارگذاری نشود هیچ کاری نمیکند. CSS همچنین سبک اشاره را در هر حالتی خودش برمیدارد، در حالی که اسکریپت باید همهی راههایی را که اشارهگر میتواند عنصر را ترک کند به خاطر بسپارد.
واردسازی دام
صفحه:
عنوان = "اشاره"
سراسری: گزینشگر = "body" خانواده قلم = "Tahoma, system-ui, sans-serif" فضا = "1.5rem" پایان
سراسری: گزینشگر = "button" فاصله = "10px 18px" فضا = "0 0 0 12px" اندازه قلم = "1rem" کادر = "none" گردی کادر = 8 رنگ = سفید پایان
دکمه:
شناسه = "css"
محتوا = "اشاره با CSS"
پس زمینه = "#0f766e"
گذار = "background 0.2s"
اشاره پس زمینه = "#115e59"
پایان
دکمه:
شناسه = "js"
محتوا = "اشاره با JS"
پس زمینه = "#0f766e"
عبور ماوس = (): دام.تنظیم سبک(دام.با شناسه("js")، "background"، "#115e59") پایان
بیرون رفتن ماوس = (): دام.تنظیم سبک(دام.با شناسه("js")، "background"، "#0f766e") پایان
پایان
پاراگراف: محتوا = "هر دو یک شکلاند. فقط اولی به اسکریپت نیاز ندارد." پایان
پایانرویداد ماوس را وقتی بگذارید که چیزی باید اتفاق بیفتد: عددی عوض شود، جعبهای ظاهر شود، درخواستی فرستاده شود. CSS را وقتی بگذارید که صفحه فقط باید جور دیگری دیده شود. درسهای CSS دوباره سراغ اشاره، تمرکز و فشردن میروند.
صفحهی لمسی اشارهگری ندارد که رویش اشاره کند. راهنما یا منویی که فقط با اشاره ظاهر شود برای گوشی در دسترس نیست، پس یک راه کلیک یا لمس هم بگذارید.
مرجع: همهی رویدادهای ماوس
هر سطر ویژگی، نام ویژگی HTML که از آن ساخته میشود و زمان رخ دادن رویداد را میدهد. نمونهها را مترجم وارسی کرده است. جایی که رویدادگیر خود رویداد را لازم دارد نمونه از رشتهی جاوااسکریپت استفاده میکند، چون نمونهی چسباندهشده تابع نامداری برای صدا زدن ندارد. در کد خودتان تابع نامداری با پارامتر صحیح۶۴ بنویسید، مثل نمونههای بالا.
| ویژگی | چه وقت رخ میدهد | نمونه |
|---|---|---|
کلیکclick onclick | وقتی دکمهی اصلی ماوس روی عنصر فشرده و رها شود رخ میدهد، و وقتی کسی با صفحهکلید روی دکمهی فوکوسدار Enter یا فاصله بزند. رویداد هر چیزی است که مثل دکمه کار میکند. | دکمه: کلیک = (): دام.تنظیم متن(دام.با شناسه("out")، "کلیک شد") پایان محتوا = "مرا بزنید" پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
دو کلیکdouble click ondblclick | بعد از دو کلیک سریع روی یک عنصر رخ میدهد. دو رویداد کلیک معمولی اول میآیند، پس رویدادگیر کلیک همان عنصر دو بار اجرا میشود و بعد این. | جعبه: دو کلیک = (): دام.تنظیم متن(دام.با شناسه("out")، "دو کلیک شد") پایان محتوا = "اینجا دو کلیک کنید" فاصله = 20 پس زمینه = "#e0f2fe" انتخاب کاربر = هیچ پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
کلیک کمکیaux click onauxclick | وقتی دکمهای جز دکمهی اصلی کلیک شود رخ میدهد. خاصیت button رویداد میگوید کدام: ۱ دکمهی وسط، ۲ دکمهی راست، و ۳ و ۴ دکمههای پیش و پس بعضی ماوسها. | جعبه: کلیک کمکی = (): دام.تنظیم متن(دام.با شناسه("out")، "دکمهی دیگر") پایان محتوا = "اینجا با دکمهی وسط کلیک کنید" فاصله = 20 پس زمینه = "#fef3c7" پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
منوی زمینهcontext menu oncontextmenu | وقتی کاربر منوی زمینه بخواهد رخ میدهد: راست کلیک، دکمهی منو در صفحهکلید یا Shift و F10. دام.جلوگیری پیش فرض(رخداد) منوی خود مرورگر را میبندد تا صفحه منوی خودش را نشان دهد. | جعبه: منوی زمینه = "event.preventDefault(); this.textContent = 'منوی شما اینجا میآید'" محتوا = "اینجا راست کلیک کنید" فاصله = 20 پس زمینه = "#fce7f3" پایان |
فشردن ماوسmouse down onmousedown | لحظهای رخ میدهد که دکمهی ماوس روی عنصر پایین میرود، پیش از رها شدن. جای شروع کشیدن و نقاشی است. | جعبه: فشردن ماوس = (): دام.تنظیم متن(دام.با شناسه("out")، "دکمه پایین است") پایان رها کردن ماوس = (): دام.تنظیم متن(دام.با شناسه("out")، "دکمه رها شد") پایان محتوا = "فشار دهید و نگه دارید" فاصله = 20 پس زمینه = "#e0e7ff" انتخاب کاربر = هیچ پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
رها کردن ماوسmouse up onmouseup | وقتی دکمهی ماوس بالا میآید و اشارهگر روی عنصر است رخ میدهد. دکمهای که بیرون از عنصر اولیه رها شود به عنصر زیر اشارهگر گزارش میشود، نه به اولی. | جعبه: رها کردن ماوس = (): دام.تنظیم متن(دام.با شناسه("out")، "اینجا رها شد") پایان محتوا = "دکمه را روی من رها کنید" فاصله = 20 پس زمینه = "#dcfce7" انتخاب کاربر = هیچ پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
حرکت ماوسmouse move onmousemove | تا وقتی اشارهگر روی عنصر حرکت میکند بارها و بارها در ثانیه رخ میدهد. رویدادگیر را کوتاه نگه دارید. مکان با دام.رویداد افقی(رخداد) و دام.رویداد عمودی(رخداد) خوانده میشود و از پنجره اندازه گرفته شده است. | جعبه: حرکت ماوس = "this.textContent = event.clientX + '، ' + event.clientY" محتوا = "روی من حرکت کنید" فاصله = 24 پس زمینه = "#dcfce7" پایان |
ورود ماوسmouse enter onmouseenter | یک بار رخ میدهد، وقتی اشارهگر وارد عنصر میشود. حباب نمیشود و وقتی اشارهگر میان عنصر و فرزندانش جابهجا میشود تکرار نمیشود، پس برای اثرهای اشاره که با اسکریپت ساخته میشوند انتخاب درست است. | جعبه: ورود ماوس = (): دام.تنظیم متن(دام.با شناسه("out")، "وارد شد") پایان محتوا = "اشارهگر را روی من ببرید" فاصله = 20 پس زمینه = "#e0f2fe" پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
خروج ماوسmouse leave onmouseleave | یک بار رخ میدهد، وقتی اشارهگر از عنصر و همهی فرزندانش بیرون میرود. حباب نمیشود. | جعبه: خروج ماوس = (): دام.تنظیم متن(دام.با شناسه("out")، "بیرون رفت") پایان محتوا = "اشارهگر را روی من ببرید و بعد دور کنید" فاصله = 20 پس زمینه = "#e0f2fe" پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
عبور ماوسmouse over onmouseover | وقتی اشارهگر روی عنصر یا یکی از فرزندانش بیاید رخ میدهد. حباب میشود، پس رویدادگیر پدر از هر فرزند خبر میگیرد. با دام.هدف رویداد(رخداد) میتوانید ببینید کدام فرزند بوده است. | جعبه: عبور ماوس = (): دام.تنظیم متن(دام.با شناسه("out")، "عبور کرد") پایان محتوا = "اشارهگر را روی من ببرید" فاصله = 20 پس زمینه = "#fef3c7" پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
بیرون رفتن ماوسmouse out onmouseout | وقتی اشارهگر از عنصر یا از یکی از فرزندانش برود رخ میدهد. حباب میشود، و وقتی اشارهگر از عنصر روی فرزند خودش میرود هم رخ میدهد. | جعبه: بیرون رفتن ماوس = (): دام.تنظیم متن(دام.با شناسه("out")، "بیرون رفت") پایان محتوا = "اشارهگر را روی من ببرید و بعد دور کنید" فاصله = 20 پس زمینه = "#fef3c7" پایان
پاراگراف: شناسه = "out" محتوا = "-" پایان |
چرخ ماوسwheel onwheel | وقتی چرخ ماوس میچرخد یا دو انگشت روی صفحهی لمسی میلغزند رخ میدهد. خاصیت deltaY رویداد هنگام چرخاندن رو به بالا منفی و رو به پایین مثبت است. دام.جلوگیری پیش فرض(رخداد) جلوی پیمایش صفحه را میگیرد. | جعبه: چرخ ماوس = "event.preventDefault(); this.textContent = event.deltaY < 0 ? 'بالا' : 'پایین'" محتوا = "چرخ ماوس را اینجا بچرخانید" فاصله = 24 پس زمینه = "#ede9fe" پایان |
خودتان امتحان کنید
- شمارنده را طوری عوض کنید که دو کلیک ده تا اضافه کند و یک کلیک یکی. شمارنده را موقع دو کلیک ببینید: چه نشان میدهد؟ چرا؟
- تختهی نقاشی را طوری کنید که رنگش به دکمه بستگی داشته باشد: دکمهی چپ بنفش، دکمهی وسط سبز. از
فشردن ماوسو شمارهیbuttonکمک بگیرید. - به بازی کلیک یک «امتیاز» اضافه کنید که بشمارد چند بار پشت سر هم بیخطا زدهاید، و آن را در پاراگراف نشان دهید.
- به نمونهی چراغ دکمهی دومی بدهید و با یک تابع نامدار کاری کنید که هر دو دکمه یک چراغ را کنترل کنند.