لمس را به سایت خود اضافه کنید

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

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

به حالت های عنصر پاسخ دهید

آیا تا به حال روی یک عنصر در یک صفحه وب کلیک یا لمس کرده اید و سوال کرده اید که آیا سایت واقعاً آن را شناسایی کرده است؟

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

عناصر DOM می توانند هر یک از حالت های زیر را به ارث ببرند: پیش فرض، فوکوس، شناور و فعال. برای تغییر رابط کاربری خود برای هر یک از این حالت‌ها، باید استایل‌ها را برای کلاس‌های شبه زیر اعمال کنیم :hover ، :focus و :active مانند شکل زیر:

.btn {
  background-color: #4285f4;
}

.btn:hover {
  background-color: #296cdb;
}

.btn:focus {
  background-color: #0f52c1;

  /* The outline parameter suppresses the border
  color / outline when focused */
  outline: 0;
}

.btn:active {
  background-color: #0039a8;
}

آن را امتحان کنید

تصویری که رنگ های مختلف را برای حالت های دکمه نشان می دهد

در اکثر مرورگرهای تلفن همراه، حالت های ماوس و/یا فوکوس روی یک عنصر پس از ضربه زدن اعمال می شود.

به دقت در نظر بگیرید که چه سبک هایی را تنظیم می کنید و پس از اتمام لمس کاربر چگونه به نظر می رسد.

سرکوب سبک های پیش فرض مرورگر

هنگامی که استایل ها را برای حالت های مختلف اضافه می کنید، متوجه خواهید شد که اکثر مرورگرها سبک های خود را در پاسخ به لمس کاربر پیاده سازی می کنند. این بیشتر به این دلیل است که وقتی دستگاه های تلفن همراه برای اولین بار راه اندازی شدند، تعدادی از سایت ها حالت :active را نداشتند. در نتیجه، بسیاری از مرورگرها رنگ یا سبک هایلایت اضافی را برای ارائه بازخورد به کاربر اضافه کردند.

اکثر مرورگرها از ویژگی outline CSS برای نمایش یک حلقه در اطراف یک عنصر زمانی که یک عنصر متمرکز است استفاده می کنند. شما می توانید آن را با:

.btn:focus {
    outline: 0;

    /* Add replacement focus styling here (i.e. border) */
}

سافاری و کروم یک رنگ برجسته ضربه اضافه می کنند که می توان با ویژگی -webkit-tap-highlight-color CSS از آن جلوگیری کرد:

/* Webkit / Chrome Specific CSS to remove tap
highlight color */
.btn {
  -webkit-tap-highlight-color: transparent;
}

آن را امتحان کنید

اینترنت اکسپلورر در ویندوز فون رفتار مشابهی دارد، اما از طریق یک متا تگ سرکوب می شود:

<meta name="msapplication-tap-highlight" content="no">

فایرفاکس دو عارضه جانبی دارد.

کلاس شبه -moz-focus-inner ، که یک طرح کلی روی عناصر قابل لمس اضافه می کند، می توانید با تنظیم border: 0 حذف کنید.

اگر از عنصر <button> در فایرفاکس استفاده می‌کنید، یک گرادیان اعمال می‌شود که می‌توانید با تنظیم background-image: none .

/* Firefox Specific CSS to remove button
differences and focus ring */
.btn {
  background-image: none;
}

.btn::-moz-focus-inner {
  border: 0;
}

آن را امتحان کنید

غیرفعال کردن انتخاب کاربر

هنگامی که رابط کاربری خود را ایجاد می کنید، ممکن است سناریوهایی وجود داشته باشد که بخواهید کاربران با عناصر شما تعامل داشته باشند، اما می خواهید رفتار پیش فرض انتخاب متن با فشار طولانی یا کشیدن ماوس روی رابط کاربری خود را سرکوب کنید.

شما می توانید این کار را با ویژگی CSS user-select انجام دهید، اما مراقب باشید که انجام این کار در محتوا می تواند برای کاربران بسیار آزاردهنده باشد اگر بخواهند متن موجود در عنصر را انتخاب کنند. بنابراین مطمئن شوید که آن را با احتیاط و کم استفاده کنید.

