भरोसा अच्छा है और निगरानी करना बेहतर है: इंटरसेक्शन ऑब्ज़र्वर v2

इंटरसेक्शन ऑब्ज़र्वर v2, इंटरसेक्शन को सिर्फ़ देखने की सुविधा ही नहीं देता, बल्कि यह भी पता लगाता है कि इंटरसेक्शन के समय इंटरसेक्शन एलिमेंट दिख रहा था या नहीं.

Intersection Observer v1 उन एपीआई में से एक है जो शायद सभी को पसंद है. अब Safari पर भी इसका इस्तेमाल किया जा सकता है. इसलिए, अब इसे सभी मुख्य ब्राउज़र में इस्तेमाल किया जा सकता है. एपीआई के बारे में ज़्यादा जानकारी पाने के लिए, हमारा सुझाव है कि आप Surma की सुपरचार्ज्ड माइक्रोटिप को, इंटरसेक्शन ऑब्ज़र्वर v1 पर देखें. इसे नीचे एम्बेड किया गया है. आप सूरमा का गहराई से लिखा लेख भी पढ़ सकते हैं. लोगों ने Intersection Observer v1 का इस्तेमाल, कई तरह के इस्तेमाल के उदाहरणों के लिए किया है. जैसे, इमेज और वीडियो को लैज़ी लोड करना, एलिमेंट तक पहुंचने पर सूचना पाना, Analytics इवेंट ट्रिगर करना वगैरह.position: sticky

पूरी जानकारी के लिए, MDN पर Intersection Observer के दस्तावेज़ देखें. हालांकि, आपको याद दिला दें कि सबसे बुनियादी मामले में, 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'));

इंटरसेक्शन ऑब्ज़र्वर v1 में क्या चुनौती भरा है?

साफ़ तौर पर बताएं, इंटरसेक्शन ऑब्ज़र्वर v1 बहुत अच्छा है, लेकिन यह पूरी तरह सही नहीं है. कुछ मामलों में, एपीआई काम नहीं करता. आइए, इस पर ज़्यादा ध्यान से नज़र डालते हैं! Intersection Observer v1 API से यह पता चल सकता है कि कोई एलिमेंट, विंडो के व्यूपोर्ट में कब स्क्रोल किया गया. हालांकि, इससे यह पता नहीं चलता कि एलिमेंट को पेज के किसी दूसरे कॉन्टेंट से ढका गया है या नहीं (यानी, एलिमेंट को छिपाया गया है) या transform, opacity, filter वगैरह जैसे विज़ुअल इफ़ेक्ट की मदद से, एलिमेंट के विज़ुअल डिसप्ले में बदलाव किया गया है या नहीं. इन इफ़ेक्ट की वजह से, एलिमेंट असल में नहीं दिखता.

टॉप लेवल दस्तावेज़ के किसी एलिमेंट के लिए, इस जानकारी का पता लगाने के लिए, JavaScript की मदद से DOM का विश्लेषण किया जा सकता है. उदाहरण के लिए, DocumentOrShadowRoot.elementFromPoint() के ज़रिए और फिर ज़्यादा जानकारी हासिल की जा सकती है. इसके उलट, अगर वह एलिमेंट तीसरे पक्ष के iframe में है, तो उससे यह जानकारी नहीं मिल सकती.

विज्ञापन दिखने की दर इतनी अहम क्यों है?

