इंटरसेक्शन ऑब्ज़र्वर' दिख रहा है

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

Browser Support

  • Chrome: 51.
  • Edge: 15.
  • Firefox: 55.
  • Safari: 12.1.

Source

मान लें कि आपको यह ट्रैक करना है कि आपके 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 इससे काफ़ी मिलता-जुलता है. इससे आपको पता चलता है कि एलिमेंट का कितना हिस्सा दिख रहा है. इस जानकारी की मदद से, अब ऐसेट को स्क्रीन पर दिखने से पहले ही लोड करने जैसी सुविधाएं लागू की जा सकती हैं. बेहतर तरीके से.

इंटरसेक्शन रेशियो.

IntersectionObservers अपना डेटा एसिंक्रोनस तरीके से डिलीवर करते हैं. साथ ही, आपका कॉलबैक कोड मुख्य थ्रेड में चलेगा. इसके अलावा, खास जानकारी में यह भी बताया गया है कि IntersectionObserver को लागू करने के लिए, requestIdleCallback() का इस्तेमाल किया जाना चाहिए. इसका मतलब है कि आपके दिए गए कॉलबैक को कम प्राथमिकता दी जाएगी और ब्राउज़र, खाली समय के दौरान कॉल करेगा. यह डिज़ाइन से जुड़ा एक सोच-समझकर लिया गया फ़ैसला है.

स्क्रोलिंग डिव

मुझे किसी एलिमेंट के अंदर स्क्रोल करना पसंद नहीं है. हालांकि, मैं यहां जज करने के लिए नहीं हूं और न ही IntersectionObserver. options ऑब्जेक्ट, root विकल्प लेता है. इससे, व्यूपोर्ट के विकल्प को रूट के तौर पर तय किया जा सकता है. यह ध्यान रखना ज़रूरी है कि root को मॉनिटर किए जा रहे सभी एलिमेंट का पैरंट एलिमेंट होना चाहिए.

सभी चीज़ों को इंटरसेक्ट करें!

नहीं! खराब डेवलपर! यह आपके उपयोगकर्ता के सीपीयू साइकल का सही इस्तेमाल नहीं है. उदाहरण के लिए, इनफ़ाइनाइट स्क्रोलर के बारे में सोचें: इस स्थिति में, डीओएम में सेंटिनल जोड़ना और उन्हें मॉनिटर करना (और रीसाइकल करना!) बेहतर रहेगा. आपको इनफ़ाइनाइट स्क्रोलर में आखिरी आइटम के पास एक सेंटिनल जोड़ना चाहिए. जब वह सेंटिनल दिखता है, तब डेटा लोड करने, अगले आइटम बनाने, उन्हें डीओएम से अटैच करने, और सेंटिनल को फिर से पोज़िशन करने के लिए, कॉलबैक का इस्तेमाल किया जा सकता है. अगर सेंटिनल को सही तरीके से रीसाइकल किया जाता है, तो observe() को फिर से कॉल करने की ज़रूरत नहीं पड़ती. IntersectionObserver काम करता रहता है.

इनफ़ाइनाइट स्क्रोलर

मुझे और अपडेट चाहिए

जैसा कि पहले बताया गया है, कॉलबैक को एक बार तब ट्रिगर किया जाएगा, जब मॉनिटर किया गया एलिमेंट कुछ हद तक व्यू में आ जाएगा. साथ ही, दूसरी बार तब ट्रिगर किया जाएगा, जब वह व्यूपोर्ट से बाहर चला जाएगा. इस तरह, IntersectionObserver आपको इस सवाल का जवाब देता है कि "क्या एलिमेंट X व्यू में है?". हालांकि, कुछ मामलों में यह काफ़ी नहीं होता.

ऐसे में, threshold विकल्प काम आता है. इससे आपको intersectionRatio थ्रेशोल्ड का कलेक्शन तय करने की सुविधा मिलती है. जब भी intersectionRatio इनमें से किसी वैल्यू को पार करेगा, तब आपके कॉलबैक को कॉल किया जाएगा. threshold की डिफ़ॉल्ट वैल्यू [0] है. इससे डिफ़ॉल्ट व्यवहार के बारे में पता चलता है. अगर हम threshold को बदलकर [0, 0.25, 0.5, 0.75, 1] कर देते हैं, तो एलिमेंट का हर अतिरिक्त चौथाई हिस्सा दिखने पर हमें सूचना मिलेगी:

थ्रेशोल्ड ऐनिमेशन.

क्या कोई और विकल्प है?

फ़िलहाल, ऊपर दिए गए विकल्पों के अलावा सिर्फ़ एक और विकल्प उपलब्ध है. rootMargin की मदद से, रूट के लिए मार्जिन तय किए जा सकते हैं. इससे, इंटरसेक्शन के लिए इस्तेमाल किए जाने वाले हिस्से को बढ़ाया या घटाया जा सकता है. इन मार्जिन को सीएसएस-स्टाइल स्ट्रिंग, á 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 के इस्तेमाल के ओरिजनल उदाहरणों के बारे में ज़्यादा जानकारी दी गई है.

कॉलबैक में कितना काम किया जा सकता है?

कॉल बैक में ज़्यादा समय बिताने से, आपके ऐप्लिकेशन में रुकावट आ सकती है. इसलिए, सभी सामान्य तरीकों को लागू करें.

आगे बढ़ें और अपने एलिमेंट को इंटरसेक्ट करें

IntersectionObserver के लिए ब्राउज़र की सहायता अच्छी है, क्योंकि यह सभी मॉडर्न ब्राउज़र में उपलब्ध है. अगर ज़रूरी हो, तो पुराने ब्राउज़र में पॉलीफ़िल का इस्तेमाल किया जा सकता है. यह WICG की रिपॉज़िटरी में उपलब्ध है. ज़ाहिर है कि उस पॉलीफ़िल का इस्तेमाल करने से आपको परफ़ॉर्मेंस के वे फ़ायदे नहीं मिलेंगे जो नेटिव तरीके से लागू करने पर मिलते.

IntersectionObserver का इस्तेमाल अभी से शुरू किया जा सकता है! हमें बताएं कि आपने क्या किया.