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

رویدادهای لمسی (Touch Events)

در سال‌های اخیر استفاده از دستگاه‌های مجهز به صفحه نمایش‌های لمسی (مانند تلفن همراه و تبلت) بسیار فراگیر شده است. با توجه به این که در این دستگاه‌ها معمولاً از ماوس استفاده نمی‌شود و بیشتر از لمس صفحه نمایش برای تعامل با دستگاه استفاده می‌شود، باید از رویدادهای دیگری به عنوان جایگزین رویدادهای ماوس استفاده کرد. البته رویدادهای click و dblclick را به خوبی می‌توان با لمس صفحه نمایش تولید کرد. اما سایر رویدادهای ماوس در صفحات لمسی یا قابل تولید نیستند (مانند mousemove) و یا عملکر مناسبی ندارند (مانند mousedown).

 

انواع رویدادهای لمسی

در مجموع ۴ نوع رویداد لمسی در جاوا اسکریپت تعریف شده است که به شرح زیر می‌باشند.

برای درک بهتر عملکرد هر یک از رویداهای فوق مثال زیر را اجرا کنید. در این مثال یک عنصر از نوع <div> وجود دارد که در صورت وقوع هر یک از رویدادهای لمسی در محدوده‌ی این عنصر، تابع handler فراخوانی شده و نام رویداد رخ داده را در عنصری دیگر از نوع <p> نمایش می‌دهد. توجه کنید که این مثال را حتماً باید در دستگاهی که مجهز به صفحه نمایش لمسی است اجرا کنید. و یا از شبیه‌ساز مرورگر Chrome استفاده کنید. این مثال را می‌توانید اینجا در CodePen اجرا کنید.


const div = document.querySelector('div');
div.addEventListener('touchstart', handler);
div.addEventListener('touchmove', handler);            
div.addEventListener('touchend', handler);
div.addEventListener('touchcancel', handler);
function handler(event) {
	const p = document.querySelector('p');
	p.textContent += event.type + ' ';
}

نکته : در دستگاه‌های مجهز به صفحه نمایش لمسی، معمولاً برای شبیه‌سازی دکمه‌ی فرعی ماوس (یا کلیک راست) باید صفحه را لمس کرده و حدود ۲ ثانیه انگشت (یا قلم) را ثابت نگاه داشت. لذا انجام این کار موجب تولید رویداد contextmenu در این نوع دستگاه‌ها می‌شود.

 

خاصیت‌های شئ event

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

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

اما شئ Touch دارای ۴ خاصیت دیگر نیز می‌باشد که فعلاً به استاندارد نهایی اضافه نشده‌اند و پشتیبانی از آنها در دستگاه‌های مختلف متفاوت است. این خاصیت‌ها برای به دست آوردن اطلاعاتی در مورد نحوه‌ی لمس صفحه به کار می‌روند. اسامی این ۴ خاصیت و کاربرد هر یک در زیر آمده است. توجه کنید که منظور از "بیضی" در توضیحات زیر، همان سطح تماس انگشت با صفحه نمایش است که معمولاً به شکل بیضی می‌باشد.

البته تعاریف فوق، تعاریف استانداردی است که برای این خاصیت‌ها ارائه شده است. اما در حال حاضر در دستگاه‌های مختلف رفتار این خاصیت‌ها متفاوت است. (مثلاً در آزمایشی که بر روی تلفن همراه من با مرورگر Chrome انجام شد، به غیر از خاصیت force، بقیه موارد برابر با صفر بودند. ضمناً خاصیت force میزان فشار را نشان نمی‌دهد، بلکه با بیشتر شدن سطح لمس شده، بزرگتر می‌شود.)

اما برای استفاده از خاصیت‌های شئ Touch به خاصیت‌هایی از شئ event نیاز خواهیم داشت. شئ event در رویدادهای لمسی دارای ۳ خاصیت به نام‌های touches و changedTouches و targetTouches می‌باشد. هر یک از این خاصیت‌ها حاوی لیستی از اشیاء Touch هستند. یعنی مانند یک آرایه رفتار می‌کنند. محتوای هر یک از این خاصیت‌ها به شرح زیر است.

خاصیت touches بیشترین کاربرد را در بین موارد فوق دارد. مثال زیر را بر روی تلفن همراه یا تبلت اجرا کنید تا با رفتار این خاصیت و خاصیت‌های شئ Touch بهتر آشنا شوید. در این مثال فرض شده است که فقط یک نقطه لمس شده است. این مثال را می‌توانید اینجا اجرا کنید.


const div = document.querySelector('div');
div.addEventListener('touchstart', handler);
function handler(event) {
	const p = document.querySelector('p');
	p.innerHTML = 'clientX: ' + event.touches[0].clientX +'<br />';
	p.innerHTML += 'clientY: ' + event.touches[0].clientY + '<br />';
	p.innerHTML += 'screenX: ' + event.touches[0].screenX + '<br />';
	p.innerHTML += 'screenY: ' + event.touches[0].screenY + '<br />';
	p.innerHTML += 'pageX: ' + event.touches[0].pageX + '<br />';
	p.innerHTML += 'pageY: ' + event.touches[0].pageY + '<br />';
	p.innerHTML += 'identifier: ' + event.touches[0].identifier + '<br />';
	p.innerHTML += 'target: ' + event.touches[0].target.tagName;
}

نکته : در دستگاه‌های مجهز به صفحه نمایش‌های لمسی، مقدار خاصیت‌های مربوط به مختصات معمولاً اعشاری هستند.

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


const div = document.querySelector('div');
div.addEventListener('touchstart', handler);
function handler(event) {
	const p = document.querySelector('p');
	p.innerHTML = 'RadiusX: ' + event.touches[0].radiusX + '<br />';
	p.innerHTML += 'RadiusY: ' + event.touches[0].radiusY + '<br />';
	p.innerHTML += 'angle: ' + event.touches[0].rotationAngle + '<br />';
	p.innerHTML += 'force: ' + event.touches[0].force;
}

حال برای مشاهده‌ی رفتار خاصیت touches در صورت لمس شدن همزمان چند نقطه از صفحه نمایش، مثال زیر را اجرا کنید. در این مثال مختصات تمام نقاط لمس شده در صفحه‌ی وب در یک عنصر از نوع <p> نمایش داده می‌شود. این مثال را می‌توانید اینجا اجرا کنید.


document.addEventListener('touchstart', handler);
function handler(event) {
	const p = document.querySelector('p');
	const points = event.touches.length;
	let message = '';
	for(let i=0 ; i < points ; i++){
		message += `Point ${i}: <br />
			clientX: ${event.touches[i].clientX}<br />
			clientY: ${event.touches[i].clientY}<br /><br />`;
	}
	p.innerHTML = message;
}

شکل زیر نمونه‌ای از اجرای این برنامه را نشان می‌دهد. حالت نشان داده شده در این شکل با لمس همزمان ۴ نقطه از صفحه نمایش به وجود آمده است. مشاهده می‌کنید که اعداد مربوط به مختصات، اعشاری هستند.

multi-touch

در نهایت ذکر این نکته ضروری است که استفاده از رویدادهای لمسی کمی دشوار است و برای استفاده از این رویدادها باید با دقت بالا کدنویسی کرده و حتماً برنامه را در چند دستگاه محتلف آزمایش کنید.