/* Example: Disable selecting text on a paragraph element: */
p.disable-text-selection {
  user-select: none;
}

ژست های سفارشی را پیاده سازی کنید

اگر ایده ای برای تعاملات و حرکات سفارشی برای سایت خود دارید، دو موضوع وجود دارد که باید در نظر داشته باشید:

  1. نحوه پشتیبانی از همه مرورگرها
  2. چگونه نرخ فریم خود را بالا نگه دارید

در این مقاله، دقیقاً به این موضوعات مربوط به APIهایی که برای ضربه زدن به همه مرورگرها باید از آنها پشتیبانی کنیم و سپس نحوه استفاده کارآمد از این رویدادها را توضیح خواهیم داد.

بسته به کاری که می‌خواهید ژست شما انجام دهد، احتمالاً می‌خواهید کاربر در یک زمان با یک عنصر تعامل داشته باشد یا می‌خواهید که بتواند همزمان با چندین عنصر تعامل داشته باشد.

ما قصد داریم در این مقاله دو نمونه را بررسی کنیم که هر دو نشان دهنده پشتیبانی از همه مرورگرها و نحوه بالا نگه داشتن نرخ فریم هستند.

نمونه GIF لمس روی سند

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

این مفید است زیرا انعطاف پذیری زیادی را برای کاربر فراهم می کند، اما محدودیتی را در مورد نحوه تعامل کاربر با رابط کاربری شما اعمال می کند.

نمونه GIF لمس روی عنصر

با این حال، اگر از کاربران انتظار دارید که همزمان با چندین عنصر تعامل داشته باشند (با استفاده از لمس چندگانه)، باید لمس را به عنصر خاصی محدود کنید.

این برای کاربران انعطاف‌پذیرتر است، اما منطق دستکاری UI را پیچیده‌تر می‌کند و در برابر خطاهای کاربر مقاومت کمتری دارد.

شنوندگان رویداد را اضافه کنید

در کروم (نسخه 55 و جدیدتر)، Internet Explorer و Edge، PointerEvents رویکرد توصیه شده برای اجرای حرکات سفارشی هستند.

در سایر مرورگرها، TouchEvents و MouseEvents رویکرد صحیحی هستند.

ویژگی عالی PointerEvents این است که چندین نوع ورودی، از جمله رویدادهای ماوس، لمسی و قلم را در یک مجموعه از تماس‌ها ادغام می‌کند. رویدادهایی که باید به آنها گوش دهید عبارتند از: pointerdown , pointermove , pointerup و pointercancel .

معادل‌های موجود در سایر مرورگرها عبارتند از: touchstart ، touchmove ، touchend و touchcancel برای رویدادهای لمسی و اگر می‌خواهید همان حرکت را برای ورودی ماوس پیاده‌سازی کنید، باید mousedown ، mousemove و mouseup پیاده‌سازی کنید.

اگر درباره رویدادهایی که باید استفاده کنید سؤالی دارید، این جدول رویدادهای لمس، ماوس و اشاره گر را بررسی کنید.

استفاده از این رویدادها مستلزم فراخوانی متد addEventListener() بر روی یک عنصر DOM، همراه با نام رویداد، یک تابع callback و یک بولی است. بولی تعیین می کند که آیا شما باید رویداد را قبل یا بعد از اینکه دیگر عناصر فرصتی برای گرفتن و تفسیر رویدادها داشته باشند، دریافت کنید. ( true به این معنی است که شما رویداد را قبل از سایر عناصر می خواهید.)

در اینجا یک مثال از گوش دادن برای شروع یک تعامل است.

// Check if pointer events are supported.
if (window.PointerEvent) {
  // Add Pointer Event Listener
  swipeFrontElement.addEventListener('pointerdown', this.handleGestureStart, true);
  swipeFrontElement.addEventListener('pointermove', this.handleGestureMove, true);
  swipeFrontElement.addEventListener('pointerup', this.handleGestureEnd, true);
  swipeFrontElement.addEventListener('pointercancel', this.handleGestureEnd, true);
} else {
  // Add Touch Listener
  swipeFrontElement.addEventListener('touchstart', this.handleGestureStart, true);
  swipeFrontElement.addEventListener('touchmove', this.handleGestureMove, true);
  swipeFrontElement.addEventListener('touchend', this.handleGestureEnd, true);
  swipeFrontElement.addEventListener('touchcancel', this.handleGestureEnd, true);

  // Add Mouse Listener
  swipeFrontElement.addEventListener('mousedown', this.handleGestureStart, true);
}

