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

Intersection Observer v2 این قابلیت را اضافه می کند که نه تنها تقاطع ها را به خودی خود مشاهده می کند، بلکه همچنین می تواند تشخیص دهد که آیا عنصر متقاطع در زمان تقاطع قابل مشاهده بوده است یا خیر.

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

برای جزئیات کامل، اسناد Intersection Observer را در MDN بررسی کنید، اما به عنوان یک یادآوری کوتاه، این همان چیزی است که Intersection Observer v1 API در ابتدایی ترین حالت به نظر می رسد:

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 v1 چالش برانگیز است؟

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

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

چرا دید واقعی اینقدر مهم است؟

متاسفانه اینترنت جایی است که بازیگران بد را با نیات بدتر جذب می کند. به عنوان مثال، ناشر مخفی که تبلیغات پرداخت به ازای کلیک را در یک سایت محتوا ارائه می دهد، ممکن است تشویق شود تا افراد را فریب دهد تا بر روی تبلیغات آنها کلیک کنند تا پرداخت تبلیغات ناشر را افزایش دهند (حداقل برای مدت کوتاهی، تا زمانی که شبکه تبلیغاتی آنها را جلب کند). به طور معمول، چنین تبلیغاتی در iframe ارائه می شوند. حال اگر ناشر بخواهد کاربران را وادار کند که روی چنین تبلیغاتی کلیک کنند، می توانند iframe های تبلیغاتی را با اعمال یک قانون CSS کاملا شفاف کنند iframe { opacity: 0; } و پوشاندن iframe ها روی چیزی جذاب، مانند یک ویدیوی گربه زیبا که کاربران واقعاً می خواهند روی آن کلیک کنند. به این کار کلیک جک می گویند. شما می‌توانید چنین حمله کلیک‌جکینگی را در بخش بالای این دمو مشاهده کنید (تماشای ویدیوی گربه را امتحان کنید و «حالت ترفند» را فعال کنید). متوجه خواهید شد که تبلیغ در iframe "فکر می کند" کلیک های قانونی دریافت کرده است، حتی اگر زمانی که شما (تظاهر به غیر ارادی) روی آن کلیک کرده اید کاملاً شفاف باشد.

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

Intersection Observer v2 چگونه این مشکل را برطرف می کند؟

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

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

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

کد جدید در عمل چگونه به نظر می رسد؟

سازنده IntersectionObserver اکنون دو ویژگی پیکربندی اضافی را می گیرد: delay و trackVisibility . delay عددی است که نشان‌دهنده حداقل تأخیر در میلی‌ثانیه بین اعلان‌های ناظر برای یک هدف معین است. trackVisibility یک بولی است که نشان می دهد آیا ناظر تغییرات در دید یک هدف را ردیابی خواهد کرد یا خیر.

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

با توجه به مشخصات فعلی، دید به صورت زیر محاسبه می شود:

  • اگر ویژگی trackVisibility ناظر false باشد، هدف قابل مشاهده در نظر گرفته می شود. این با رفتار v1 فعلی مطابقت دارد.

  • اگر هدف دارای یک ماتریس تبدیل مؤثر به غیر از ترجمه دو بعدی یا ارتقاء مقیاس دو بعدی متناسب باشد، هدف نامرئی در نظر گرفته می شود.

  • اگر هدف، یا هر عنصری در زنجیره بلوک حاوی آن، کدورت مؤثری غیر از 1.0 داشته باشد، هدف نامرئی در نظر گرفته می شود.

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

  • اگر پیاده سازی نتواند تضمین کند که هدف به طور کامل توسط محتوای دیگر صفحه مسدود نشده است، آنگاه هدف نامرئی در نظر گرفته می شود.

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

در زیر یک نمونه کد کوتاه آمده است که ویژگی های جدید API را نشان می دهد. می‌توانید منطق ردیابی کلیک آن را در بخش دوم دمو مشاهده کنید (اما اکنون، سعی کنید ویدیوی توله سگ را "تماشا کنید". مطمئن شوید که "حالت ترفند" را دوباره فعال کنید تا فوراً خود را به یک ناشر سایه تبدیل کنید و ببینید چگونه Intersection Observer v2 از ردیابی کلیک های غیر قانونی تبلیغات جلوگیری می کند. این بار، Intersection Observer v2 پشت ماست! 🎉

Intersection Observer v2 از کلیک ناخواسته روی تبلیغ جلوگیری می کند.

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

سپاسگزاریها

از Simeon Vincent ، Yoav Weiss و Mathias Bynens برای بررسی این مقاله و همچنین Stefan Zager برای بررسی و اجرای این ویژگی در کروم تشکر می‌کنیم. تصویر قهرمان توسط سرگئی سمین در Unsplash .