दुर्भाग्य से, इंटरनेट एक ऐसी जगह है जो बुरे मकसद से बुरे मकसद से काम करने वाले लोगों या ग्रुप को आकर्षित करती है. उदाहरण के लिए, किसी कॉन्टेंट साइट पर हर क्लिक के हिसाब से पैसे चुकाने वाले विज्ञापन दिखाने वाले किसी धोखाधड़ी वाले पब्लिशर को, लोगों को अपने विज्ञापनों पर क्लिक करने के लिए गुमराह करने के लिए उकसाया जा सकता है. इससे पब्लिशर को विज्ञापन से मिलने वाला पेआउट बढ़ सकता है. हालांकि, ऐसा कम से कम कुछ समय के लिए ही किया जा सकता है, जब तक कि विज्ञापन नेटवर्क उन्हें पकड़ न ले. आम तौर पर, ऐसे विज्ञापन iframe में दिखाए जाते हैं. अगर पब्लिशर को उपयोगकर्ताओं से ऐसे विज्ञापनों पर क्लिक कराना है, तो वह CSS नियम iframe { opacity: 0; } लागू करके, विज्ञापन के iframes को पूरी तरह से पारदर्शी बना सकता है. साथ ही, iframes को किसी आकर्षक चीज़ के ऊपर ओवरले कर सकता है. जैसे, बिल्ली का कोई प्यारा वीडियो, जिस पर उपयोगकर्ता ज़रूर क्लिक करना चाहेंगे. इसे क्लिकजैकिंग कहा जाता है. इस डेमो के ऊपरी सेक्शन में, इस तरह के क्लिकजैकिंग हमले को देखा जा सकता है. (बिल्ली का वीडियो "देखकर" देखें और "ट्रिक मोड" चालू करें). आप देखेंगे कि iframe में मौजूद विज्ञापन को "सोचता है" कि उसे वैध क्लिक मिले हैं, भले ही आपने (यानी अनजाने में) उस पर क्लिक करते समय पूरी तरह से पारदर्शी हो.

किसी विज्ञापन को पारदर्शी बनाकर और उसे किसी आकर्षक चीज़ के ऊपर ओवरले करके, उपयोगकर्ता को धोखा देकर उस पर क्लिक करवाना.

इंटरसेक्शन ऑब्ज़र्वर v2 इस समस्या को कैसे ठीक करता है?

इंटरसेक्शन ऑब्ज़र्वर v2 में, टारगेट एलिमेंट की "विज़िबिलिटी" को ट्रैक करने का सिद्धांत दिया गया है जैसे कि कोई इंसान खुद इसे तय करेगा. IntersectionObserver कंस्ट्रक्टर में कोई विकल्प सेट करने से, IntersectionObserverEntry इंस्टेंस को इंटरसेक्ट करने पर, उसमें isVisible नाम का एक नया बूलियन फ़ील्ड शामिल हो जाएगा. isVisible के लिए true वैल्यू, लागू किए गए तरीके से इस बात की पुष्टि करती है कि टारगेट एलिमेंट, दूसरे कॉन्टेंट से पूरी तरह से छिपा नहीं है और उस पर कोई ऐसा विज़ुअल इफ़ेक्ट लागू नहीं किया गया है जिससे स्क्रीन पर उसके डिसप्ले में बदलाव या गड़बड़ी हो. इसके उलट, false वैल्यू का मतलब है कि लागू करने से, यह गारंटी नहीं मिल सकती.

स्पेसिफ़िकेशन की एक अहम जानकारी यह है कि लागू करने की सुविधा को गलत नेगेटिव की रिपोर्ट करने की अनुमति है. इसका मतलब है कि टारगेट एलिमेंट पूरी तरह से दिखने और उसमें कोई बदलाव न होने पर भी, isVisible को false पर सेट किया जा सकता है. परफ़ॉर्मेंस या अन्य वजहों से, ब्राउज़र सिर्फ़ बाउंडिंग बॉक्स और रेक्टिलिनियर ज्यामिति के साथ काम करते हैं. वे border-radius जैसे बदलावों के लिए, पिक्सल-परफ़ेक्ट नतीजे पाने की कोशिश नहीं करते.

हालांकि, किसी भी स्थिति में गलत तरीके से सही के तौर पर मार्क करने की अनुमति नहीं है. इसका मतलब है कि टारगेट एलिमेंट पूरी तरह से न दिखने और उसमें बदलाव न होने पर, isVisible को true पर सेट करना.

नए कोड का इस्तेमाल कैसे किया जाता है?