آن را امتحان کنید

تعامل تک عنصری را مدیریت کنید

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

TouchEvents یک حرکت را پس از شروع آن بدون توجه به جایی که لمس انجام می‌شود ردیابی می‌کند و PointerEvents رویدادها را بدون توجه به جایی که لمس رخ می‌دهد پس از فراخوانی setPointerCapture در عنصر DOM ردیابی می‌کند.

برای رویدادهای حرکت و پایان ماوس، شنوندگان رویداد را به روش شروع حرکت اضافه می کنیم و شنوندگان را به سند اضافه می کنیم، به این معنی که می تواند مکان نما را تا زمانی که ژست کامل شود ردیابی کند.

اقدامات انجام شده برای اجرای این امر عبارتند از:

  1. همه شنوندگان TouchEvent و PointerEvent را اضافه کنید. برای MouseEvents فقط رویداد شروع را اضافه کنید.
  2. در داخل بازگشت به تماس با اشاره شروع، رویدادهای حرکت و پایان ماوس را به سند متصل کنید. به این ترتیب تمام رویدادهای ماوس صرف نظر از اینکه رویداد روی عنصر اصلی رخ می دهد یا خیر دریافت می شود. برای PointerEvents باید setPointerCapture() روی عنصر اصلی خود فراخوانی کنیم تا همه رویدادهای بعدی را دریافت کنیم. سپس شروع ژست را کنترل کنید.
  3. رویدادهای حرکت را مدیریت کنید.
  4. در رویداد پایانی، حرکت ماوس و پایان شنوندگان را از سند بردارید و ژست را پایان دهید.

در زیر قطعه ای از متد handleGestureStart() ما آمده است که رویدادهای حرکت و پایان را به سند اضافه می کند:

// Handle the start of gestures
this.handleGestureStart = function(evt) {
  evt.preventDefault();

  if(evt.touches && evt.touches.length > 1) {
    return;
  }

  // Add the move and end listeners
  if (window.PointerEvent) {
    evt.target.setPointerCapture(evt.pointerId);
  } else {
    // Add Mouse Listeners
    document.addEventListener('mousemove', this.handleGestureMove, true);
    document.addEventListener('mouseup', this.handleGestureEnd, true);
  }

  initialTouchPos = getGesturePointFromEvent(evt);

  swipeFrontElement.style.transition = 'initial';
}.bind(this);

آن را امتحان کنید

فراخوان پایانی که اضافه می‌کنیم handleGestureEnd() است که شنونده‌های انتقال و رویداد پایانی را از سند حذف می‌کند و وقتی ژست به این صورت تمام شد، نشانگر را آزاد می‌کند:

// Handle end gestures
this.handleGestureEnd = function(evt) {
  evt.preventDefault();

  if (evt.touches && evt.touches.length > 0) {
    return;
  }

  rafPending = false;

  // Remove Event Listeners
  if (window.PointerEvent) {
    evt.target.releasePointerCapture(evt.pointerId);
  } else {
    // Remove Mouse Listeners
    document.removeEventListener('mousemove', this.handleGestureMove, true);
    document.removeEventListener('mouseup', this.handleGestureEnd, true);
  }

  updateSwipeRestPosition();

  initialTouchPos = null;
}.bind(this);

آن را امتحان کنید

با پیروی از این الگوی افزودن رویداد حرکت به سند، اگر کاربر شروع به تعامل با یک عنصر کرد و ژست خود را به خارج از عنصر حرکت داد، بدون توجه به اینکه در کجای صفحه هستند، به حرکت ماوس ادامه خواهیم داد، زیرا رویدادها از سند دریافت می شود.

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

نمایش رویدادهای لمسی الزام آور برای سند در «تاچ استارت».

