اعتماد خوب است، مشاهده بهترین است: Intersection Observer نسخه ۲

Browser Support

  • کروم: ۵۱.
  • لبه: ۱۵.
  • فایرفاکس: ۵۵.
  • سافاری: ۱۲.۱.

Source

Intersection Observer یکی از آن APIهایی است که احتمالاً مورد علاقه جهانی است و در همه مرورگرهای اصلی قابل استفاده است. توسعه‌دهندگان از این API برای طیف گسترده‌ای از موارد استفاده، از جمله بارگذاری تنبل تصاویر و ویدیوها ، اعلان‌ها هنگام رسیدن عناصر به position: sticky ، اجرای رویدادهای تحلیلی و بسیاری موارد دیگر استفاده کرده‌اند.

در ابتدایی‌ترین شکل، رابط برنامه‌نویسی کاربردی (API) مربوط به Intersection Observer نسخه ۱ به این شکل است:

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'));

چالش‌های دید در Intersection Observer نسخه ۱

با استفاده از API مربوط به Intersection Observer نسخه ۱، می‌توانید متوجه شوید که چه زمانی یک عنصر به داخل نمای پنجره اسکرول می‌شود. با این حال، نمی‌توانید تشخیص دهید که آیا آن عنصر توسط محتوای صفحه دیگری که به عنوان انسداد شناخته می‌شود، پوشانده شده است یا خیر، یا اینکه آیا عنصر توسط CSS مانند transform ، opacity یا filter تغییر یافته است یا خیر، که ممکن است عنصر را نامرئی کند.

برای یک عنصر در سند سطح بالا، این اطلاعات را می‌توان با تجزیه و تحلیل DOM با جاوا اسکریپت، به عنوان مثال با DocumentOrShadowRoot.elementFromPoint() تعیین کرد. در مقابل، اگر عنصر مورد نظر در یک iframe شخص ثالث قرار داشته باشد، نمی‌توان همان اطلاعات را به دست آورد.

چرا دیده شدن مهم است؟

متأسفانه، اینترنت بازیگران بدی دارد. به عنوان مثال، یک ناشر متقلب ممکن است از تبلیغات کلیکی در یک وب‌سایت استفاده کند. آنها ممکن است کاربران را فریب دهند تا روی این تبلیغات کلیک کنند تا پول بیشتری کسب کنند، حداقل تا زمانی که شبکه تبلیغاتی متوجه نقشه آنها شود. معمولاً چنین تبلیغاتی در iframeها ارائه می‌شوند.

برای فریب کاربران، ناشر می‌تواند آی‌فریم‌های تبلیغاتی را با استفاده از CSS کاملاً شفاف کند: iframe { opacity: 0; } . سپس، می‌تواند این آی‌فریم‌های شفاف را روی محتوای جذابی مانند یک ویدیوی گربه بامزه که کاربران می‌خواهند روی آن کلیک کنند، قرار دهد. به این کار کلیک‌ربایی می‌گویند.

می‌توانید چنین حمله‌ی کلیک‌ربایی را در عمل در بخش بالایی نسخه‌ی نمایشی ما مشاهده کنید. ویدیوی گربه را «تماشا» کنید و حالت ترفند را فعال کنید. تبلیغ موجود در iframe، کلیک‌ها را به عنوان کلیک‌های قانونی ثبت می‌کند، حتی اگر شما (به طور غیرعمدی) در حالی که iframe شفاف بوده است، روی آن کلیک کرده باشید.

فریب دادن کاربر برای کلیک روی یک تبلیغ با شفاف کردن آن و قرار دادن آن روی چیزی جذاب.

بهبودهایی در نرم‌افزار Intersection Observer نسخه ۲

Intersection Observer نسخه ۲ می‌تواند «قابلیت مشاهده» یک عنصر را همانطور که یک انسان تعریف می‌کند، ردیابی کند. اگر گزینه‌ای را در سازنده IntersectionObserver تنظیم کنید، نمونه‌های IntersectionObserverEntry حاصل شامل یک فیلد بولی جدید به نام isVisible می‌شوند. وقتی isVisible برابر با true باشد، مرورگر مطمئن می‌شود که عنصر کاملاً توسط محتوای دیگر آشکار شده و هیچ جلوه بصری ندارد که نمایش آن را پنهان یا تغییر دهد. اگر isVisible برابر با false باشد، مرورگر نمی‌تواند این تضمین را بدهد.

