بازگشت به دوره

رویدادهای صفحه کلید

در این بخش به بررسی انواع رویدادهایی که توسط صفحه کلید تولید می‌شوند می‌پردازیم. همچنین خاصیت‌های شئ event که در این رویدادها در دسترس هستند را معرفی خواهیم کرد.

 

انواع رویدادهای صفحه کلید

در جاوا اسکریپت ۳ نوع رویداد توسط صفحه کلید تولید می‌شوند که عبارتند از :

نکته : در زمان فشردن کلیدهای کاراکتری، ابتدا رویداد keydown و سپس رویداد keypress رخ می‌دهد. و در صورت فشرده نگه داشتن کلید، این دو رویداد با همین ترتیب تکرار می‌شوند.

نکته : برخی از عناصر در صفحات وب می‌توانند focus را در اختیار بگیرند. عنصری که focus را در اختیار دارد، تمام ورودی‌های صفحه کلید را دریافت می‌کند. مثلاً برای تایپ کردن یک رشته در عنصری از نوع <input>، ابتدا باید focus را به عنصر مورد نظر منتقل کرد (با کلیک کردن یا زدن کلید TAB)، سپس ورودی مورد نظر را تایپ کرد. توجه به این نکته بسیار مهم است که برخلاف رویدادهای ماوس که برای هر عنصری قابل استفاده هستند. رویدادهای صفحه کلید فقط برای عناصری که می‌توانند focus را در اختیار بگیرند قابل استفاده می‌باشند. زیرا فقط این عناصر می‌توانند ورودی‌هایی را از صفحه کلید دریافت کنند. مثلاً یک عنصر از نوع <div> نمی‌تواند ورودی‌های صفحه کلید را دریافت کند، پس نمی‌توان از رویدادهای صفحه کلید برای این عنصر استفاده کرد. (مگر این که از صفت tabindex برای عنصر مورد نظر استفاده شود)

مثال زیر نحوه‌ی وقوع رویدادهای صفحه کلید و ترتیب وقوع آنها را نشان می‌دهد. در این مثال برای یک عنصر از نوع <input>، یک تابع به عنوان Event Handler برای هر ۳ رویداد صفحه کلید تعریف شده است. در صورت فراخوانی این تابع، نام رویداد در صفحه‌ی وب نمایش می‌دهد. اگر این مثال را اجرا کنید، مشاهده می‌کنید که با فشردن هر یک از کلیدهای کاراکتری هر ۳ رویداد رخ می‌دهند. ترتیب وقوع آنها نیز به این صورت است که ابتدا رویداد keydown، سپس رویداد keypress و در انتها رویداد keyup رخ می‌دهد. در صورت نگه داشتن کلید نیز رویدادهای keydown و keypress به صورت متوالی رخ می‌دهند.

اما اگر یکی از کلیدهای غیر کاراکتری (مانند Shift یا Insert) را فشار دهید. فقط ۲ رویداد keydown و keyup رخ می‌دهند و رویداد keypress برای این نوع کلیدها رخ نمی‌دهد. این مثال را می‌توانید اینجا در CodePen اجرا کنید.


const input = document.querySelector('input');
input.addEventListener('keydown', handler);
input.addEventListener('keypress', handler);
input.addEventListener('keyup', handler);

function handler(event) {
	let p = document.querySelector('p');
	p.textContent += event.type + ' ';
}
 

خاصیت‌های charCode و keyCode

در زمان وقوع هر یک از رویدادهای صفحه کلید، دقیقاً مانند رویدادهای ماوس، یک آرگومان ورودی به تابع Event Handler ارسال می‌شود. این شئ دارای خاصیت‌هایی است که به وسیله‌ی آنها می‌توان کلید یا کلیدهای فشرده شده از صفحه کلید را تشخیص داد.