به لمس موثر پاسخ می دهد

اکنون که رویدادهای شروع و پایان را در نظر گرفته ایم، در واقع می توانیم به رویدادهای لمسی پاسخ دهیم.

برای هر یک از رویدادهای شروع و حرکت، می توانید به راحتی x و y از یک رویداد استخراج کنید.

مثال زیر با بررسی وجود targetTouches بررسی می‌کند که آیا رویداد مربوط به TouchEvent است یا خیر. اگر این کار را انجام داد، پس از اولین لمس، clientX و clientY را استخراج می کند. اگر رویداد یک PointerEvent یا MouseEvent باشد، clientX و clientY مستقیماً از خود رویداد استخراج می‌کند.

function getGesturePointFromEvent(evt) {
    var point = {};

    if (evt.targetTouches) {
      // Prefer Touch Events
      point.x = evt.targetTouches[0].clientX;
      point.y = evt.targetTouches[0].clientY;
    } else {
      // Either Mouse event or Pointer Event
      point.x = evt.clientX;
      point.y = evt.clientY;
    }

    return point;
  }

آن را امتحان کنید

یک TouchEvent دارای سه لیست حاوی داده های لمسی است:

  • touches : فهرستی از تمام لمس‌های فعلی روی صفحه، صرف‌نظر از عنصر DOM که روی آن هستند.
  • targetTouches : فهرست لمس‌هایی که در حال حاضر روی عنصر DOM که رویداد به آن محدود شده است.
  • changedTouches : فهرست لمس‌هایی که تغییر کرده و منجر به اجرا شدن رویداد می‌شود.

در بیشتر موارد، targetTouches هر آنچه را که نیاز دارید و می خواهید در اختیار شما قرار می دهد. (برای اطلاعات بیشتر در مورد این لیست ها به لیست های لمسی مراجعه کنید).

از requestAnimationFrame استفاده کنید

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

با استفاده از requestAnimationFrame() فرصتی برای به روز رسانی رابط کاربری داریم درست قبل از اینکه مرورگر قصد ترسیم یک فریم را داشته باشد و به ما کمک می کند تا برخی از کارها را از تماس های رویداد خود خارج کنیم.

اگر با requestAnimationFrame() آشنا نیستید، می توانید در اینجا اطلاعات بیشتری کسب کنید .

یک پیاده سازی معمولی ذخیره مختصات x و y از شروع و جابجایی رویدادها و درخواست یک فریم انیمیشن در داخل callback رویداد move است.

در نسخه ی نمایشی خود، موقعیت لمس اولیه را در handleGestureStart() ذخیره می کنیم (به دنبال initialTouchPos بگردید):

// Handle the start of gestures
this.handleGestureStart = function(evt) {
  evt.preventDefault();

  if (evt.touches && evt.touches.length > 1) {
    return;
  }

  // Add the move and end listeners
  if (window.PointerEvent) {
    evt.target.setPointerCapture(evt.pointerId);
  } else {
    // Add Mouse Listeners
    document.addEventListener('mousemove', this.handleGestureMove, true);
    document.addEventListener('mouseup', this.handleGestureEnd, true);
  }

  initialTouchPos = getGesturePointFromEvent(evt);

  swipeFrontElement.style.transition = 'initial';
}.bind(this);

متد handleGestureMove() موقعیت رویداد خود را قبل از درخواست یک فریم انیمیشن در صورت نیاز ذخیره می‌کند و تابع onAnimFrame() ما را به عنوان callback ارسال می‌کند:

this.handleGestureMove = function (evt) {
  evt.preventDefault();

  if (!initialTouchPos) {
    return;
  }

  lastTouchPos = getGesturePointFromEvent(evt);

  if (rafPending) {
    return;
  }

  rafPending = true;

  window.requestAnimFrame(onAnimFrame);
}.bind(this);

مقدار onAnimFrame تابعی است که با فراخوانی آن، رابط کاربری ما را تغییر می‌دهد تا آن را جابه‌جا کند. با ارسال این تابع به requestAnimationFrame() ، به مرورگر می گوییم که درست قبل از اینکه صفحه را به روز کند آن را فراخوانی کند (یعنی هر تغییری را در صفحه نقاشی کند).

