تُعلمك IntersectionObservers عندما يدخل عنصر قيد المراقبة إلى إطار عرض المتصفّح أو يخرج منه.
لنفترض أنك تريد تتبع وصول عنصر في نموذج العناصر في المستند (DOM) إلى إطار العرض المرئي. قد تحتاج إلى إجراء ذلك حتى تتمكّن من تحميل الصور بشكل بطيء في الوقت المناسب أو لأنّك بحاجة إلى معرفة ما إذا كان المستخدم ينظر فعلاً إلى بانر إعلاني معيّن. يمكنك إجراء ذلك من خلال ربط حدث الانتقال للأعلى أو للأسفل أو باستخدام موقّت دوري واستدعاء getBoundingClientRect()
على هذا العنصر.
ومع ذلك، فإنّ هذا الأسلوب بطيء جدًا لأنّ كلّ طلب إلى getBoundingClientRect()
يفرض على المتصفّح إعادة ترتيب الصفحة بأكملها وسيؤدي إلى حدوث تقطُّع كبير في موقعك الإلكتروني. تقترب المسائل القانونية من المستحيل عندما تعلم أنّه يتم تحميل موقعك الإلكتروني داخل إطار iframe وتريد معرفة الوقت الذي يمكن للمستخدم رؤية عنصر فيه. لن يسمح لك نموذج المصدر الواحد والمتصفّح بالوصول إلى أي بيانات من صفحة الويب التي تحتوي على إطار iframe. هذه مشكلة شائعة في الإعلانات، على سبيل المثال، التي يتم تحميلها كثيرًا باستخدام إطارات iframe.
إنّ جعل اختبار مستوى الظهور هذا أكثر كفاءة هو ما تم تصميم IntersectionObserver
، وتم توفيره في جميع المتصفحات الحديثة. يُعلمك مقياس IntersectionObserver
عندما يدخل عنصر قيد المراقبة إلى إطار عرض المتصفّح أو يخرج منه.
كيفية إنشاء IntersectionObserver
واجهة برمجة التطبيقات صغيرة إلى حدٍ ما، ويمكن وصفها على أفضل وجه باستخدام مثال:
const io = new IntersectionObserver(entries => {
console.log(entries);
}, {
/* Using default options. Details below */
});
// Start observing an element
io.observe(element);
// Stop observing an element
// io.unobserve(element);
// Disable entire IntersectionObserver
// io.disconnect();
باستخدام الخيارات التلقائية لسمة IntersectionObserver
، سيتمّ استدعاء الدالة المُعاد الاتصال بها عند ظهور العنصر جزئيًا في العرض وعند خروجه بالكامل من إطار العرض.
إذا كنت بحاجة إلى مراقبة عناصر متعدّدة، من الممكن وننصح بمراقبة عناصر متعدّدة باستخدام مثيل IntersectionObserver
نفسه من خلال استدعاء observe()
عدّة مرات.
يتم تمرير مَعلمة entries
إلى دالة ردّ الاتصال التي هي مصفوفة من عناصر IntersectionObserverEntry
. يحتوي كل عنصر على هذا النوع من البيانات على بيانات تقاطع معدّلة لأحد العناصر التي تم رصدها.
🔽[IntersectionObserverEntry]
time: 3893.92
🔽rootBounds: ClientRect
bottom: 920
height: 1024
left: 0
right: 1024
top: 0
width: 920
🔽boundingClientRect: ClientRect
// ...
🔽intersectionRect: ClientRect
// ...
intersectionRatio: 0.54
🔽target: div#observee
// ...
rootBounds
هي نتيجة استدعاء getBoundingClientRect()
على العنصر الجذر، وهو إطار العرض تلقائيًا. boundingClientRect
هي نتيجة getBoundingClientRect()
التي تمّت دعوتها على العنصر المرصود. يمثّل intersectionRect
تقاطع المستطيلين ويوضّح لك بفعالية الجزء المرئي من العنصر المرصود. يرتبط مقياس intersectionRatio
ارتباطًا وثيقًا بمقياس العرض، ويُعلمك بمقدار العنصر المرئي. باستخدام هذه المعلومات، يمكنك الآن تنفيذ ميزات مثل تحميل مواد العرض في الوقت المناسب قبل أن تصبح مرئية على الشاشة. فعّالة
تقدِّم IntersectionObserver
البيانات بشكلٍ غير متزامن، وسيتم تنفيذ رمز معاودة الاتصال في سلسلة المحادثات الرئيسية. بالإضافة إلى ذلك، تشير المواصفات إلى أنّ عمليات تنفيذ IntersectionObserver
يجب أن تستخدم requestIdleCallback()
. وهذا يعني أنّ طلب ردّ الاتصال المقدَّم منك له أولوية منخفضة وسيجريه المتصفّح خلال وقت السكون. هذا قرار تصميم مدروس.
أقسام div التي يمكن التمرير فيها
لستُ من المعجبين كثيرًا بالتمرير داخل أحد العناصر، ولكنني لست هنا للحكم، وكذلك IntersectionObserver
. يأخذ عنصر options
خيار root
الذي يتيح لك تحديد بديل لمساحة العرض كجذر. من المهم أن تضع في اعتبارك أن root
يجب أن يكون أصلاً لجميع العناصر المرصودة.
تقاطع كل الأشياء
لا مطوِّر سيئ وهذا الاستخدام غير مدروس لدورات وحدة المعالجة المركزية للمستخدم. لنفكّر في شريط التمرير اللانهائي كمثال: في هذا السيناريو، من المستحسن بالتأكيد إضافة عناصر مراقبة إلى DOM ومراقبة هذه العناصر (وإعادة استخدامها). يجب إضافة حارس بالقرب من العنصر الأخير في شريط التمرير اللانهائي. عندما يظهر هذا العنصر، يمكنك استخدام دالة الاستدعاء لتحميل البيانات وإنشاء العناصر التالية وإرفاقها بعنصر DOM وإعادة وضع العنصر المراقب وفقًا لذلك. في حال إعادة تدوير أداة المراقبة بشكل صحيح، لن يكون هناك حاجة إلى إجراء مكالمة إضافية إلى observe()
. يستمر تطبيق IntersectionObserver
في العمل.
المزيد من التحديثات، يُرجى
كما ذكرنا سابقًا، سيتم تشغيل دالة الاستدعاء مرة واحدة عندما يظهر العنصر المرصود جزئيًا في العرض ومرة أخرى عندما يغادر إطار العرض. بهذه الطريقة يقدم لك IntersectionObserver
إجابة على السؤال، "هل العنصر X ظاهر؟". في بعض حالات الاستخدام، قد لا يكون ذلك كافيًا.
وهنا يأتي دور خيار threshold
. يتيح لك تحديد صفيف من حدود intersectionRatio
. سيتمّ استدعاء الدالة المخصّصة للردّ في كلّ مرّة يتجاوز فيها intersectionRatio
إحدى هذه القيم. القيمة التلقائية للعنصر threshold
هي [0]
، ما يفسّر السلوك التلقائي. إذا غيّرنا threshold
إلى [0, 0.25, 0.5, 0.75, 1]
، سنتلقّى إشعارًا في كل مرة يصبح فيها ربع إضافي من العنصر مرئيًا:
هل لديك خيارات أخرى؟
في الوقت الحالي، يتوفّر خيار إضافي واحد فقط إلى جانب الخيارات المذكورة أعلاه. يسمح لك الرمز rootMargin
بتحديد الهوامش للجذر، ما يتيح لك بشكل فعّال تكبير المنطقة المستخدَمة للتقاطعات أو تصغيرها. يتم تحديد هذه الهوامش باستخدام سلسلة بأسلوب CSS، مثل "10px 20px 30px 40px"
، لتحديد الهامش العلوي والأيمن والسفلي والأيسر على التوالي. باختصار، تقدّم بنية الخيارات IntersectionObserver
الخيارات التالية:
new IntersectionObserver(entries => {/* … */}, {
// The root to use for intersection.
// If not provided, use the top-level document's viewport.
root: null,
// Same as margin, can be 1, 2, 3 or 4 components, possibly negative lengths.
// If an explicit root element is specified, components may be percentages of the
// root element size. If no explicit root element is specified, using a
// percentage is an error.
rootMargin: "0px",
// Threshold(s) at which to trigger callback, specified as a ratio, or list of
// ratios, of (visible area / total area) of the observed element (hence all
// entries must be in the range [0, 1]). Callback will be invoked when the
// visible ratio of the observed element crosses a threshold in the list.
threshold: [0],
});
سحر <iframe>
تم تصميم IntersectionObserver
خصيصًا مع وضع خدمات الإعلانات وتطبيقات الشبكات الاجتماعية المصغّرة في الاعتبار، والتي تستخدم عناصر <iframe>
بشكل متكرّر ويمكن أن تستفيد من معرفة ما إذا كانت مرئية. إذا رصدت علامة <iframe>
أحد عناصرها، سيؤدي الانتقال للأعلى أو للأسفل في <iframe>
وكذلك الانتقال للأعلى أو للأسفل في النافذة التي تحتوي على <iframe>
إلى تشغيل دالة الاستدعاء في الأوقات المناسبة. في الحالة الأخيرة، سيتم ضبط rootBounds
على null
لتجنُّب تسرُّب البيانات في جميع مصادر البيانات.
ما هو موضوع IntersectionObserver
Not؟
يُرجى العِلم أنّ IntersectionObserver
لا يقدّم جودة دقة بكسل مثالية أو وقت استجابة منخفضًا عن قصد. ومن المؤكد أنّ استخدامها لتنفيذ مشاريع مثل الصور المتحركة التي تعتمد على الانتقال إلى الأسفل أو للأعلى سيؤدي إلى الفشل، لأنّ البيانات ستكون قديمة بحلول الوقت الذي ستتمكن فيه من استخدامها. يتضمّن الشرح المزيد من التفاصيل حول حالات الاستخدام الأصلية لـ IntersectionObserver
.
ما هو حجم العمل الذي يمكنني تنفيذه في المكالمة المُعاد توجيهها؟
نصيحة موجزة: سيؤدي قضاء وقت طويل في طلب إعادة الاتصال إلى تأخُّر تطبيقك، وينطبق ذلك على جميع الممارسات الشائعة.
احرص على تداخل العناصر.
يتوافق المتصفّح مع IntersectionObserver
بشكل جيد، لأنّه متوفّر في جميع المتصفّحات الحديثة. وإذا لزم الأمر، يمكن استخدام رمز polyfill في المتصفحات القديمة وهو متاح في مستودع WICG. من الواضح أنّك لن تحصل على مزايا الأداء التي يوفّرها لك التنفيذ الأصلي باستخدام هذا العنصر البديل.
يمكنك بدء استخدام IntersectionObserver
الآن. أخبِرنا بالحلّ الذي تمكّنت من الوصول إليه.