با استفاده از خاصیت charCode می‌توان کد عددی کاراکتر وارد شده را به دست آورد. این خاصیت فقط باید در رویداد keypress به کار برده شود. توجه کنید که مقدار خاصیت charCode به کاراکتر وارد شده وابسته است، نه کلید فشرده شده. زیرا یک کلید خاص بر روی صفحه کلید می‌تواند کاراکترهای مختلفی را تولید کند. مثلاً کلید "A" می‌تواند در حالتی که زبان ورودی انگلیسی باشد دو کاراکتر "a" و "A" را تولید کند که مقدار خاصیت charCode برای این دو کاراکتر متفاوت بوده و به ترتیب برابر با 97 و 65 است. همچنین اگر زبان ورودی تغییر کند (مثلاً به فارسی)، همان کلید "A" می‌تواند کاراکتر "ش" را تولید کند. که مقدار خاصیت charCode برای این کاراکتر 1588 خواهد بود.

مثال زیر نحوه‌ی استفاده از خاصیت charCode را نشان می‌دهد. در این مثال کد کاراکتر وارد شده در عنصر <input>، در یک عنصر از نوع <p> نمایش داده می‌شود. این مثال را می‌توانید اینجا اجرا کنید.


const input = document.querySelector('input');
input.addEventListener('keypress', handler);

function handler(event) {
	const p = document.querySelector('p');
	p.textContent += event.charCode + ' ';
}

خاصیت دیگری که در رویدادهای صفحه کلید به کار برده می‌شود، خاصیت keyCode است. با استفاده از این خاصیت می‌توان کد کلید فشرده شده را به دست آورد. این خاصیت فقط باید در رویدادهای keydown و keyup به کار برده شود. توجه کنید که برخلاف خاصیت charCode، مقدار خاصیت keyCode برای هر یک از کلیدهای صفحه کلید همیشه ثابت است. یعنی نوع زبان ورودی و یا کوچک یا بزرگ بودن حروف هیچ تاثیری در مقدار این خاصیت ندارد. در واقع این خاصیت شماره‌ی کلید فشرده شده را مشخص می‌کند و هر کلید در صفحه کلید دارای شماره‌ی ثابتی است.

مثال زیر نحوه‌ی استفاده از این خاصیت را نشان می‌دهد. این مثال را می‌توانید اینجا اجرا کنید. مثلاً با زدن کلید "A" از صفحه کلید، همیشه مقدار این خاصیت برابر با 65 خواهد بود.


const input = document.querySelector('input');
input.addEventListener('keydown', handler);

function handler(event) {
	const p = document.querySelector('p');
	p.textContent += event.keyCode + ' ';
}
 

خاصیت‌های key و code

هرچند خاصیت‌های charCode و keyCode در تمام مرورگرها پشتیبانی می‌شوند. اما جزء موارد منسوخ شده (Deprecated) در جاوا اسکریپت محسوب می‌شوند و توصیه می‌شود که از این خاصیت‌ها استفاده نشود. زیرا ممکن است در آینده، پشتیبانی از این خاصیت‌ها از مرورگرها حذف شود. (البته احتمال آن بسیار کم است)

در استاندارد جدید بهتر است از دو خاصیت key و code به ترتیب به جای charCode و keyCode استفاده شود. این خاصیت‌ها را در تمام رویدادهای صفحه کلید می‌توان به کار برد. تفاوت اصلی key و code با charCode و keyCode در این است که بر خلاف دو خاصیت قبلی که کدها را به صورت عددی ذخیره می‌کردند، این دو خاصیت کدها را به صورت رشته‌ای ذخیره می‌کنند.

مثلاً خاصیت key برای هر کاراکتر، دقیقاً همان کاراکتر را ذخیره می‌کند. و برای کلیدهای غیر کاراکتری، نام آن کلید را به صورت رشته‌ای ذخیره می‌کند. مثلاً برای کلید Ctrl، مقدار "Control" را ذخیره می‌کند.

مثال زیر نحوه‌ی استفاده از خاصیت key را نشان می‌دهد. این مثال را می‌توانید اینجا اجرا کنید.


const input = document.querySelector('input');
input.addEventListener('keydown', handler);

function handler(event) {
	const p = document.querySelector('p');
	p.textContent += event.key + ' ';
}