در فراخوانی handleGestureMove() ابتدا بررسی می‌کنیم که آیا rafPending نادرست است، که نشان می‌دهد onAnimFrame() توسط requestAnimationFrame() از آخرین رویداد حرکت فراخوانی شده است یا خیر. این بدان معناست که ما فقط یک requestAnimationFrame() داریم که در هر زمان منتظر اجراست.

وقتی فراخوانی onAnimFrame() ما اجرا می‌شود، تبدیل را روی هر عنصری که می‌خواهیم منتقل کنیم، قبل از به‌روزرسانی rafPending روی false قرار می‌دهیم، و به رویداد لمسی بعدی اجازه می‌دهیم یک فریم انیمیشن جدید درخواست کند.

function onAnimFrame() {
  if (!rafPending) {
    return;
  }

  var differenceInX = initialTouchPos.x - lastTouchPos.x;
  var newXTransform = (currentXPosition - differenceInX)+'px';
  var transformStyle = 'translateX('+newXTransform+')';

  swipeFrontElement.style.webkitTransform = transformStyle;
  swipeFrontElement.style.MozTransform = transformStyle;
  swipeFrontElement.style.msTransform = transformStyle;
  swipeFrontElement.style.transform = transformStyle;

  rafPending = false;
}

حرکات را با استفاده از اقدامات لمسی کنترل کنید

ویژگی CSS touch-action به شما امکان می دهد رفتار لمس پیش فرض یک عنصر را کنترل کنید. در مثال‌هایمان، ما از touch-action: none برای جلوگیری از انجام کاری توسط مرورگر با لمس کاربر، به ما امکان می‌دهد همه رویدادهای لمسی را رهگیری کنیم.

/* Pass all touches to javascript: */
button.custom-touch-logic {
  touch-action: none;
}

استفاده از touch-action: none تا حدی یک گزینه هسته ای نیستند زیرا از همه رفتارهای پیش فرض مرورگر جلوگیری می کنند. در بسیاری از موارد یکی از گزینه های زیر راه حل بهتری است.

touch-action به شما امکان می دهد ژست های پیاده سازی شده توسط مرورگر را غیرفعال کنید. به عنوان مثال، IE10+ از حرکت دوبار ضربه زدن برای بزرگنمایی پشتیبانی می کند. با تنظیم یک touch-action manipulation از رفتار پیش فرض دو ضربه زدن جلوگیری می کنید.

این به شما این امکان را می دهد که خودتان یک ژست دوبار ضربه بزنید.

در زیر لیستی از مقادیر متداول touch-action وجود دارد:

Action Parameters را لمس کنید
touch-action: none هیچ تعامل لمسی توسط مرورگر انجام نخواهد شد.
touch-action: pinch-zoom همه تعاملات مرورگر مانند «عمل لمسی: هیچ‌کدام» را غیرفعال می‌کند، به غیر از «بزرگ‌نمایی کوچک»، که همچنان توسط مرورگر مدیریت می‌شود.
touch-action: pan-y pinch-zoom اسکرول‌های افقی را در جاوا اسکریپت بدون غیرفعال کردن پیمایش عمودی یا کوچک‌نمایی (مثلاً چرخ فلک‌های تصویر) مدیریت کنید.
touch-action: manipulation ژست دوبار ضربه زدن را غیرفعال می کند که از هرگونه تأخیر کلیک توسط مرورگر جلوگیری می کند. اسکرول و زوم کردن را به مرورگر می‌گذارد.

پشتیبانی از نسخه های قدیمی IE

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

برای بررسی پشتیبانی از PointerEvents معمولاً به دنبال window.PointerEvent می‌گردید، اما در IE10، به دنبال window.navigator.msPointerEnabled می‌گردید.

نام رویدادها با پیشوندهای فروشنده عبارتند از: 'MSPointerDown' ، 'MSPointerUp' و 'MSPointerMove' .

مثال زیر نحوه بررسی پشتیبانی و تغییر نام رویداد را به شما نشان می دهد.

var pointerDownName = 'pointerdown';
var pointerUpName = 'pointerup';
var pointerMoveName = 'pointermove';

