جاواسکریپت: ۹- ایونت

نوشته حسین بهنودی در ۷ آذر ۱۳۹۹

جاواسکریپت نیز مانند بسیاری از زبان‌های دیگر می‌تواند به هنگام اجرا، از موس، کیبرد یا … اطلاعاتی را دریافت کند و بر اساس آن بی درنگ (Real-time) عملیاتی را انجام دهد.

واژه ایونت (Event) به معنای رویداد است. هرگاه بر روی یک آبجکت چیزی رخ دهد، مثلا با موس روی آن کلیک شود، یا دکمه‌ای از کیبرد زده شود؛ آن آبجکت، یک سیگنال می‌فرستد. و به وسیله آن نشان می‌دهد، که چه چیزی روی داده است. در جاواسکریپت به آن سیگنال، ایونت گفته می‌شود. صدها نوع ایونت وجود دارد که شما می‌توانید از آنها در پروژه خود استفاده کنید. ایونت‌های ماوس، کیبرد، تاچ، شبکه … که در اینجا نمی‌توان به همه آنها پرداخت.

چند نمونه از ایونت‌های پرکاربرد موس:

  • click – کلیک چپ
  • dblclick – دابل کلیک
  • contextmenu – کلیک راست
  • mousedown / mouseup – هنگامی که دکمه ماوس فشرده / رها می‌شود.
  • mouseenter / mouseleave – هنگامی که نشانگر ماوس بر روی آبجکت وارد / خارج می‌شود.
  • mousemove – هنگامی که نشانگر ماوس جابجا می‌شود.

هر ایونت، خود یک آبجکت است که می‌تواند پراپرتی‌های زیادی داشته باشد. برای نمونه ایونت کلیک، یک آبجکتی است با ده‌ها پراپرتی. از جمله:

  • مختصات مکان کلیک
  • زمان دقیق کلیک
  • کلیدهای همراه (Shift یا Ctrl یا Alt) کلیک

واژه هَندِل (Handle) به معنای گوش به زنگ بودن و واکنش مناسب نشان دادن است. گاهی رسیدگی کردن یا مدیریت کردن نیز ترجمه می‌شود. در برنامه نویسی، به فانکشنی که هنگام رخ دادن یک ایونت اجرا می‌شود، Event Handler می‌گویند.

در جاواسکریپت به ۳ روش می‌توان آن را راه‌اندازی کرد.

  • HTML Attribute
  • Element Property
  • Element Method

هر کدام از این روش‌ها کاربرد ویژه‌ای دارد. و در جای خودش باید به کار گرفته شود.


HTML Attribute

در درون تگ HTML به صورت یک اتریبیوت می‌آید. این روش ساده‌ترین راه است. با این حال بسیار کم استفاده می‌شود. چون برای تغییر در جاواسکریپت نیاز به تغییر در HTML نیز دارد.

HTML

<tag onclick="myFunc()">...</tag>        

JS

const myFunc = function() {
    ...
};

تنها برای نوشتن کدهای کوتاه، مانند نمونه زیر، مناسب است.


<tag onclick="alert('Click!')">...</tag>        


Element Property

در همه آبجکت‌ها، به ازای هر ایونت، یک پراپرتی (برای هندل کردن آن ایونت) وجود دارد.


myElem.onclick = function() { ... };

اما بیش از یک فانکشن نمی‌توان به آن نسبت داد. و تنها آخرین فانکشن اجرا می‌شود.


myElem.onclick = myFunc1;
myElem.onclick = myFunc2;    // replaces myFunc1


Element Method

در این روش از متد addEventListener استفاده می‌شود.


myElem.addEventListener("click", myFunc);

این راه از راه‌های قبلی کمی پیچیده‌تر است. اما در عوض توانایی‌های بیشتری دارد. برای نمونه:

با یک ایونت چند فانکشن می‌تواند اجرا شود.


myElem.addEventListener("click", myFunc1);
myElem.addEventListener("click", myFunc2);

در بین برنامه با کمک متد removeEventListener می‌توان آن را از کار انداخت.