این مشخصات امکان تشخیص نادرست را فراهم می‌کند: isVisible می‌تواند false باشد، حتی زمانی که عنصر واقعاً قابل مشاهده و بدون تغییر است. برای عملکرد، مرورگرها از محاسبات ساده‌تری مانند کادرهای مرزی و اشکال مستطیلی استفاده می‌کنند و هر پیکسل را برای جزئیات پیچیده‌ای مانند border-radius بررسی نمی‌کنند.

با این حال، نتایج مثبت کاذب تحت هیچ شرایطی مجاز نیستند. این بدان معناست که اگر عنصر کاملاً قابل مشاهده و بدون تغییر نباشد، isVisible true نخواهد داشت.

اعمال این تغییرات

سازنده‌ی IntersectionObserver اکنون دو ویژگی پیکربندی اضافی را می‌پذیرد:

  • delay عددی است که حداقل تأخیر بین اعلان‌های ناظر را برای یک هدف مشخص، بر حسب میلی‌ثانیه نشان می‌دهد.
  • trackVisibility یک مقدار بولی است که نشان می‌دهد آیا ناظر تغییرات در میزان دید هدف را دنبال خواهد کرد یا خیر.

وقتی trackVisibility روی true تنظیم شده باشد، delay باید روی 100 یا مقداری بالاتر تنظیم شود (یعنی، بیش از یک اعلان در هر ۱۰۰ میلی‌ثانیه نباشد). از آنجایی که محاسبه visibility پرهزینه است، این یک اقدام احتیاطی در برابر کاهش عملکرد و مصرف باتری است. توسعه‌دهندگان مسئول باید از بزرگترین مقدار قابل تحمل برای delay استفاده کنند.

spec ، قابلیت مشاهده را محاسبه می‌کند. مانند نسخه ۱، وقتی ویژگی trackVisibility ناظر false باشد، هدف قابل مشاهده در نظر گرفته می‌شود.

در نسخه ۲، هدف در صورت وجود شرایط زیر نامرئی در نظر گرفته می‌شود:

  • این یک ماتریس تبدیل مؤثر دارد، غیر از یک انتقال دوبعدی یا ارتقاء دوبعدی متناسب.

  • هدف یا هر عنصری در زنجیره بلوک حاوی آن، دارای شفافیت مؤثر کمتر از ۱.۰ است.

  • فیلتری روی هدف یا هر عنصری در زنجیره بلوک حاوی آن اعمال شده است.

  • اگر پیاده‌سازی نتواند تضمین کند که هدف کاملاً توسط محتوای صفحه دیگر مسدود نشده است.

این یعنی پیاده‌سازی‌های فعلی در تضمین دیده شدن عنصر بسیار محافظه‌کارانه عمل می‌کنند. برای مثال، اعمال یک فیلتر خاکستری تقریباً نامحسوس ( filter: grayscale(0.01%) ) یا تنظیم کمترین میزان شفافیت ( opacity: 0.99 ) باعث می‌شود عنصر نامرئی شود.

در اینجا نمونه کدی وجود دارد که ویژگی‌های جدید API را نشان می‌دهد. می‌توانید منطق ردیابی کلیک آن را در عمل در بخش دوم نسخه آزمایشی مشاهده کنید. ویدیوی توله سگ را "تماشا کنید". حالت ترفند را فعال کنید تا خود را به یک بازیگر بد تبدیل کنید و ببینید که چگونه Intersection Observer نسخه ۲ از ردیابی کلیک‌های تبلیغاتی غیرمجاز جلوگیری می‌کند. Intersection Observer نسخه ۲ از ما محافظت می‌کند.

نرم‌افزار 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 v2, fallback 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'));

منابع اضافی

تقدیرنامه‌ها

با تشکر از سیمئون وینسنت ، یوآو وایس و ماتیاس بیننز برای بررسی، و همچنین استفان زاگر برای بررسی و پیاده‌سازی این ویژگی در کروم.