خاصیت code نیز برای هر یک از کلیدهای صفحه کلید، یک نام مشخص را به صورت رشته بازمی‌گرداند. دقیقاً مانند خاصیت keyCode، در این خاصیت نیز فقط کلید فشرده شده مهم است و زبان ورودی و یا کوچک و بزرگ بودن حروف مهم نیست. مثلاً برای کلید "D" تحت هر شرایطی مقدار "KeyD" در این خاصیت ذخیره می‌شود. یک مزیت مهم خاصیت code نسبت به خاصیت keyCode در این است که برای کلیدهایی که دو نمونه از آنها در صفحه کلید وجود دارد (مانند Shift یا Ctrl)، دو کد متفاوت بازمی‌گرداند (مثلا ShiftLeft و ShiftRight). در صورتی که کد عددی ذخیره شده در خاصیت keyCode برای کلیدهای Shift سمت چپ و راست یکسان و برابر با عدد 16 است.

مثال زیر نیز نحوه‌ی استفاده از خاصیت code را نشان می‌دهد. این مثال را می‌توانید اینجا اجرا کنید.


const input = document.querySelector('input');
input.addEventListener('keydown', handler);

function handler(event) {
	const p = document.querySelector('p');
	p.textContent += event.code + ' ';
}

نکته : خاصیت key در حال حاضر در تمام مرورگرها پشتیبانی می‌شود. اما خاصیت code در مرورگر IE و Edge (تا نسخه‌ی ۱۸) پشتیبانی نمی‌شود. پس تا زمانی که این خاصیت در مرورگر Edge پشتیبانی شود بهتر است از آن استفاده نشود. و یا قبل از استفاده، وضعیت پشتیبانی از این خاصیت بررسی شود.

قطعه کد زیر نحوه‌ی بررسی وضعیت پشتیانی از خاصیت code را نشان می‌دهد. به طور کلی برای بررسی این که آیا یک متد یا یک خاصیت در مرورگر پشتیبانی می‌شود یا خیر، آن را با مقدار undefined مقایسه می‌کنیم. زیرا در صورتی که خاصیت یا متدی در یک شئ تعریف نشده باشد، مقدار آن undefined خواهد بود.


const input = document.querySelector('input');
input.addEventListener('keydown', handler);

function handler(event) {
	const p = document.querySelector('p');
	if (event.code === undefined) {
		p.textContent += event.keyCode + ' ';
	} else {
		p.textContent += event.code + ' ';
	}	
}

در این مثال در صورتی که مرورگر از خاصیت code پشتیبانی نکند، خاصیت keyCode که یک کد عددی است نمایش داده می‌شود. و در صورت پشتیبانی از خاصیت code، مقدار این خاصیت که یک کد رشته‌ای است نمایش داده می‌شود. این مثال را می‌توانید اینجا اجرا کنید. سعی این مثال را با مرورگرهای مختلف اجرا کنید تا تاثیر دستورات شرطی را مشاهده کنید.

 

خاصیت‌های altKey و shiftKey و ctrlKey

دقیقاً مانند رویدادهای ماوس، در رویدادهای صفحه کلید نیز می‌توان با استفاده از ۳ خاصیت altKey و shiftKey و ctrlKey وضعیت فشرده بودن یا نبودن هر یک از این کلیدها را در زمان وقوع رویداد تشخیص داد.

به عنوان مثال فرض کنید در برنامه‌ای قصد دارید در صورت فشرده شدن همزمان کلیدهای Ctrl + Q عمل خاصی را انجام دهید. قطعه کد زیر نحوه‌ی انجام این کار را نشان می‌دهد. در این مثال در صورت فشردن همزمان این دو کلید، پیامی به کاربر نمایش داده می‌شود.


const input = document.querySelector('input');
input.addEventListener('keydown', handler);

function handler(event) {
	if(event.ctrlKey){
		if(event.code == 'KeyQ'){
			alert('Ctrl + Q Pressed!');
		}
	}
}
این مثال را می‌توانید اینجا اجرا کنید.