myElem.addEventListener("click", myFunc);
...
myElem.removeEventListener("click", myFunc);


ایونت: نخستین آرگومان

در همه روش‌ها فانکشن می‌تواند ایونت را به عنوان نخستین آرگومان دریافت کند. و از این راه در درون فانکشن شما به پراپرتی‌های ایونت دسترسی دارید.


myElem.onclick = function(e) { ... };

// Or

myElem.addEventListener("click", function(e) { ... });


ایونت‌ها

Events Reference

ایونت‌های ماوس

پراپرتی‌های ایونت ماوس

  • مکان
    • screenX, screenY: نسبت به مانیتور
    • pageX, pageY: نسبت به صفحه
    • clientX, clientY: نسبت به بروزر
    • offsetX, offsetY: نسبت به المنت
    • movementX, movementY: نسبت به جای قبلی
  • دکمه ماوس
    • چپ: button = 0
    • میانی: button = 1
    • راست: button = 3
  • کیبرد
    • shiftKey: true | false
    • ctrlKey: true | false
    • altKey: true | false
    • metaKey: true | false

مثال click

HTML

<section id="in-box"></section>
<section id="out-box"></section>

JS

const inBox = document.getElementById("in-box");
const outBox = document.getElementById("out-box");

inBox.addEventListener('click', function(e) {
    let msg = "<p><b>click</b><hr>"
    msg += "screenX=" + e.screenX + "/screenY=" + e.screenY + "<br>";
    msg += "pageX  =" + e.pageX   + "/pageY  =" + e.pageY   + "<br>";
    msg += "clientX=" + e.clientX + "/clientY=" + e.clientY + "<br>";
    msg += "offsetX=" + e.offsetX + "/offsetY=" + e.offsetY + "<br>";
    msg += "<br>";
    msg += "altKey   = " + e.altKey   + "<br>";
    msg += "ctrlKey  = " + e.ctrlKey  + "<br>";
    msg += "shiftKey = " + e.shiftKey + "<br>";
    msg += "metaKey  = " + e.metaKey  + "<br>";
    msg += "<br>";
    msg += "button = " + e.button + "</p>";
    outBox.innerHTML = msg;
});

مثال mousedown / mouseup

HTML

<section id="in-box"></section>
<section id="out-box"></section>
                
JS

const inBox = document.getElementById("in-box");
const outBox = document.getElementById("out-box");
let msg = "";

const log = function(e) {
    msg += "<p><b>" + e.type + "</b>";
    msg += " button = " + e.button + "</p>";
    outBox.innerHTML = msg;
};

inBox.addEventListener('click', log);
inBox.addEventListener('dblclick', log);
inBox.addEventListener('contextmenu', log);
inBox.addEventListener('mousedown', log);
inBox.addEventListener('mouseup', log);

مثال mouseenter / mouseleave

HTML

<section id="in-box"><div></div></section>
<section id="out-box"></section>

JS

const inBox = document.getElementById("in-box");
const outBox = document.getElementById("out-box");
let msg = "";

const log = function(e) {
    msg += "<p>" + e.type + "</p>";
    outBox.innerHTML = msg;
};

inBox.addEventListener('mouseenter', log);
inBox.addEventListener('mouseleave', log);

مثال mousemove

HTML

<section id="in-box"></section>
<section id="out-box"></section>

JS

const inBox = document.getElementById("in-box");
const outBox = document.getElementById("out-box");

const log = e => {
    let msg = "<p><b>mousemove</b><hr>";
    msg += "offsetX = " + e.offsetX + "<br>";
    msg += "offsetY = " + e.offsetY + "</p>";

    outBox.innerHTML = msg;
};

inBox.addEventListener('mousemove', log);

تمرین ۱

  • این فایل را دانلود کنید.
  • آن را در فولدر js1 باز کنید.
  • تنها فایل script.js را می‌توانید تغییر دهید.
  • در صفحه هر جا mousedown کردید، توپ به آنجا منتقل شود.

اختیاری: در تمرین بالا، هنگامیکه mousedown است به دنبال ماوس حرکت کند تا mouseup شود.