تضيف الإصدار 2 من Intersection Observer إمكانية مراقبة التقاطعات بحد ذاتها، ولكن أيضًا للكشف عمّا إذا كان العنصر المتقاطع مرئيًا في وقت التقاطع.
واجهة برمجة التطبيقات Intersection Observer الإصدار 1 هي إحدى واجهات برمجة التطبيقات التي يُحتمل أن تكون رائجة على مستوى العالم، والآن بعد أن أصبح
Safari متوافقًا معها أيضًا،
أصبح بإمكانك استخدامها على مستوى العالم في جميع المتصفّحات الرئيسية. لمراجعة سريعة لواجهة برمجة التطبيقات،
ننصح بمشاهدة Supercharged Microtip من Surma بشأن الإصدار 1 من Intersection
Observer والمضمّن أدناه.
يمكنك أيضًا قراءة المقالة المفصّلة التي كتبتها "سورما".
استخدَم المستخدمون الإصدار 1 من Intersection Observer لمجموعة كبيرة من حالات الاستخدام، مثل
التحميل البطيء للصور والفيديوهات،
تلقّي إشعارات عند وصول العناصر إلى position: sticky
،
تفعيل أحداث الإحصاءات،
وغير ذلك الكثير.
للاطّلاع على التفاصيل الكاملة، يمكنك الاطّلاع على مستندات Intersection Observer على MDN، ولكن في ما يلي تذكير موجز بكيفية ظهور واجهة برمجة التطبيقات Intersection Observer v1 في أبسط الحالات:
const onIntersection = (entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
console.log(entry);
}
}
};
const observer = new IntersectionObserver(onIntersection);
observer.observe(document.querySelector('#some-target'));
ما هي المشاكل المتعلّقة بالإصدار 1 من Intersection Observer؟
للتوضيح، إنّ الإصدار 1 من Intersection Observer رائع، ولكنه ليس مثاليًا. هناك
بعض الحالات الخاصة التي لا تتوافق فيها واجهة برمجة التطبيقات مع المتطلبات. لنلقِ نظرة عن كثب.
يمكن أن تُعلمك واجهة برمجة التطبيقات Intersection Observer v1 عندما يتم الانتقال إلى عنصر في
مجال عرض النافذة، ولكنّها لا تُعلمك ما إذا كان العنصر مغطّى
بأي محتوى آخر للصفحة (أي عندما يكون العنصر محجوبًا) أو ما إذا كان
قد تم تعديل العرض المرئي للعنصر باستخدام تأثيرات مرئية مثل transform
وopacity
filter
وما إلى ذلك، ما يمكن أن يجعله غير مرئي بشكل فعّال.
بالنسبة إلى عنصر في المستند من المستوى الأعلى، يمكن تحديد هذه المعلومات من خلال تحليل
DOM من خلال JavaScript، على سبيل المثال من خلال
DocumentOrShadowRoot.elementFromPoint()
ثم التعمّق أكثر.
في المقابل، لا يمكن الحصول على المعلومات نفسها إذا كان العنصر المعنيّ
موجودًا في إطار iframe تابع لجهة خارجية.
ما أهمية مستوى الظهور الفعلي؟
يجذب الإنترنت، للأسف، جهات سيئة بنوايا أسوأ.
على سبيل المثال، قد يتم تحفيز ناشر مشبوه يعرض إعلانات "الدفع بالنقرة" على موقع إلكتروني يتضمّن محتوى بهدف
خداع المستخدمين لكي ينقروا على إعلاناته لزيادة عائد الإعلانات الذي يحصل عليه الناشر (على الأقل
لمدة قصيرة، إلى أن ترصده شبكة الإعلانات).
وعادةً ما يتم عرض هذه الإعلانات في إطارات iframe.
إذا أراد الناشر الآن أن يدفع المستخدمين إلى النقر على هذه الإعلانات، يمكنه جعل إطارات iframe للإعلان
شفّافة تمامًا من خلال تطبيق قاعدة CSS iframe { opacity: 0; }
وتداخل إطارات iframe
على شيء جذاب، مثل فيديو قطة لطيفة قد يريد المستخدمون النقر عليه.
ويُعرف هذا الإجراء باسم التصيُّد بالنقر.
يمكنك مشاهدة هجوم خداع بالنقر في الجزء العلوي من هذا
العرض التجريبي (جرِّب "مشاهدة" فيديو القطة
وتفعيل "وضع الخداع").
ستلاحظ أنّ الإعلان في إطار iframe "يظن" أنّه تلقّى نقرات مشروعة، حتى لو كان
شفّافًا تمامًا عند النقر عليه (بطريقة مصطنعة).
كيف يحلّ الإصدار 2 من Intersection Observer هذه المشكلة؟
يقدّم الإصدار 2 من Intersection Observer مفهوم تتبُّع "مستوى الرؤية" الفعلي لعنصر مستهدف، كما يحدّده الشخص.
من خلال ضبط خيار في مُنشئIntersectionObserver
، ستحتوي المثيلات المتعلّقة بالحدود المتلاقية
IntersectionObserverEntry
على حقل منطقي جديد باسم isVisible
.
إنّ قيمة true
لـ isVisible
هي ضمانة قوية من التنفيذ الأساسي
بأنّ العنصر المستهدَف غير محجوب تمامًا عن الرؤية بواسطة محتوى آخر
وأنّه لم يتم تطبيق أيّ تأثيرات مرئية من شأنها تغيير طريقة عرضه على الشاشة أو تشويهها.
في المقابل، تعني قيمة false
أنّ التنفيذ لا يمكنه تقديم هذا الضمان.
من التفاصيل المهمة في
المواصفات
أنّه يُسمح بتسجيل نتائج سلبية خاطئة (أي ضبط isVisible
على false
حتى عندما يكون العنصر المستهدَف مرئيًا بالكامل وغير معدَّل).
لأسباب تتعلّق بالأداء أو لأسباب أخرى، تقتصر المتصفّحات على استخدام مربّعات الحدود والأشكال الهندسية المستقيمة، ولا تحاول تحقيق نتائج دقيقة على مستوى البكسل للتعديلات مثل border-radius
.
ومع ذلك، لا يُسمح بالإيجابيات الزائفة تحت أيّ ظرف (أي ضبط قيمة
isVisible
على true
عندما لا يكون العنصر المستهدَف مرئيًا بالكامل وغير معدَّل).
كيف يبدو الرمز الجديد عمليًا؟
يأخذ الآن مُنشئ IntersectionObserver
سمتَي إعداد إضافيتَين: delay
وtrackVisibility
.
delay
هو رقم يشير إلى الحد الأدنى من التأخير بالمللي ثانية بين الإشعارات الواردة من
المراقِب لهدف معيّن.
trackVisibility
هو قيمة منطقية تشير إلى ما إذا كان المُراقب سيتتبّع التغييرات في
مستوى رؤية الهدف.
من المهمّ ملاحظة أنّه عندما يكون trackVisibility
هو true
، يجب أن يكون delay
هو
100
على الأقل (أي لا يزيد عن إشعار واحد كل 100 ملي ثانية).
كما ذكرنا سابقًا، يتطلّب احتساب مستوى الرؤية تكلفة عالية، وهذا الشرط هو إجراء وقائي لتجنّب
انخفاض الأداء واستهلاك البطارية. سيستخدم المطوِّر المسؤول
أكبر قيمة مقبولة للتأخّر.
وفقًا لحال المواصفات الحالية، يتم احتساب مستوى الرؤية على النحو التالي:
إذا كانت سمة
trackVisibility
للمُراقب هيfalse
، يُعتبر الهدف مرئيًا. يتطابق ذلك مع سلوك الإصدار 1 الحالي.إذا كان الهدف يتضمّن مصفوفة تحويل فعّالة غير الترجمة ثنائية الأبعاد أو التكبير التناسبي ثنائي الأبعاد، يُعدّ الهدف غير مرئي.
إذا كان الهدف أو أي عنصر في سلسلة الكتل التي يحتوي عليها يمتلك مستوى شفافية فعّالًا غير 1.0، يُعتبر الهدف غير مرئي.
إذا تم تطبيق أي فلاتر على الهدف أو أي عنصر في سلسلة الكتل التي يحتوي عليها، يُعتبر الهدف غير مرئي.
إذا لم يتمكّن التنفيذ من ضمان أنّ الهدف غير محجوب تمامًا من خلال محتوى الصفحة الآخر، يُعتبر الهدف غير مرئي.
وهذا يعني أنّ عمليات التنفيذ الحالية متحفظة جدًا في ما يتعلق بضمان مستوى الرؤية.
على سبيل المثال، سيؤدي تطبيق فلتر ألوان رمادية غير ملحوظ تقريبًا مثل filter: grayscale(0.01%)
أو ضبط شفافية غير مرئية تقريبًا باستخدام opacity: 0.99
إلى جعل العنصر
غير مرئي.
في ما يلي نموذج رمز برمجي قصير يوضّح ميزات واجهة برمجة التطبيقات الجديدة. يمكنك الاطّلاع على آلية تتبُّع النقرات في القسم الثاني من العرض التجريبي (ولكن الآن، جرِّب "مشاهدة" فيديو الجرو). احرص على تفعيل "وضع الخداع" مرة أخرى لتحويل نفسك على الفور إلى ناشر مشبوه ومعرفة كيف يمنع الإصدار 2 من Intersection Observer تتبُّع النقرات على الإعلانات غير المشروعة. هذه المرة، يمكننا الاعتماد على الإصدار 2 من Intersection Observer. 🎉
<!DOCTYPE html>
<!-- This is the ad running in the iframe -->
<button id="callToActionButton">Buy now!</button>
// This is code running in the iframe.
// The iframe must be visible for at least 800ms prior to an input event
// for the input event to be considered valid.
const minimumVisibleDuration = 800;
// Keep track of when the button transitioned to a visible state.
let visibleSince = 0;
const button = document.querySelector('#callToActionButton');
button.addEventListener('click', (event) => {
if ((visibleSince > 0) &&
(performance.now() - visibleSince >= minimumVisibleDuration)) {
trackAdClick();
} else {
rejectAdClick();
}
});
const observer = new IntersectionObserver((changes) => {
for (const change of changes) {
// ⚠️ Feature detection
if (typeof change.isVisible === 'undefined') {
// The browser doesn't support Intersection Observer v2, falling back to v1 behavior.
change.isVisible = true;
}
if (change.isIntersecting && change.isVisible) {
visibleSince = change.time;
} else {
visibleSince = 0;
}
}
}, {
threshold: [1.0],
// 🆕 Track the actual visibility of the element
trackVisibility: true,
// 🆕 Set a minimum delay between notifications
delay: 100
}));
// Require that the entire iframe be visible.
observer.observe(document.querySelector('#ad'));
روابط ذات صلة
- أحدث مسودة للمحرِّر من مواصفات Intersection Observer
- Intersection Observer الإصدار 2 على حالة النظام الأساسي Chrome
- خطأ في Chromium في الإصدار 2 من Intersection Observer
- انقر على Intent to Implement posting (الموافقة على نشر المحتوى).
الشكر والتقدير
نشكر سيمون فنسنت، يواف ويس، وماتياس بينينز على مراجعة هذه المقالة، وكذلك ستيفان زاغر بدوره على مراجعة الميزة وتنفيذها في Chrome. الصورة الرئيسية لسيرجي سيمن على Unsplash