إضافة لمسة إلى موقعك الإلكتروني

تتوفّر الشاشات التي تعمل باللمس على المزيد والمزيد من الأجهزة، بدءًا من الهواتف وحتى شاشات أجهزة الكمبيوتر المكتبي. يجب أن يستجيب تطبيقك للمس المستخدمين بطرق بديهية وجميلة.

تتوفر الشاشات التي تعمل باللمس على المزيد والمزيد من الأجهزة، بدءًا من الهواتف وحتى شاشات سطح المكتب. عندما يختار المستخدمون التفاعل مع واجهة المستخدم الخاصة بك، يجب أن يستجيب تطبيقك إلى لمسهم بطرق بديهية.

الاستجابة لحالات العناصر

هل سبق لك أن لمست أو نقرت على أحد العناصر في صفحة ويب وتساءلت عما إذا كان الموقع قد اكتشفه بالفعل؟

إنّ تغيير لون عنصر ما عندما يلمس المستخدمون أجزاء من واجهة المستخدم أو يتفاعلون معها يمنحهم شعورًا أساسيًا بالطمأنينة بأنّ موقعك الإلكتروني يعمل على ما يرام. لا يخفف هذا من الإحباط فقط، بل يمكن أن يمنح أيضًا شعورًا سريعًا وسريع الاستجابة.

يمكن أن تكتسب عناصر 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. نتيجةً لذلك، أضافت العديد من المتصفّحات لونًا أو نمطًا إضافيًا للتمييز من أجل تقديم ملاحظات للمستخدم.

تستخدِم معظم المتصفّحات سمة CSS outline لعرض حلقة حول عنصر عند التركيز عليه. ويمكنك منعه باستخدام:

.btn:focus {
    outline: 0;

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

يضيف Safari وChrome لونًا لتمييز النقرات يمكن منعه باستخدام سمة CSS التالية: -webkit-tap-highlight-color

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

التجربة الآن

يستخدم Internet Explorer على Windows Phone سلوكًا مشابهًا، ولكن يتم إيقافه عبر علامة وصفية:

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

هناك تأثيران جانبيان في Firefox يجب التعامل معهما.

الفئة الصورية -moz-focus-inner التي تضيف مخططًا على العناصر التي يمكن لمسها، ويمكنك إزالتها من خلال ضبط border: 0.

إذا كنت تستخدم عنصر <button> على Firefox، سيتم تطبيق تدرج ، ويمكنك إزالته من خلال ضبط 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. كيفية الحفاظ على ارتفاع عدد اللقطات في الثانية

في هذه المقالة، سنتناول هذه المواضيع بالضبط التي تتناول واجهات برمجة التطبيقات التي نحتاج إلى استخدامها للوصول إلى جميع المتصفّحات، ثم سنتناول كيفية استخدامنا لهذه الأحداث بكفاءة.

بناءً على ما تريد أن تفعله إيماءتك، قد تريد على الأرجح أن يتفاعل المستخدم مع عنصر واحد في كل مرة أو تريد أن يكون قادرًا على التفاعل مع عناصر متعددة في الوقت نفسه.

سنلقي نظرة على مثالين في هذه المقالة، كلاهما يوضّح توافق كل المتصفحات وكيفية الحفاظ على ارتفاع عدد اللقطات في الثانية.

مثال على ملف GIF يعرض لمسة على المستند

سيسمح المثال الأول للمستخدم بالتفاعل مع عنصر واحد. في هذه الحالة، قد تحتاج إلى منح جميع أحداث اللمس لهذا العنصر الواحد، ما دامت الإشارة قد بدأت في البداية على العنصر نفسه. على سبيل المثال، سيظل بإمكانك التحكّم في العنصر حتى بعد إزالة إصبعك عنه.

ويُعدّ ذلك مفيدًا لأنّه يمنح المستخدم قدرًا كبيرًا من المرونة، ولكنه يفرض قيودًا على كيفية تفاعل المستخدم مع واجهة المستخدم.

مثال GIF على لمسة العنصر

إذا كنت تتوقع تفاعل المستخدمين مع عناصر متعددة في الوقت نفسه (باستخدام تقنية اللمس المتعدّد)، يجب حصر اللمس بالعنصر المحدّد.

وهذا الأسلوب أكثر مرونة للمستخدمين، ولكنه يعقد منطق التحكم في واجهة المستخدم، كما أنّه أقل مرونة في التعامل مع الأخطاء التي يرتكبها المستخدمون.

إضافة أدوات معالجة الأحداث

في Chrome (الإصدار 55 والإصدارات الأحدث)، وInternet Explorer وEdge، PointerEvents، يُنصح باستخدام هذه الطريقة لتنفيذ الإيماءات المخصّصة.

في المتصفّحات الأخرى، يُرجى استخدام TouchEvents وMouseEvents.

تتمثل الميزة الرائعة في PointerEvents في أنّه يدمج أنواعًا متعدّدة من الإدخال، بما في ذلك أحداث الماوس واللمس والقلم، في مجموعة واحدة من الطلبات المُعاد تنفيذها. الأحداث التي يجب الاستماع إليها هي pointerdown وpointermove pointerup وpointercancel.

إنّ الرموز المماثلة في المتصفّحات الأخرى هي touchstart وtouchmove touchend وtouchcancel لأحداث اللمس، وإذا أردت تنفيذ الحركة نفسها لإدخال الماوس، عليك تنفيذ mousedown mousemove وmouseup.

إذا كانت لديك أسئلة حول الأحداث التي يجب استخدامها، اطّلِع على جدول أحداث اللمس والماوس والمؤشر.

يتطلّب استخدام هذه الأحداث استدعاء طريقة addEventListener() على عنصر DOM ، بالإضافة إلى اسم حدث ودالّة ردّ اتصال وقيمة منطقية. تحدد القيمة المنطقية ما إذا كان يجب عليك مشاهدة الحدث قبل أو بعد حصول العناصر الأخرى على الفرصة لاكتشاف الأحداث وتفسيرها. (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);

التجربة

وباتباع نمط إضافة حدث النقل إلى المستند، إذا بدأ المستخدم في التفاعل مع عنصر وتحريك إيماءته خارج العنصر، فسنستمر في الحصول على حركات الماوس بغض النظر عن مكان وجودها في الصفحة، نظرًا لأنه يتم استلام الأحداث من المستند.

يوضِّح هذا المخطّط البياني ما تفعله أحداث اللمس عند إضافة حدثَي التحرك والانتهاء إلى المستند بعد بدء إيماءة.

توضيح أحداث اللمس الملزمة لتوثيقها في
&quot;Touchstart&quot;

الاستجابة للمس بكفاءة

بعد أن عالجنا أحداث البدء والانتهاء، يمكننا الآن الاستجابة لأحداث اللمس.

بالنسبة إلى أيّ من أحداث البدء والنقل، يمكنك بسهولة استخراج x وy من حدث.

يتحقّق المثال التالي ممّا إذا كان الحدث من TouchEvent من خلال التحقّق ممّا إذا كان targetTouches متوفّرًا. إذا كان الأمر كذلك، يتم استخراج 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

بما أنّ عمليات استدعاء الأحداث يتم تشغيلها في سلسلة المهام الرئيسية، نريد تنفيذ أقل قدر ممكن من الرموز البرمجية في عمليات استدعاء الأحداث، مع الحفاظ على معدل عرض اللقطات مرتفعًا ومنع حدوث تقطُّع.

باستخدام requestAnimationFrame()، تتوفّر لنا فرصة لتعديل واجهة المستخدم قبل أن يرسم المتصفّح إطارًا، ما سيساعدنا في نقل بعض المهام من وظائف الاستدعاء للأحداث.

إذا لم تكن على دراية بخدمة requestAnimationFrame()، يمكنك الاطّلاع على مزيد من المعلومات هنا.

يتمثل التنفيذ المعتاد في حفظ الإحداثيات x وy من حدثَي x وy وطلب إطار للحركة داخل x.

في العرض التقديمي، نخزّن موضع اللمس الأوّلي في 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() كدالّة ردّ الاتصال:

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 غير صحيحة، ما يشير إلى ما إذا كان requestAnimationFrame() قد استدعى onAnimFrame() منذ حدث النقل الأخير. وهذا يعني أنّ لدينا 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 الشائعة الاستخدام:

مَعلمات إجراءات اللمس
touch-action: none لن يعالج المتصفّح أي تفاعلات باللمس.
touch-action: pinch-zoom يوقف هذا الخيار جميع تفاعلات المتصفّح، مثل "touch-action: none" باستثناء "pinch-zoom" الذي يعالجه المتصفّح إلى الآن.
touch-action: pan-y pinch-zoom يجب معالجة عمليات التمرير الأفقي في JavaScript بدون إيقاف التمرير العمودي أو التصغير/التكبير باستخدام إصبعَين (مثل لوحات العرض الدوّارة للصور).
touch-action: manipulation إيقاف إيماءة النقر المزدوج التي تتجنّب أي تأخير في النقر من قِبل المتصفّح تترك ميزة الانتقال للأعلى أو للأسفل وتصغير المحتوى أو تكبيره للمتصفّح.

التوافق مع الإصدارات القديمة من Internet Explorer

إذا كنت تريد إتاحة استخدام 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;
}