IntersectionObserver कन्स्ट्रक्टर में अब दो अतिरिक्त कॉन्फ़िगरेशन प्रॉपर्टी शामिल की गई हैं: delay और trackVisibility. delay एक संख्या है, जो किसी टारगेट के लिए, ऑब्ज़र्वर से मिली सूचनाओं के बीच के कम से कम समय को मिलीसेकंड में दिखाती है. trackVisibility एक बूलियन है, जो यह बताता है कि ऑब्ज़र्वर, टारगेट के दिखने की स्थिति में हुए बदलावों को ट्रैक करेगा या नहीं.

यहां यह ध्यान रखना ज़रूरी है कि जब trackVisibility true हो, तो delay कम से कम 100 होना चाहिए. इसका मतलब है कि हर 100 मिलीसेकंड में एक से ज़्यादा सूचनाएं नहीं भेजी जा सकतीं. जैसा कि पहले बताया गया है, विज़िबिलिटी का हिसाब लगाना महंगा होता है. इसलिए, यह ज़रूरी है कि आप इसकी जानकारी दें, ताकि परफ़ॉर्मेंस पर असर न पड़े और बैटरी की खपत कम हो. ज़िम्मेदार डेवलपर, देरी के लिए सबसे ज़्यादा वैल्यू का इस्तेमाल करेगा.

मौजूदा स्पेसिफ़िकेशन के मुताबिक, विज्ञापन दिखने की दर का हिसाब इस तरह लगाया जाता है:

  • अगर ऑब्ज़र्वर का trackVisibility एट्रिब्यूट false है, तो टारगेट को दिखने वाला माना जाता है. यह मौजूदा v1 व्यवहार से मेल खाता है.

  • अगर टारगेट में 2D अनुवाद या समानुपातिक 2D अपस्केलिंग के अलावा कोई असरदार ट्रांसफ़ॉर्मेशन मैट्रिक्स है, तो टारगेट को दिखाई न देने वाला मैसेज माना जाता है.

  • अगर टारगेट या उसमें मौजूद ब्लॉक चेन के किसी एलिमेंट की ऑपैसिटी 1.0 के अलावा कोई दूसरी वैल्यू है, तो टारगेट को अदृश्य माना जाता है.

  • अगर टारगेट या उसमें मौजूद ब्लॉक चेन के किसी एलिमेंट पर कोई फ़िल्टर लागू है, तो टारगेट को इनविज़िबल माना जाता है.

  • अगर लागू करने से यह गारंटी नहीं मिलती कि टारगेट, पेज के दूसरे कॉन्टेंट से पूरी तरह से नहीं छिपा है, तो टारगेट को इनविज़िबल माना जाता है.

इसका मतलब है कि दिखने वाले विज्ञापनों को लागू करने का मौजूदा तरीका काफ़ी पुराना है. उदाहरण के लिए, filter: grayscale(0.01%) जैसे ऐसे ग्रेस्केल फ़िल्टर का इस्तेमाल करने पर जो मुश्किल से दिखता है या opacity: 0.99 की मदद से, एलिमेंट को पारदर्शी बनाने पर, वह एलिमेंट दिखना बंद हो जाएगा.

नीचे एक छोटा कोड सैंपल दिया गया है, जिसमें एपीआई की नई सुविधाओं के बारे में बताया गया है. डेमो के दूसरे सेक्शन में, क्लिक ट्रैकिंग के लॉजिक को काम करते हुए देखा जा सकता है. हालांकि, अब पप्पी का वीडियो "देखें". खुद को तुरंत एक संदिग्ध पब्लिशर में बदलने के लिए, "ट्रिक मोड" को फिर से चालू करना न भूलें. इससे आपको यह भी पता चलेगा कि इंटरसेक्शन ऑब्ज़र्वर 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'));

धन्यवाद

इस लेख की समीक्षा करने के लिए, सिमियोन विंसेंट, योव वाइस, और मैथियास बाइनेंस को धन्यवाद. साथ ही, स्टीफ़न ज़ैगर को भी, Chrome में इस सुविधा की समीक्षा करने और इसे लागू करने के लिए धन्यवाद. Unsplash पर, सर्गेई सेमिन की हीरो इमेज.