مقدمه ای بر رویدادها در جاوا اسکریپت — راهنمای کاربردی
رویدادها، اقدامات یا رخدادهایی هستند که در سیستمی که برای آن برنامهنویسی میکنیم، اتفاق میافتند. در این حالت سیستم در مورد رویدادها به برنامه اطلاعاتی میدهد و شما به عنوان برنامهنویس باید برای پاسخ به این رویدادها، در صورت نیاز نوعی واکنش تعریف کنید. برای نمونه اگر کاربر روی یک دکمه در صفحه وب کلیک کرد، ممکن است لازم باشد به این اقدام با نمایش دادن یک کادر اطلاعات پاسخ دهیم. در این مقاله، برخی از مفاهیم مهم پیرامون رویدادها را مورد بررسی قرار داده و به طرز کار آنها در مرورگرها میپردازیم. این یک مقاله جامع محسوب نمیشود و صرفاً میخواهیم با مبانی رویدادها آشنا شویم.
پیشنیازها
- سواد مقدماتی رایانه
- درکی ابتدایی از HTML و CSS
- آشنایی مقدماتی با جاوا اسکریپت
هدف از این مقاله درک مبانی نظری رویدادها، طرز کارشان در مرورگرها، و تفاوت آنها در محیطهای برنامهنویسی مختلف است. برای مشاهده قسمت قبلی این مجموعه مطلب آموزش جاوا اسکریپت روی لینک زیر کلیک کنید:
مقدمهای بر رویدادها
همان طور که پیشتر اشاره کردیم، «رویدادها» (Events) اقدامها یا رخدادهایی هستند که در سیستمی که برایش برنامهنویسی میکنیم، پیش میآیند و سیستم در زمان رخداد این حالت، نوعی سیگنال ارسال میکند و ساز و کاری ارائه میدهد که میتوان آن رویداد را به صورت خودکار دریافت کرد. برای مثال در زمان اتفاق افتادن آن رویداد نوعی کد اجرا میشود. برای مثال در یک فرودگاه زمانی که باند برای پرواز یک هواپیما باز میشود، یک سیگنال به خلبان ارسال میشود و در نتیجه وی میتواند هواپیما را به پرواز دربیاورد.
در مورد وب، رویدادها درون پنجره مرورگر ایجاد میشوند و در اغلب موارد به آیتم خاصی که به آن مربوط است الصاق شدهاند. در نتیجه رویداد میتواند متعلق به یک عنصر منفرد باشد و یا به مجموعهای از عناصر تعلق داشته باشد. همچنین رویداد میتواند به سند بارگذاری شده در برگه جاری و یا کل پنجره مرورگر مربوط باشد. انواع بسیار مختلفی از رویدادها هستند که میتوانند رخ دهند. در ادامه مثالهایی از برخی رویدادها را ارائه کردهایم:
- کاربر روی یک عنصر خاص کلیک میکند یا کرسر را روی یک عنصر میبرد.
- کاربر یک کلید را روی صفحه کلید میفشارد.
- کاربر پنجره مرورگر را تغییر اندازه داده یا آن را میبندد.
- مراحل بارگذاری یک صفحه وب پایان میپذیرد.
- یک فرم تحویل داده میشود.
- یک ویدئو پخش یا متوقف میشود و یا به پایان میرسد.
- یک خطا رخ میدهد.
احتمالاً با مطالعه فهرست فوق متوجه شدهاید که یک فهرست طولانی از رویدادها وجود دارند که میتوان به آنها پاسخ داد.
هر رویداد دارای یک «دستگیره رویداد» (Event handler) مربوطه است که در واقع یک بلوک کد به حساب میآید. این بلوک کد که در اغلب موارد تابع جاوا اسکریپت تعریف شده از سوی کاربر است، در زمان اتفاق افتادن رویداد اجرا میشود. هنگامی که چنین بلوک کدی را چنان تعریف کنیم که در پاسخ به اتفاق افتادن یک رویداد اجرا شود، گفته میشود که یک دستگیره رویداد ثبت شده است. دقت کنید که دستگیرههای رویداد در برخی موارد «شنونده رویداد» (Event Listener) نیز نامیده میشوند. این دو نام با توجه به مقاصدی که ما دنبال میکنیم به جای هم قابل استفاده هستند؛ اما اگر بخواهیم روشنتر صحبت کنیم این دو با یکدیگر همکاری دارند. شنونده منتظر اتفاق افتادن یک رویداد است و دستگیره، کدی است که در پاسخ به اتفاق افتادن رویداد اجرا میشود.
نکته: لازم به ذکر است که رویدادهای وب بخشی از هسته اصلی زبان جاوا اسکریپت نیستند و به عنوان بخشی از API-های جاوا اسکریپت در مرورگر تعریف میشوند.
یک مثال ساده
در ادامه یک مثال ساده را مورد بررسی قرار میدهیم، تا آن چه را تا به اینجا آموختهایم مرور کنیم. ما در بخشهای قبلی این سری مطالب آموزشی با رویدادها و دستگیرههای رویداد در مثالهای فراوانی آشنا شدهایم؛ اما جهت مرور دوباره یک مثال دیگر را نیز بررسی میکنیم. در کد زیر یک عنصر <button> داریم که وقتی فشرده شود، پسزمینه صفحه به یک رنگ تصادفی تغییر مییابد:
1<button>Change color</button>
کد جاوا اسکریپت به صورت زیر است:
1var btn = document.querySelector('button');
2
3function random(number) {
4 return Math.floor(Math.random()*(number+1));
5}
6
7btn.onclick = function() {
8 var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
9 document.body.style.backgroundColor = rndCol;
10}
ما در این کد با استفاده از تابع ()Document.querySelector یک ارجاع به دکمه درون یک متغیر ایجاد میکنیم که btn نام دارد. همچنین یک تابع تعریف میکنیم که یک عدد تصادفی بازگشت میدهد. بخش سوم کد همان دستگیره رویداد است. متغیر btn به یک عنصر <button> اشاره دارد و این نوع شیء، چند نوع رویداد دارد که میتواند روی آنها اجرا شود. از این رو دستگیرههای رویدادی ارائه شدهاند. ما منتظریم که یک رویداد کلیک شدن رخ دهد و به این منظور خصوصیت دستگیره رویداد onclick را برابر با یک «تابع بینام» (anonymous function) قرار میدهیم که شامل کدی است که یک رنگ تصادفی RGB تولید کرده و آن را به صورت رنگ پسزمینه <body> قرار میدهد.
این کد هر زمان که رویداد کلیک روی عنصر <button> رخ دهد، یعنی هنگامی که کاربر روی آن کلیک کند، اجرا خواهد شد.
رویدادها صرفاً در مورد صفحههای وب نیستند
نکته دیگری که باید توجه داشته باشید این است که رویدادها اختصاص به جاوا اسکریپت ندارند و اغلب زبانهای برنامهنویسی دیگر نوعی مدل رویداد دارند؛ هر چند روشی که آنها استفاده میکنند در اغلب موارد متفاوت از جاوا اسکریپت است. در واقع مدل رویداد در جاوا اسکریپت برای صفحههای وب از مدل رویداد برای جاوا اسکریپت که در محیطهای دیگر استفاده میشود نیز متفاوت است.
برای نمونه Node.js یک محیط اجرای بسیار محبوب جاوا اسکریپت است که به توسعهدهندگان امکان میدهد تا از جاوا اسکریپت برای ساختن اپلیکیشنهای شبکه و سمت سرور استفاده کنند. مدل رویداد Node.js روی شنوندهها برای دریافت رویدادها و روی emitter-ها برای ارسال دورهای رویدادها تکیه دارد. با این که این وضعیت چندان متفاوت به نظر نمیرسد؛ اما در باطن کاملاً طرز کار متفاوتی دارد و از تابعهایی مانند ()on جهت ثبت به عنوان شنونده رویداد و ()once برای ثبت یک شنونده رویداد که پس از اجرای اولیه ثبت میشود، بهره گرفته شده است. برای کسب اطلاعات بیشتر و مشاهده مثالهای عملی، میتوانید به مستندات رویداد connect در HTTP (+) مراجعه کنید.
به عنوان یک مثال دیگر، میتوانید از جاوا اسکریپت برای ساخت افزونههای چند مرورگری، بهینهسازی کارکرد مرورگر با استفاده از یک فناوری به نام WebExtensions (+) بهره بگیرید. مدل رویداد آن مشابه مدل رویدادهای وب؛ اما اندکی متفاوت است، چون مشخصات شنوندههای رویداد به صورت «حالت شتری» (camel-cased) نوشته میشوند یعنی به جای onmessage از onMessage استفاده میشود و باید با تابع addListener ترکیب شوند. برای مشاهده مثالهای بیشتر به صفحه runtime.onMessage (+) مراجعه کنید.
در این مرحله لازم نیست که در مورد محیطهای دیگر اطلاعاتی داشته باشید و هدف از بخش فوق این است که برای شما روشن کنیم که رویدادها در محیطهای برنامهنویسی مختلف میتوانند طرز کار متفاوتی داشته باشند.
روشهای استفاده از رویدادهای وب
چند روش متفاوت وجود دارد که با استفاده از آنها میتوان شنوندههای رویداد را به صفحههای کد اضافه کرد و بدین ترتیب از آنها در موارد اتفاق افتادن رویدادهای مربوطه بهره گرفت. در این بخش به بررسی ساز و کارهای مختلف این کار و مقایسه موارد استفاده هر کدام میپردازیم.
مشخصات Event Handler
مشخصات دستگیرههای رویداد جهت نوشتن کد دستگیره رویدادی طراحی شدهاند که در طی این دوره آموزشی از ابتدا تاکنون بارها مشاهده کردهایم. اگر به مثال ابتدای این مطلب بازگردیم:
1var btn = document.querySelector('button');
2
3btn.onclick = function() {
4 var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
5 document.body.style.backgroundColor = rndCol;
6}
مشخصه onclick یک مشخصه دستگیره رویداد است که در این موقعیتها استفاده میشود. این یک مشخصه ضروری مانند همه مشخصههای دیگر موجود برای یک دکمه مانند btn.textContent یا btn.style است؛ اما نوع آن خاص است، زیرا وقتی که آن را برابر با کدی قرار دهیم، این کد هر زمان که رویداد کلیک شدن دکمه اتفاق بیفتد، اجرا خواهد شد.
همچنین میتوان مشخصه دستگیره را برابر با یک تابع بانام قرار داد. کد زیر همان کاری را انجام میدهد که مثال قبلی اجرا میکند:
1var btn = document.querySelector('button');
2
3function bgChange() {
4 var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
5 document.body.style.backgroundColor = rndCol;
6}
7
8btn.onclick = bgChange;
مشخصات دستگیره برای رویدادهای بسیار فراوانی وجود دارند که در ادامه آنها را مورد بررسی قرار میدهیم. قبل از هر چیز یک کپی محلی از فایل زیر روی سیستم خود ایجاد کرده و آن را در یک مرورگر باز کنید:
1<!DOCTYPE html>
2<html>
3 <head>
4 <meta charset="utf-8">
5 <title>Random color example — event handler property</title>
6 <style>
7 button {
8 margin: 10px;
9 }
10 </style>
11 </head>
12 <body>
13 <button>Change color</button>
14 <script>
15 var btn = document.querySelector('button');
16 function random(number) {
17 return Math.floor(Math.random()*number);
18 }
19 function bgChange() {
20 var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
21 document.body.style.backgroundColor = rndCol;
22 }
23 btn.onclick = bgChange;
24 </script>
25 </body>
26</html>
این صرفاً یک کپی از مثال ایجاد رنگهای تصادفی است که قبلاً برسی کردیم. اینک تلاش میکنیم مشخصه btn.onclick را به ترتیب به مقادیر مختلف زیر تغییر دهیم و نتیجه هر کدام را ملاحظه کنیم:
- btn.onfocus و btn.onblur: این کد زمانی که دکمه فوکوس را دریافت میکند یا از دست میدهد اجرا میشود. شما میتوانید با زدن مکرر دکمه tab فوکوس صفحه را به این دکمه برده و یا از آن جدا کنید. از این مشخصه عموماً برای نمایش اطلاعاتی در مورد شیوه پر کردن فیلدهای فرم در زمان دریافت فوکوس و یا نمایش یک پیام در صورت وارد کردن یک مقدار نادرست در فیلدهای فرم استفاده میشود.
- btn.ondblclick: رنگ صفحه تنها زمانی تغییر مییابد که روی آن دو بار کلیک شود.
- window.onkeypress، window.onkeydown، window.onkeyup: در این مثال رنگ صفحه زمانی تغییر خواهد یافت که یک کلید روی صفحه کلید زده شود. keypress به فشرده شدن هر نوع کلید (یعنی فشردن به سمت پایین و رها کردن کلید) اشاره میکند؛ در حالی که keydown اشاره به صرفاً پایین رفتن یک کلید و keyup نیز اشاره به رها کردن یک کلید صفحه کلید دارد. دقت کنید که اگر تلاش کنید دستگیره رویداد را روی خود دکمه ثبت کنید، این مثال کار نمیکند، چون باید آن را روی شیء window ثبت کنید که کل پنجره مرورگر را شامل میشود.
- btn.onmouseover و btn.onmouseout: در این مثال رنگ صفحه زمانی تغییر مییابد که اشارهگر ماوس طوری جابجا شود که روی دکمه قرار گیرد و یا در مورد onmouseout زمانی فعال میشود که ماوس از محدوده دکمه خارج شود.
برخی رویدادها بسیار عمومی هستند و تقریباً در همه جا حضور دارند. برای نمونه دستگیره onclick میتواند تقریباً روی هر عنصری ثبت شود؛ در حالی که برخی دیگر خاصتر هستند و تنها در موقعیتهای خاص به کار میآیند. برای مثال میتوان از onplay تنها روی عناصر خاصی مانند <video> استفاده کرد.
دستگیرههای رویداد درونخطی (که نباید استفاده شوند)
شما احتمالاً در کد خود با الگویی مانند زیر مواجه شدید:
1<button onclick="bgChange()">Press me</button>
1function bgChange() {
2 var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
3 document.body.style.backgroundColor = rndCol;
4}
نخستین متد برای ثبت دستگیرههای رویداد که در وب ارائه شد، شامل خصوصیتهای HTML دستگیره رویداد، یعنی «دستگیرههای رویداد درونخطی» (inline event handlers) بود که در مثال فوق مشاهده کردید. مقدار این خصوصیت در عمل کد جاوا اسکریپتی بود که باید در زمان اتفاق افتادن رویداد اجرا میشد. مثال فوق یک تابع را فراخوانی میکند که درون یک عنصر <script> روی همان صفحه تعریف شده است؛ اما میتوان برای مثال به صورت زیر کد جاوا اسکریپت را مستقیماً درون خصوصیت قرار داد:
1<button onclick="alert('Hello، this is my old-fashioned event handler!');">Press me</button>
شما با کمی بررسی متوجه میشوید که بسیاری از خصوصیتهای HTML معادل مشخصههای دستگیره رویداد هستند؛ اما نباید از آنها استفاده کنید، چون در حال حاضر استفاده از آنها رویه نامناسبی تلقی میشود. با این که استفاده از این خصوصیتهای رویداد در مواردی که میخواهید کاری را به سرعت انجام دهید آسان به نظر میآید؛ اما این وضعیت به سرعت به موقعیتی غیر قابل مدیریت و ناکارآمد تبدیل خواهد شد.