لمزيد من المعلومات، يمكنك الاطّلاع على مقالة التحديثات هذه من Microsoft.

مَراجع

الفئات الزائفة لحالات اللمس

دورات تدريبية مثال الوصف
:hover
الزر في الحالة المضغوطة
يتم إدخالها عند وضع مؤشر فوق عنصر. إنّ التغييرات في واجهة المستخدم عند التمرير فوقها مفيدة لتشجيع المستخدمين على التفاعل مع العناصر.
‎:focus
زرّ في حالة التركيز
يتم إدخاله عندما ينتقل المستخدم بين العناصر في الصفحة باستخدام مفتاح التبويب. تسمح حالة التركيز للمستخدم بمعرفة العنصر الذي يتفاعل معه حاليًا، كما تسمح للمستخدمين بالتنقّل في واجهة المستخدم بسهولة باستخدام لوحة مفاتيح.
‎:active
الزر في الحالة المضغوطة
يتم إدخاله عند اختيار عنصر، مثلاً، عندما ينقر المستخدم على عنصر أو يلمسه.

يمكنك العثور على المرجع النهائي لأحداث اللمس هنا: أحداث اللمس في W3C.

أحداث اللمس والماوس والمؤشر

هذه الأحداث هي اللبنات الأساسية لإضافة إيماءات جديدة إلى تطبيقك:

أحداث اللمس والماوس والمؤشر
touchstart، mousedown، pointerdown يتمّ استدعاء هذا الإجراء عندما يلمس إصبع المستخدم عنصرًا لأول مرّة أو عندما ينقر المستخدم على الماوس.
touchmove، mousemove، pointermove يتمّ استدعاء هذا الإجراء عندما يحرِّك المستخدِم إصبعه على الشاشة أو يسحب باستخدام الماوس.
touchend، mouseup، pointerup يتمّ استدعاء هذا الحدث عندما يرفع المستخدم إصبعه عن الشاشة أو يُفلِت الماوس.
touchcancel pointercancel يتمّ استدعاء هذا الإجراء عندما يلغي المتصفّح إيماءات اللمس. على سبيل المثال، يلمس أحد المستخدمين تطبيق ويب ثم يغيّر علامات التبويب.

قوائم اللمس

يتضمّن كل حدث لمس ثلاث سمات قائمة:

سمات أحداث اللمس
touches قائمة بجميع اللمسات الحالية على الشاشة، بغض النظر عن العناصر التي يتم لمسها
targetTouches قائمة اللمسات التي بدأت على العنصر المستهدف للحدث الحالي. على سبيل المثال، إذا ربطت العنصر بـ <button>، لن تتلقّى سوى اللمسات على هذا الزر حاليًا. إذا التزمت بالمستند، ستحصل على جميع اللمسات الحالية على المستند.
changedTouches قائمة اللمسات التي تغيّرت نتيجةً لإطلاق الحدث:
  • بالنسبة إلى الحدث touchstart ، يتم عرض قائمة بنقاط الاتصال التي أصبحت نشطة للتو مع الحدث الحالي.
  • بالنسبة إلى الفعالية touchmove، قائمة بنقاط الاتصال التي تم نقلها منذ آخر فعالية.
  • بالنسبة إلى حدثَي touchend و touchcancel ، يتم عرض قائمة بنقاط الاتصال التي تمت إزالتها للتو من السطح.

تفعيل دعم الحالة النشطة على iOS

للأسف، لا يطبّق متصفّح Safari على iOS الحالة active تلقائيًا. لتفعيل الخدمة، يجب إضافة أداة معالجة الأحداث 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);
    }
  }
};