if (window.navigator.msPointerEnabled) {
  pointerDownName = 'MSPointerDown';
  pointerUpName = 'MSPointerUp';
  pointerMoveName = 'MSPointerMove';
}

// Simple way to check if some form of pointerevents is enabled or not
window.PointerEventsSupport = false;
if (window.PointerEvent || window.navigator.msPointerEnabled) {
  window.PointerEventsSupport = true;
}

برای اطلاعات بیشتر، این مقاله به‌روزرسانی‌های مایکروسافت را بررسی کنید.

مرجع

کلاس های شبه برای حالت های لمسی

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

مرجع رویدادهای لمسی قطعی را می‌توانید در اینجا پیدا کنید: رویدادهای لمسی W3C .

رویدادهای لمس، ماوس و اشاره گر

این رویدادها بلوک های ساختمانی برای اضافه کردن ژست های جدید به برنامه شما هستند:

رویدادهای لمس، ماوس، اشاره گر
touchstart ، mousedown ، pointerdown هنگامی که یک انگشت برای اولین بار عنصری را لمس می کند یا زمانی که کاربر روی ماوس کلیک می کند، این نام خوانده می شود.
touchmove ، mousemove ، pointermove زمانی که کاربر انگشت خود را روی صفحه حرکت می‌دهد یا با ماوس می‌کشد، این نام خوانده می‌شود.
touchend ، mouseup ، pointerup زمانی که کاربر انگشت خود را از روی صفحه بلند می کند یا ماوس را رها می کند، این نام خوانده می شود.
pointercancel touchcancel زمانی که مرورگر حرکات لمسی را لغو می کند، این نام خوانده می شود. به عنوان مثال، کاربر یک برنامه وب را لمس می کند و سپس برگه ها را تغییر می دهد.

لیست ها را لمس کنید

هر رویداد لمسی شامل سه ویژگی لیست است:

ویژگی های رویداد را لمس کنید
touches فهرست تمام لمس‌های فعلی روی صفحه، صرف‌نظر از عناصری که لمس می‌شوند.
targetTouches فهرست لمس هایی که روی عنصری که هدف رویداد فعلی است شروع شده است. به عنوان مثال، اگر به یک <button> متصل شوید، در حال حاضر فقط روی آن دکمه لمس خواهید شد. اگر به سند متصل شوید، تمام مواردی که در حال حاضر روی سند وجود دارد را دریافت خواهید کرد.
changedTouches فهرست لمس هایی که تغییر کرده و منجر به اجرا شدن رویداد شده است:
  • برای رویداد touchstart - لیستی از نقاط لمسی که به تازگی با رویداد فعلی فعال شده اند.
  • برای رویداد touchmove فهرست نقاط لمسی که از آخرین رویداد جابجا شده‌اند.
  • برای رویدادهای touchend و touchcancel - لیستی از نقاط لمسی که به تازگی از سطح حذف شده اند.

فعال کردن پشتیبانی حالت فعال در iOS

متأسفانه، Safari در iOS به طور پیش‌فرض حالت فعال را اعمال نمی‌کند، برای اینکه آن را به کار ببندید، باید یک شنونده رویداد touchstart به بدنه سند یا به هر عنصر اضافه کنید.

شما باید این کار را پشت تست عامل کاربر انجام دهید تا فقط روی دستگاه‌های iOS اجرا شود.

افزودن یک شروع لمسی به بدنه این مزیت را دارد که برای همه عناصر موجود در DOM اعمال می شود، با این حال ممکن است هنگام پیمایش صفحه مشکلات عملکردی داشته باشد.

window.onload = function() {
  if (/iP(hone|ad)/.test(window.navigator.userAgent)) {
    document.body.addEventListener('touchstart', function() {}, false);
  }
};

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

window.onload = function() {
  if (/iP(hone|ad)/.test(window.navigator.userAgent)) {
    var elements = document.querySelectorAll('button');
    var emptyFunction = function() {};

    for (var i = 0; i < elements.length; i++) {
        elements[i].addEventListener('touchstart', emptyFunction, false);
    }
  }
};