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

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

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

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

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

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

يمكن أن تكتسب عناصر 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;
}

التجربة الآن

صورة توضح ألوانًا مختلفة
لحالات الأزرار

في معظم متصفحات الأجهزة الجوّالة، سيتم تطبيق حالات hover و/أو hover على أحد العناصر بعد النقر عليه.

ضع في اعتبارك بعناية الأنماط التي تقوم بتعيينها وكيف ستبدو للمستخدم بعد الانتهاء من لمسه.

إيقاف أنماط المتصفح التلقائية

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

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

.btn:focus {
    outline: 0;

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

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

/* 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">

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

الفئة الزائفة -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;
}

التجربة الآن

إيقاف اختيار المستخدم

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

يمكنك استخدام السمة user-select في CSS، ولكن عليك الانتباه إلى أنّ تنفيذ هذا الإجراء على المحتوى قد يكون مزعجًا extremely للمستخدمين إذا أرادوا تحديد النص في العنصر. لذلك يُرجى التأكد من استخدامه بحذر وبشكل باعتدال.

/* 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. بالنسبة إلى أحداث Mouseالأحداث، أضِف حدث البدء فقط.
  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);

التجربة الآن

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

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

توضيح أحداث اللمس الملزِمة لتوثيقها في
` touchstart`

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

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

بالنسبة إلى أي من أحداث البدء ونقل، يمكنك بسهولة استخراج 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 من حدثَي البدء والنقل وطلب إطار صور متحركة داخل معاودة الاتصال بحدث النقل.

في العرض التوضيحي، نخزّن موضع اللمس الأولي في 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 غير صحيح، مما يشير إلى ما إذا تم طلب 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 الشائعة الاستخدام:

مَعلمات إجراءات اللمس
touch-action: none لن يتعامل المتصفّح مع أي تفاعلات اللمس.
touch-action: pinch-zoom لإيقاف جميع تفاعلات المتصفّح، مثل " touch-action: none" باستثناء "التصغير أو التكبير بإصبعين"، الذي لا يزال المتصفّح يعالجه.
touch-action: pan-y pinch-zoom معالجة عمليات التمرير الأفقي في JavaScript بدون إيقاف التمرير العمودي أو التكبير أو التصغير بإصبعين (مثل لوحات العرض الدوّارة للصور)
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;
}

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

مَراجع

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

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

يمكنك الاطّلاع على المرجع النهائي لأحداث اللمس على الرابط: W3C Touch Events.

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

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

أحداث اللمس والماوس والمؤشر
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);
    }
  }
};