برنامج IntersectionObserver قيد العرض

تتيح لك أداة IntersectionMonitorers معرفة وقت دخول عنصر تمت ملاحظته إلى إطار عرض المتصفّح أو الخروج منه.

التوافق مع المتصفح

  • 51
  • 15
  • 55
  • 12.1

المصدر

لنفترض أنك تريد تتبُّع وقت دخول عنصر في نموذج العناصر في المستند (DOM) إلى إطار العرض المرئي. وننصحك بإجراء ذلك لتتمكّن من استخدام طريقة التحميل الكسول للصور في الوقت المناسب أو لأنّك تحتاج إلى معرفة ما إذا كان المستخدِم ينظر إلى إعلان بانر معيّن. يمكنك إجراء ذلك من خلال تثبيت حدث الانتقال للأعلى أو للأسفل أو استخدام موقّت دوري واستدعاء الرمز getBoundingClientRect() على ذلك العنصر.

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

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

إمكانية رؤية إطار iframe

كيفية إنشاء 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 يجب أن يكون أصلاً لجميع العناصر المرصودة.

تتداخل في كل الأشياء!

لا مطور سيئ! هذا ليس استخدامًا مدركًا لدورات وحدة المعالجة المركزية (CPU) لدى المستخدم. لنأخذ مثال على تمرير لا نهائي: في هذا السيناريو، من المستحسن إضافة أدوات الحماية إلى نموذج العناصر في المستند (DOM) وتتبُّعها (وإعادة تدويرها). عليك إضافة عنصر حارس بالقرب من العنصر الأخير في شريط التمرير اللا نهائي. عندما يظهر هذا الموجه، يمكنك استخدام معاودة الاتصال لتحميل البيانات وإنشاء العناصر التالية وإرفاقها بنموذج العناصر في المستند وإعادة ضبط موضع الإرسال وفقًا لذلك. إذا أعدت تدوير الحارس بشكل صحيح، ليس عليك إجراء مكالمة إضافية مع "observe()". يستمر IntersectionObserver في العمل.

تمرير لا نهائي

يُرجى إعلامنا بمزيد من الأخبار

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

وهنا يأتي دور خيار threshold. تسمح لك هذه السياسة بتحديد مصفوفة من حدود intersectionRatio. سيتم طلب معاودة الاتصال في كل مرة تتجاوز فيها intersectionRatio إحدى هذه القيم. القيمة التلقائية للسمة threshold هي [0]، ما يفسّر السلوك التلقائي. إذا تم تغيير threshold إلى [0, 0.25, 0.5, 0.75, 1]، سنتلقّى إشعارًا في كل مرة يظهر فيها ربع إضافي من العنصر:

المؤثرات الحركية للحد الأدنى

هل لديك خيارات أخرى؟

اعتبارًا من الآن، هناك خيار إضافي واحد فقط إلى تلك الخيارات المذكورة أعلاه. تتيح لك rootMargin تحديد هوامش الجذر، ما يتيح لك بشكلٍ فعّال زيادة المساحة المستخدمة للتقاطعات أو تقليصها. ويتم تحديد هذه الهوامش باستخدام سلسلة بنمط CSS، á la "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 لا؟

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

ما مقدار العمل الذي يمكنني تنفيذه في معاودة الاتصال؟

Short 'n (اللطيفة): قضاء الكثير من الوقت في معاودة الاتصال يجعل تطبيقك متأخِّرًا - تنطبق جميع الممارسات الشائعة.

تقديم وتقاطع العناصر الخاصة بك

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

يمكنك بدء استخدام "IntersectionObserver" الآن. يُرجى إخبارنا بما توصلت إليه.