यदि वर्तमान व्यूपोर्ट में कोई DOM तत्व दिखाई देता है तो मैं कैसे बता सकता हूं?


949

क्या यह बताने का एक कारगर तरीका है कि क्या कोई DOM तत्व (HTML डॉक्यूमेंट में) वर्तमान में दिखाई दे रहा है ( व्यूपोर्ट में दिखाई देता है )?

(सवाल फ़ायरफ़ॉक्स को संदर्भित करता है।)


निर्भर करता है कि आपके दिखाई देने का क्या मतलब है। यदि आप का अर्थ है कि यह वर्तमान में पृष्ठ पर दिखाया गया है, तो स्क्रॉल स्थिति को देखते हुए, आप इसकी गणना तत्वों y ऑफसेट और वर्तमान स्क्रॉल स्थिति के आधार पर कर सकते हैं।
रॉरीफ

18
स्पष्टीकरण: दृश्यमान, जैसा कि वर्तमान में प्रदर्शित आयत के भीतर है। दृश्यमान, जैसे छिपा या प्रदर्शित नहीं: कोई नहीं? दृश्यमान, जैसा कि जेड-ऑर्डर में कुछ और पीछे नहीं है?
एडम राइट

6
वर्तमान में प्रदर्शित आयत के भीतर की तरह। धन्यवाद। पुनः निर्मित।
बेनजीता

2
ध्यान दें कि यहां दिए गए सभी उत्तर आपको उन वस्तुओं के लिए एक झूठी सकारात्मक देंगे जो उनके मूल तत्व के दृश्य क्षेत्र के बाहर हैं (छिपी हुई अतिप्रवाह के साथ एह) लेकिन व्यूपोर्ट क्षेत्र के अंदर।
एंडी ई

1
एक मिलियन उत्तर हैं और अधिकांश हास्यास्पद रूप से लंबे हैं। दो-लाइनर के लिए यहां देखें
leonheess

जवाबों:


346

अद्यतन: समय मार्च और इतने पर हमारे ब्राउज़र हैं। यह तकनीक अब अनुशंसित नहीं है और आपको 7 से पहले इंटरनेट एक्सप्लोरर के संस्करण का समर्थन करने की आवश्यकता नहीं है, तो आपको डैन के समाधान का उपयोग करना चाहिए ।

मूल समाधान (अब पुराना):

यह जाँच करेगा कि तत्व पूरी तरह से वर्तमान व्यूपोर्ट में दिखाई दे रहा है:

function elementInViewport(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top >= window.pageYOffset &&
    left >= window.pageXOffset &&
    (top + height) <= (window.pageYOffset + window.innerHeight) &&
    (left + width) <= (window.pageXOffset + window.innerWidth)
  );
}

यदि तत्व का कोई भी हिस्सा व्यूपोर्ट में दिखाई दे रहा है, तो आप यह निर्धारित करने के लिए इसे संशोधित कर सकते हैं:

function elementInViewport2(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top < (window.pageYOffset + window.innerHeight) &&
    left < (window.pageXOffset + window.innerWidth) &&
    (top + height) > window.pageYOffset &&
    (left + width) > window.pageXOffset
  );
}

1
मूल फ़ंक्शन में कोई गलती थी।
रिगसाइनिंग

15
क्या होगा अगर तत्व एक स्क्रॉल करने योग्य div में रहता है और एक दृश्य से बाहर स्क्रॉल किया जाता है ??
amartynov

2
कृपया स्क्रिप्ट के एक नए संस्करण की समीक्षा करें
दान

1
@ Amartynov के प्रश्न के बारे में भी उत्सुक। किसी को पता है कि पूर्वजों तत्व के अतिप्रवाह के कारण कोई तत्व छिपा है या नहीं, तो कैसे बताएं? बोनस अगर यह पता लगाया जा सकता है कि बच्चे को कितना गहरा घोंसला है।
एरिक गुयेन

1
DOM के माध्यम से @deadManN को बेहद धीमा माना जाता है। यह पर्याप्त कारण है, लेकिन ब्राउज़र विक्रेताओं ने getBoundingClientRectविशेष रूप से तत्व निर्देशांक खोजने के उद्देश्य से भी बनाया है ... हम इसका उपयोग क्यों नहीं करेंगे?
प्रेस्टुल जूल 6'15

1402

अब अधिकांश ब्राउज़र getBoundingClientRect पद्धति का समर्थन करते हैं , जो सबसे अच्छा अभ्यास बन गया है। एक पुराने उत्तर का उपयोग करना बहुत धीमा है , सटीक नहीं है और इसमें कई बग हैं

सही के रूप में चयनित समाधान लगभग कभी सटीक नहीं होता है । आप इसके बग्स के बारे में अधिक पढ़ सकते हैं


यह समाधान इंटरनेट एक्सप्लोरर 7 (और बाद में), आईओएस 5 (और बाद में) सफारी, एंड्रॉइड 2.0 (एक्लेयर) और बाद में ब्लैकबेरी, ओपेरा मोबाइल और इंटरनेट एक्सप्लोरर मोबाइल 9 पर परीक्षण किया गया था


function isElementInViewport (el) {

    // Special bonus for those using jQuery
    if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
    }

    var rect = el.getBoundingClientRect();

    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
    );
}

कैसे इस्तेमाल करे:

आप यह सुनिश्चित कर सकते हैं कि ऊपर दिया गया फ़ंक्शन उस समय का सही उत्तर देता है जब उसे कॉल किया जाता है, लेकिन ईवेंट के रूप में ट्रैकिंग तत्व की दृश्यता के बारे में क्या?

अपने <body>टैग के नीचे निम्नलिखित कोड रखें :

function onVisibilityChange(el, callback) {
    var old_visible;
    return function () {
        var visible = isElementInViewport(el);
        if (visible != old_visible) {
            old_visible = visible;
            if (typeof callback == 'function') {
                callback();
            }
        }
    }
}

var handler = onVisibilityChange(el, function() {
    /* Your code go here */
});


// jQuery
$(window).on('DOMContentLoaded load resize scroll', handler);

/* // Non-jQuery
if (window.addEventListener) {
    addEventListener('DOMContentLoaded', handler, false);
    addEventListener('load', handler, false);
    addEventListener('scroll', handler, false);
    addEventListener('resize', handler, false);
} else if (window.attachEvent)  {
    attachEvent('onDOMContentLoaded', handler); // Internet Explorer 9+ :(
    attachEvent('onload', handler);
    attachEvent('onscroll', handler);
    attachEvent('onresize', handler);
}
*/

यदि आप कोई डोम संशोधन करते हैं, तो वे आपके तत्व की दृश्यता को बदल सकते हैं।

दिशानिर्देश और सामान्य नुकसान:

हो सकता है कि आपको पृष्ठ ज़ूम / मोबाइल डिवाइस चुटकी ट्रैक करने की आवश्यकता हो? jQuery को ज़ूम / पिंच क्रॉस ब्राउज़र को संभालना चाहिए , अन्यथा पहले या दूसरे लिंक को आपकी मदद करनी चाहिए।

यदि आप DOM को संशोधित करते हैं , तो यह तत्व की दृश्यता को प्रभावित कर सकता है। आपको उस पर नियंत्रण रखना चाहिए और handler()मैन्युअल रूप से कॉल करना चाहिए । दुर्भाग्य से, हमारे पास कोई क्रॉस ब्राउज़र onrepaintघटना नहीं है। दूसरी ओर जो हमें अनुकूलन करने और केवल डोम संशोधनों पर फिर से जांच करने की अनुमति देता है जो किसी तत्व की दृश्यता को बदल सकते हैं।

कभी भी इसे jQuery $ (डॉक्यूमेंट) (।) ( केवल ) के अंदर उपयोग करें , क्योंकि कोई वारंटी नहीं है CSS को इस क्षण में लागू नहीं किया गया है । आपका कोड आपके सीएसएस के साथ स्थानीय रूप से हार्ड ड्राइव पर काम कर सकता है, लेकिन एक बार रिमोट सर्वर पर डालने पर यह विफल हो जाएगा।

DOMContentLoadedनिकाल दिए जाने के बाद , शैलियों को लागू किया जाता है , लेकिन चित्र अभी तक लोड नहीं किए गए हैं । इसलिए, हमें window.onloadईवेंट श्रोता को जोड़ना चाहिए ।

हम अभी तक ज़ूम / पिंच ईवेंट नहीं पकड़ सकते।

अंतिम उपाय निम्नलिखित कोड हो सकता है:

/* TODO: this looks like a very bad code */
setInterval(handler, 600);

यदि आप ध्यान रखते हैं कि आपके वेब पेज के साथ टैब सक्रिय और दृश्यमान है, तो आप HTML5 API की भयानक सुविधा पृष्ठ का उपयोग कर सकते हैं ।

TODO: यह विधि दो स्थितियों को नहीं संभालती है:


6
मैं इस समाधान का उपयोग कर रहा हूं (हालांकि "बॉटम" टाइपो से सावधान रहें)। जब हम जिस तत्व पर विचार कर रहे हैं, उसमें छवियों के होने की भी जानकारी होनी चाहिए। Chrome (कम से कम) को उस छवि के लिए प्रतीक्षा करनी होगी जो बाध्यता के लिए सटीक मान हो। लगता है कि फ़ायरफ़ॉक्स में यह "समस्या" नहीं है
क्लाउडियो

4
क्या यह तब काम करता है जब आपके शरीर के अंदर एक कंटेनर में स्क्रॉलिंग सक्षम होती है। उदाहरण के लिए यह यहाँ काम नहीं करता है - agaase.github.io/webpages/demo/isoncreen2.html isElementInViewport (document.getElementById ("innerele"))। innerele एक कंटेनर के अंदर मौजूद होता है जिसमें स्क्रॉलिंग सक्षम होती है।
आगासे

70
गणना यह मानती है कि तत्व स्क्रीन से छोटा है। यदि आपके पास उच्च या विस्तृत तत्व हैं, तो इसका उपयोग करना अधिक सटीक हो सकता हैreturn (rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth));
Roonaan

11
युक्ति: jQuery के साथ इसे लागू करने का प्रयास करने वालों के लिए, HTML DOM ऑब्जेक्ट (जैसे isElementInViewport(document.getElementById('elem'))) में पारित करने के लिए बस एक अनुकूल अनुस्मारक है और jQuery ऑब्जेक्ट (जैसे, isElementInViewport($("#elem))) नहीं। JQuery बराबर जोड़ना है [0]तो जैसे: isElementInViewport($("#elem)[0])
जिमीं

11
el is not defined
M_Willett

175

अपडेट करें

आधुनिक ब्राउज़रों में, आप इन्टर्सेशन ऑब्जर्वर एपीआई की जांच कर सकते हैं जो निम्नलिखित लाभ प्रदान करता है:

  • स्क्रॉल घटनाओं के लिए सुनने से बेहतर प्रदर्शन
  • क्रॉस डोमेन iframes में काम करता है
  • यह बता सकता है कि कोई तत्व दूसरे को बाधित कर रहा है / रोक रहा है

इंटरसेक्शन ऑब्जर्वर एक पूर्ण मानक होने के रास्ते पर है और पहले से ही Chrome 51+, एज 15+ और फ़ायरफ़ॉक्स 55+ में समर्थित है और सफारी के लिए विकास के अंतर्गत है। वहाँ भी एक polyfill उपलब्ध है।


पिछला उत्तर

दान द्वारा प्रदान किए गए उत्तर के साथ कुछ मुद्दे हैं जो इसे कुछ स्थितियों के लिए अनुपयुक्त दृष्टिकोण बना सकते हैं। इन मुद्दों में से कुछ को नीचे दिए गए उत्तर में बताया गया है, कि उनका कोड उन तत्वों के लिए झूठी सकारात्मकता देगा:

  • परीक्षण किया जा रहा है के सामने एक और तत्व द्वारा छिपा हुआ
  • माता-पिता या पूर्वज तत्व के दृश्य क्षेत्र के बाहर
  • एक तत्व या उसके बच्चों को सीएसएस clipसंपत्ति का उपयोग करके छिपाया गया

एक साधारण परीक्षण के निम्नलिखित परिणामों में इन सीमाओं का प्रदर्शन किया जाता है :

असफल परीक्षण, का उपयोग कर रहा है

समाधान: isElementVisible()

यहां उन समस्याओं का समाधान दिया गया है, नीचे दिए गए परीक्षा परिणाम और कोड के कुछ हिस्सों की व्याख्या के साथ।

function isElementVisible(el) {
    var rect     = el.getBoundingClientRect(),
        vWidth   = window.innerWidth || document.documentElement.clientWidth,
        vHeight  = window.innerHeight || document.documentElement.clientHeight,
        efp      = function (x, y) { return document.elementFromPoint(x, y) };     

    // Return false if it's not in the viewport
    if (rect.right < 0 || rect.bottom < 0 
            || rect.left > vWidth || rect.top > vHeight)
        return false;

    // Return true if any of its four corners are visible
    return (
          el.contains(efp(rect.left,  rect.top))
      ||  el.contains(efp(rect.right, rect.top))
      ||  el.contains(efp(rect.right, rect.bottom))
      ||  el.contains(efp(rect.left,  rect.bottom))
    );
}

पासिंग टेस्ट: http://jsfiddle.net/AndyE/cAY8c/

और परिणाम:

परीक्षण का उपयोग कर, पास किया गया

अतिरिक्त नोट्स

हालांकि, यह विधि अपनी सीमाओं के बिना नहीं है। उदाहरण के लिए, किसी तत्व को उसी स्थान पर किसी अन्य तत्व की तुलना में कम z-सूचकांक के साथ परीक्षण किया जा रहा है, भले ही सामने वाला तत्व वास्तव में उसके किसी भी हिस्से को छिपाए नहीं, भले ही छिपा हो। फिर भी, इस पद्धति के कुछ मामलों में इसके उपयोग हैं जो दान के समाधान को कवर नहीं करते हैं।

दोनों element.getBoundingClientRect()और document.elementFromPoint()CSSOM कार्यकारी ड्राफ्ट विनिर्देश का हिस्सा हैं और कम से कम IE 6 और बाद में में समर्थित हैं और सबसे लंबे समय के लिए डेस्कटॉप ब्राउज़र (यद्यपि, पूरी तरह से नहीं)। अधिक जानकारी के लिए इन कार्यों पर Quirksmode देखें ।

contains()यह देखने के लिए उपयोग किया जाता है कि तत्व द्वारा लौटाया गया तत्व document.elementFromPoint()उस बच्चे का नोड है जिसे हम दृश्यता के लिए परीक्षण कर रहे हैं। यह भी सच है अगर वापस लौटा तत्व एक ही तत्व है। यह सिर्फ चेक को अधिक मजबूत बनाता है। यह सभी प्रमुख ब्राउज़रों में समर्थित है, फ़ायरफ़ॉक्स 9.0 इसे जोड़ने के लिए उनमें से अंतिम है। पुराने फ़ायरफ़ॉक्स समर्थन के लिए, इस उत्तर के इतिहास की जाँच करें।

यदि आप दृश्यता के लिए तत्व के चारों ओर अधिक बिंदुओं का परीक्षण करना चाहते हैं, तो यह सुनिश्चित करने के लिए कि तत्व से अधिक कवर नहीं किया गया है, कहते हैं, 50% 50it उत्तर के अंतिम भाग को समायोजित करने के लिए बहुत अधिक नहीं लेगा। हालाँकि, इस बात से अवगत रहें कि यदि आप 100% दृश्यमान हैं, तो यह सुनिश्चित करने के लिए कि आपने प्रत्येक पिक्सेल की जाँच की है, तो यह बहुत धीमा होगा।


2
क्या आप doc.documentElement.clientWidth का उपयोग करने का मतलब है? इसके बजाय 'document.documentElement' होना चाहिए? एक अलग नोट पर, यह एकमात्र तरीका है, जो सीएसएस की 'क्लिप' संपत्ति का उपयोग करके किसी तत्व की सामग्री को छिपाने जैसे उपयोग के मामलों के लिए भी काम करता है: snook.ca/archives/html_and_css/hiding-content-for-accessibility
केविन लैम्प

@ क्लैम्पिंग: अच्छा कैच, धन्यवाद। मैंने इसे अपने कोड के ठीक बाहर कॉपी किया था, जहाँ मैं docएक उपनाम के रूप में उपयोग कर रहा था document। हाँ, मैं इसे किनारे के मामलों के लिए एक सभ्य समाधान के रूप में सोचना पसंद करता हूं।
एंडी ई

2
मेरे लिए यह काम नहीं कर रहा है। लेकिन पिछले उत्तर में inViewport () एफएफ में काम कर रहा है।
सत्य प्रकाश

9
यह जांचना भी फायदेमंद हो सकता है कि तत्व का केंद्र दिखाई दे रहा है यदि आपके पास गोल कोनों या एक ट्रांसफ़ॉर्म है, क्योंकि बाउंडिंग कॉर्नर अपेक्षित तत्व को वापस नहीं कर सकता है:element.contains(efp(rect.right - (rect.width / 2), rect.bottom - (rect.height / 2)))
जारेड

2
मेरे लिए इनपुट पर काम नहीं किया (क्रोम कैनरी 50)। निश्चित नहीं कि क्यों, शायद देशी गोल कोनों? मुझे इसे कम करने के लिए कोर्ड्स को थोड़ा कम करना पड़ा। eltain.stains (efp (rect.left + 1, rect.top + 1)) || el.contains (efp (rect.right-1, rect.top + 1)) || el.contains (efp (rect.right-1, rect.bottom-1))) || el.contains (efp (rect.left + 1, rect.bottom-1))
Rayjax

65

मैंने डैन के जवाब की कोशिश कीहालांकि , सीमा निर्धारित करने के लिए उपयोग किए जाने वाले बीजगणित का अर्थ है कि तत्व दोनों के व्यूपोर्ट आकार और पूरी तरह से व्यूपोर्ट के अंदर होना चाहिए true, आसानी से झूठे नकारात्मक के लिए अग्रणी। यदि आप यह निर्धारित करना चाहते हैं कि क्या कोई तत्व व्यूपोर्ट में है, तो ryanve का उत्तर करीब है, लेकिन परीक्षण किया जा रहा तत्व व्यूपोर्ट को ओवरलैप करना चाहिए, इसलिए यह प्रयास करें:

function isElementInViewport(el) {
    var rect = el.getBoundingClientRect();

    return rect.bottom > 0 &&
        rect.right > 0 &&
        rect.left < (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */ &&
        rect.top < (window.innerHeight || document.documentElement.clientHeight) /* or $(window).height() */;
}

33

एक सार्वजनिक सेवा के रूप में:
सही गणनाओं के साथ डैन का उत्तर (तत्व हो सकता है> विंडो, विशेष रूप से मोबाइल फोन स्क्रीन पर), और सही jQuery परीक्षण, साथ ही साथ IsElementPartiallyInViewport:

वैसे, window.innerWidth और document.documentElement.clientWidth के बीच का अंतर यह है कि clientWidth / clientHeight में स्क्रॉलबार शामिल नहीं है, जबकि window.innerWidth / Height करता है।

function isElementPartiallyInViewport(el)
{
    // Special bonus for those using jQuery
    if (typeof jQuery !== 'undefined' && el instanceof jQuery) 
        el = el[0];

    var rect = el.getBoundingClientRect();
    // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }
    var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
    var windowWidth = (window.innerWidth || document.documentElement.clientWidth);

    // http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
    var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
    var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);

    return (vertInView && horInView);
}


// http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
function isElementInViewport (el)
{
    // Special bonus for those using jQuery
    if (typeof jQuery !== 'undefined' && el instanceof jQuery) 
        el = el[0];

    var rect = el.getBoundingClientRect();
    var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
    var windowWidth = (window.innerWidth || document.documentElement.clientWidth);

    return (
           (rect.left >= 0)
        && (rect.top >= 0)
        && ((rect.left + rect.width) <= windowWidth)
        && ((rect.top + rect.height) <= windowHeight)
    );
}


function fnIsVis(ele)
{
    var inVpFull = isElementInViewport(ele);
    var inVpPartial = isElementPartiallyInViewport(ele);
    console.clear();
    console.log("Fully in viewport: " + inVpFull);
    console.log("Partially in viewport: " + inVpPartial);
}

परीक्षण का मामला

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Test</title>
    <!--
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="scrollMonitor.js"></script>
    -->

    <script type="text/javascript">

        function isElementPartiallyInViewport(el)
        {
            // Special bonus for those using jQuery
            if (typeof jQuery !== 'undefined' && el instanceof jQuery) 
                el = el[0];

            var rect = el.getBoundingClientRect();
            // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }
            var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
            var windowWidth = (window.innerWidth || document.documentElement.clientWidth);

            // http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
            var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
            var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);

            return (vertInView && horInView);
        }


        // http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
        function isElementInViewport (el)
        {
            // Special bonus for those using jQuery
            if (typeof jQuery !== 'undefined' && el instanceof jQuery) 
                el = el[0];

            var rect = el.getBoundingClientRect();
            var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
            var windowWidth = (window.innerWidth || document.documentElement.clientWidth);

            return (
                   (rect.left >= 0)
                && (rect.top >= 0)
                && ((rect.left + rect.width) <= windowWidth)
                && ((rect.top + rect.height) <= windowHeight)
            );
        }


        function fnIsVis(ele)
        {
            var inVpFull = isElementInViewport(ele);
            var inVpPartial = isElementPartiallyInViewport(ele);
            console.clear();
            console.log("Fully in viewport: " + inVpFull);
            console.log("Partially in viewport: " + inVpPartial);
        }


        // var scrollLeft = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft,
        // var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
    </script>
</head>

<body>
    <div style="display: block; width: 2000px; height: 10000px; background-color: green;">

        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />

        <input type="button" onclick="fnIsVis(document.getElementById('myele'));" value="det" />

        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />

        <div style="background-color: crimson; display: inline-block; width: 800px; height: 500px;" ></div>
        <div id="myele" onclick="fnIsVis(this);" style="display: inline-block; width: 100px; height: 100px; background-color: hotpink;">
        t
        </div>

        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />

        <input type="button" onclick="fnIsVis(document.getElementById('myele'));" value="det" />
    </div>

    <!--
    <script type="text/javascript">

        var element = document.getElementById("myele");
        var watcher = scrollMonitor.create(element);

        watcher.lock();

        watcher.stateChange(function() {
            console.log("state changed");
            // $(element).toggleClass('fixed', this.isAboveViewport)
        });
    </script>
    -->
</body>
</html>

2
isElementPartiallyInViewportके रूप में अच्छी तरह से बहुत उपयोगी है। अच्छा है।
आरजे कुथबर्टन

IsElementInViewport (e) के लिए: आपका कोड चित्र लोड नहीं कर रहा है, यह सही है: फ़ंक्शन isElementInViewport (e) {var t = e.getBoundingClientRect (); वापसी t.top> = 0 && t.left> = 0 && t.bottom <= (window.inHeight) document.documentElement.clientHeight) और& t.right <= (window.inWWidth। document.documentElement.clientWidth) || }
अरुण चौहान

1
@ अरुण चौहान: मेरा कोई भी कोड चित्र लोड नहीं कर रहा है, इसलिए ऐसा क्यों होना चाहिए, और सूत्र सही है।
स्टीफन स्टेगर

1
@targumon: इसका कारण पुराने ब्राउज़रों का समर्थन है।
स्टेफेन स्टीगर

1
MDS के अनुसार @StefanSteiger यह IE9 के बाद से समर्थित है, इसलिए यह व्यावहारिक रूप से सुरक्षित है (कम से कम मेरे मामले में) सीधे window.innerHeight का उपयोग करने के लिए। धन्यवाद!
तारगोन

28

का स्रोत देखें कगार , जो का उपयोग करता है getBoundingClientRect । यह पसंद है:

function inViewport (el) {

    var r, html;
    if ( !el || 1 !== el.nodeType ) { return false; }
    html = document.documentElement;
    r = el.getBoundingClientRect();

    return ( !!r
      && r.bottom >= 0
      && r.right >= 0
      && r.top <= html.clientHeight
      && r.left <= html.clientWidth
    );

}

trueयदि तत्व का कोई हिस्सा व्यूपोर्ट में है तो यह वापस आ जाता है।


27

मेरा छोटा और तेज़ संस्करण:

function isElementOutViewport(el){
    var rect = el.getBoundingClientRect();
    return rect.bottom < 0 || rect.right < 0 || rect.left > window.innerWidth || rect.top > window.innerHeight;
}

और आवश्यकता के अनुसार एक jsField: https://jsfiddle.net/on1g619L/1


4
मेरा समाधान अधिक लालची और तेज है, जब तत्व के पास व्यूपोर्ट में कोई पिक्सेल होता है, तो यह गलत हो जाएगा।
एरिक चेन

1
मुझें यह पसंद है। संक्षिप्त। आप पहली पंक्ति में फ़ंक्शन नाम और कोष्ठक के बीच और कोष्ठक और ब्रेस के बीच रिक्त स्थान निकाल सकते हैं। उन रिक्त स्थानों को कभी पसंद नहीं किया। हो सकता है कि यह सिर्फ मेरा टेक्स्ट एडिटर है जो रंग को कोड करता है जो अभी भी पढ़ने में आसान बनाता है। function aaa (arg) {स्टेटमेंट्स} मुझे पता है कि यह तेजी से निष्पादित नहीं करता है, इसके स्थान पर इसे छोटा करना है।
YK

21

मैंने पाया कि यह परेशान था कि कार्यक्षमता का एक jQuery -centric संस्करण उपलब्ध नहीं था। जब मैं डैन के समाधान में आया तो मैंने उन लोगों के लिए कुछ प्रदान करने का अवसर दिया जो jQuery OO शैली में प्रोग्राम करना पसंद करते हैं। यह अच्छा और डरावना है और मेरे लिए एक आकर्षण की तरह काम करता है।

बडा बिंग बडा बूम

$.fn.inView = function(){
    if(!this.length) 
        return false;
    var rect = this.get(0).getBoundingClientRect();

    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );

};

// Additional examples for other use cases
// Is true false whether an array of elements are all in view
$.fn.allInView = function(){
    var all = [];
    this.forEach(function(){
        all.push( $(this).inView() );
    });
    return all.indexOf(false) === -1;
};

// Only the class elements in view
$('.some-class').filter(function(){
    return $(this).inView();
});

// Only the class elements not in view
$('.some-class').filter(function(){
    return !$(this).inView();
});

प्रयोग

$(window).on('scroll',function(){

    if( $('footer').inView() ) {
        // Do cool stuff
    }
});

1
क्या कर्ली ब्रेस इफ स्टेटमेंट को बंद करने के लिए पर्याप्त होगा?
कैलेसीर

1
मैं इसे एक समान वर्ग के कई तत्वों के साथ काम नहीं कर सका।
द ऑइज़ ऑफ़ ओज

1
@ TheWhizofOz मैंने आपके द्वारा लाए गए अन्य संभावित उपयोग मामलों के उदाहरण देने के लिए अपना उत्तर अपडेट किया है। शुभकामनाएँ।
r3wt

10

नया इंटर्सेक्शन ऑब्जर्वर एपीआई इस सवाल को बहुत सीधे तौर पर संबोधित करता है।

इस समाधान के लिए एक पॉलीफ़िल की आवश्यकता होगी क्योंकि सफारी, ओपेरा और इंटरनेट एक्सप्लोरर अभी तक इसका समर्थन नहीं करते हैं (पॉलीफ़िल समाधान में शामिल है)।

इस समाधान में, एक बॉक्स आउट ऑफ़ व्यू है जो लक्ष्य (मनाया गया) है। जब यह देखने में आता है, तो शीर्ष लेख में बटन छिपा होता है। एक बार बॉक्स दृश्य को छोड़ देने के बाद इसे दिखाया जाता है।

const buttonToHide = document.querySelector('button');

const hideWhenBoxInView = new IntersectionObserver((entries) => {
  if (entries[0].intersectionRatio <= 0) { // If not in view
    buttonToHide.style.display = "inherit";
  } else {
    buttonToHide.style.display = "none";
  }
});

hideWhenBoxInView.observe(document.getElementById('box'));
header {
  position: fixed;
  top: 0;
  width: 100vw;
  height: 30px;
  background-color: lightgreen;
}

.wrapper {
  position: relative;
  margin-top: 600px;
}

#box {
  position: relative;
  left: 175px;
  width: 150px;
  height: 135px;
  background-color: lightblue;
  border: 2px solid;
}
<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
<header>
  <button>NAVIGATION BUTTON TO HIDE</button>
</header>
  <div class="wrapper">
    <div id="box">
    </div>
  </div>


3
अच्छा कार्यान्वयन, और इस उत्तर में लिंक के अनुसार इसे HTML में जोड़कर सफारी पर काम करना चाहिए<!DOCTYPE html>
Alon Eitan

ध्यान दें कि IntersectionObserverएक प्रायोगिक विशेषता है (जो भविष्य में बदल सकती है)।
कार्तिक चिंताला

2
@KarthikChintala - यह IE को छोड़कर हर ब्राउज़र में समर्थित है - और एक पॉलीफिल भी उपलब्ध है।
रैंडी कैसबर्न

केवल परिवर्तन का पता IntersectionObserverलगाने के बाद से ओपी के प्रश्न को संबोधित नहीं करता है : केवल रूट के सापेक्ष लक्ष्य की गति के बाद कॉलबैक फायर करता है।
ब्रैंडन हिल

कॉलिंग observeईवेंट को तुरंत ट्रैक किए गए तत्व के वर्तमान चौराहे की स्थिति बताते हुए निकाल दिया जाता है। तो, किसी तरह से - यह संबोधित करता है।
मेस्कालिटो

8

मेरे द्वारा यहां देखे गए सभी उत्तर केवल यह देखते हैं कि तत्व वर्तमान व्यूपोर्ट के अंदर स्थित है या नहीं । लेकिन इसका मतलब यह नहीं है कि यह दिखाई दे रहा है
क्या होगा यदि दिया गया तत्व ओवरफ्लोइंग सामग्री के साथ एक डिव के अंदर है, और इसे देखने से बाहर स्क्रॉल किया गया है?

इसे हल करने के लिए, आपको जांचना होगा कि क्या तत्व सभी माता-पिता द्वारा निहित है।
मेरा समाधान ठीक यही करता है:

यह आपको यह निर्दिष्ट करने की भी अनुमति देता है कि तत्व को कितना दिखाई देना है।

Element.prototype.isVisible = function(percentX, percentY){
    var tolerance = 0.01;   //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals
    if(percentX == null){
        percentX = 100;
    }
    if(percentY == null){
        percentY = 100;
    }

    var elementRect = this.getBoundingClientRect();
    var parentRects = [];
    var element = this;

    while(element.parentElement != null){
        parentRects.push(element.parentElement.getBoundingClientRect());
        element = element.parentElement;
    }

    var visibleInAllParents = parentRects.every(function(parentRect){
        var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);
        var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);
        var visiblePercentageX = visiblePixelX / elementRect.width * 100;
        var visiblePercentageY = visiblePixelY / elementRect.height * 100;
        return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY;
    });
    return visibleInAllParents;
};

इस समाधान ने इस तथ्य को नजरअंदाज कर दिया कि तत्व अन्य तथ्यों के कारण दिखाई नहीं दे सकते हैं, जैसे opacity: 0

मैंने क्रोम और इंटरनेट एक्सप्लोरर 11 में इस समाधान का परीक्षण किया है।


8

मुझे लगता है कि ज्यादातर उपयोग के मामलों के लिए यहां स्वीकृत उत्तर अत्यधिक जटिल है। यह कोड अच्छी तरह से काम करता है (jQuery का उपयोग करके) और पूरी तरह से दृश्यमान और आंशिक रूप से दृश्य तत्वों के बीच अंतर करता है:

var element         = $("#element");
var topOfElement    = element.offset().top;
var bottomOfElement = element.offset().top + element.outerHeight(true);
var $window         = $(window);

$window.bind('scroll', function() {

    var scrollTopPosition   = $window.scrollTop()+$window.height();
    var windowScrollTop     = $window.scrollTop()

    if (windowScrollTop > topOfElement && windowScrollTop < bottomOfElement) {
        // Element is partially visible (above viewable area)
        console.log("Element is partially visible (above viewable area)");

    } else if (windowScrollTop > bottomOfElement && windowScrollTop > topOfElement) {
        // Element is hidden (above viewable area)
        console.log("Element is hidden (above viewable area)");

    } else if (scrollTopPosition < topOfElement && scrollTopPosition < bottomOfElement) {
        // Element is hidden (below viewable area)
        console.log("Element is hidden (below viewable area)");

    } else if (scrollTopPosition < bottomOfElement && scrollTopPosition > topOfElement) {
        // Element is partially visible (below viewable area)
        console.log("Element is partially visible (below viewable area)");

    } else {
        // Element is completely visible
        console.log("Element is completely visible");
    }
});

आपको $window = $(window)स्क्रॉल हैंडलर के बाहर निश्चित रूप से कैश होना चाहिए ।
सैम

4

सरल समाधान के समर्थन के रूप में Element.getBoundingClientRect () है आदर्श बन :

function isInView(el) {
    let box = el.getBoundingClientRect();
    return box.top < window.innerHeight && box.bottom >= 0;
}

यह मोबाइल ब्राउज़र पर कैसे व्यवहार करता है? उनमें से अधिकांश व्यूपोर्ट के बारे में छोटी-छोटी हैं, जिनके हेडर स्क्रॉल पर ऊपर या नीचे जा रहे हैं, और अलग-अलग व्यवहार जब कीबोर्ड दिखाता है, तो यह एंड्रॉइड या आईओएस, आदि के आधार पर होता है
केव

जब आप इस विधि को कॉल करते हैं तो @Kev के आधार पर ठीक काम करना चाहिए। यदि आप इसे कॉल करते हैं और फिर विंडो को आकार देते हैं, तो परिणाम स्पष्ट रूप से सही नहीं हो सकता है। आप इसे हर आकार-प्रकार की कार्यक्षमता के प्रकार के आधार पर कह सकते हैं। अपने विशिष्ट उपयोग के मामले के बारे में एक अलग सवाल पूछने और मुझे यहाँ पिंग करने के लिए स्वतंत्र महसूस करें।
leonheess

3

मुझे लगता है कि यह करने का एक अधिक कार्यात्मक तरीका है। दान का जवाब एक पुनरावर्ती संदर्भ में काम नहीं करता है।

यह फ़ंक्शन उस समस्या को हल करता है जब आपका तत्व किसी स्क्रॉलिंग डिव के अंदर होता है, जो HTML टैग के लिए पुनरावर्ती स्तर तक किसी भी स्तर का परीक्षण करता है, और पहले गलत पर रुकता है।

/**
 * fullVisible=true only returns true if the all object rect is visible
 */
function isReallyVisible(el, fullVisible) {
    if ( el.tagName == "HTML" )
            return true;
    var parentRect=el.parentNode.getBoundingClientRect();
    var rect = arguments[2] || el.getBoundingClientRect();
    return (
            ( fullVisible ? rect.top    >= parentRect.top    : rect.bottom > parentRect.top ) &&
            ( fullVisible ? rect.left   >= parentRect.left   : rect.right  > parentRect.left ) &&
            ( fullVisible ? rect.bottom <= parentRect.bottom : rect.top    < parentRect.bottom ) &&
            ( fullVisible ? rect.right  <= parentRect.right  : rect.left   < parentRect.right ) &&
            isReallyVisible(el.parentNode, fullVisible, rect)
    );
};

3

Android पर Google Chrome में ज़ूम करते समय सबसे स्वीकृत उत्तर काम नहीं करते हैं। Android पर Chrome के लिए खाते में Dan के उत्तर के साथ संयोजन में , VisualViewport का उपयोग किया जाना चाहिए। निम्न उदाहरण केवल ऊर्ध्वाधर जांच को ध्यान में रखता है और खिड़की की ऊंचाई के लिए jQuery का उपयोग करता है:

var Rect = YOUR_ELEMENT.getBoundingClientRect();
var ElTop = Rect.top, ElBottom = Rect.bottom;
var WindowHeight = $(window).height();
if(window.visualViewport) {
    ElTop -= window.visualViewport.offsetTop;
    ElBottom -= window.visualViewport.offsetTop;
    WindowHeight = window.visualViewport.height;
}
var WithinScreen = (ElTop >= 0 && ElBottom <= WindowHeight);

2

यहाँ मेरा समाधान है। यह काम करेगा यदि कोई तत्व स्क्रॉल करने योग्य कंटेनर के अंदर छिपा हुआ है।

यहाँ एक डेमो है (विंडो को फिर से आकार देने की कोशिश करें)

var visibleY = function(el){
    var top = el.getBoundingClientRect().top, rect, el = el.parentNode;
    do {
        rect = el.getBoundingClientRect();
        if (top <= rect.bottom === false)
            return false;
        el = el.parentNode;
    } while (el != document.body);
    // Check it's within the document viewport
    return top <= document.documentElement.clientHeight;
};

मुझे केवल यह देखने की ज़रूरत है कि यह वाई अक्ष में दिखाई दे रहा है (स्क्रॉलिंग अजाक्स लोड-अधिक-रिकॉर्ड सुविधा के लिए)।


2

डैन के समाधान के आधार पर , मुझे कार्यान्वयन को साफ करने पर जाना था ताकि एक ही पृष्ठ पर कई बार इसका उपयोग करना आसान हो:

$(function() {

  $(window).on('load resize scroll', function() {
    addClassToElementInViewport($('.bug-icon'), 'animate-bug-icon');
    addClassToElementInViewport($('.another-thing'), 'animate-thing');
    // 👏 repeat as needed ...
  });

  function addClassToElementInViewport(element, newClass) {
    if (inViewport(element)) {
      element.addClass(newClass);
    }
  }

  function inViewport(element) {
    if (typeof jQuery === "function" && element instanceof jQuery) {
      element = element[0];
    }
    var elementBounds = element.getBoundingClientRect();
    return (
      elementBounds.top >= 0 &&
      elementBounds.left >= 0 &&
      elementBounds.bottom <= $(window).height() &&
      elementBounds.right <= $(window).width()
    );
  }

});

जिस तरह से मैं इसका उपयोग कर रहा हूं वह यह है कि जब तत्व स्क्रॉल करता है, तो मैं एक वर्ग जोड़ रहा हूं जो सीएसएस कीफ़्रेम एनीमेशन को ट्रिगर करता है। यह बहुत सीधा है और विशेष रूप से अच्छी तरह से काम करता है जब आप एक पृष्ठ पर सशर्त रूप से चेतन करने के लिए 10+ चीजों की तरह हो गए हैं।


आपको $window = $(window)स्क्रॉल हैंडलर के बाहर कैश करना चाहिए
एडम रेहल

2

पिछले उत्तरों में अधिकांश usages इन बिंदुओं पर विफल हो रहे हैं:

-जब किसी तत्व का कोई पिक्सेल दिखाई देता है, लेकिन " एक कोना " नहीं:

-जब कोई तत्व व्यूपोर्ट से बड़ा और केंद्रित हो ,

उनमें से ज्यादातर केवल एक दस्तावेज़ या खिड़की के अंदर एक विलक्षण तत्व के लिए जाँच कर रहे हैं

खैर, इन सभी समस्याओं के लिए मेरे पास एक समाधान है और प्लस साइड हैं:

-आप visibleतभी लौट सकते हैं जब किसी भी तरफ से केवल एक पिक्सेल ही दिखाई दे और वह एक कोने का न हो,

-आप अभी भी वापस जा सकते हैं visibleजब तत्व viewport से बड़ा है,

-आप अपना चयन कर सकते हैं parent elementया आप स्वचालित रूप से इसे चुनने दे सकते हैं,

गतिशील रूप से जोड़े गए तत्वों पर भी काम करता है।

यदि आप नीचे दिए गए स्निपेट की जांच करते हैं, तो आपको overflow-scrollतत्व के कंटेनर में उपयोग करने में अंतर दिखाई देगा, इससे कोई परेशानी नहीं होगी और देखेंगे कि अन्य उत्तरों के विपरीत यहां तक कि अगर कोई पिक्सेल किसी भी तरफ से दिखाता है या जब कोई तत्व व्यूपोर्ट से बड़ा है और हम भीतर देख रहे हैं तत्व का पिक्सेल यह अभी भी काम करता है।

उपयोग सरल है:

// For checking element visibility from any sides
isVisible(element)

// For checking elements visibility in a parent you would like to check
var parent = document; // Assuming you check if 'element' inside 'document'
isVisible(element, parent)

// For checking elements visibility even if it's bigger than viewport
isVisible(element, null, true) // Without parent choice
isVisible(element, parent, true) // With parent choice

वह प्रदर्शन crossSearchAlgorithmजिसके बिना व्यूपोर्ट चेक एलिमेंट 3 इनर पिक्सल से बड़े तत्वों के लिए उपयोगी है, जिसे देखने के लिए:

आप देखते हैं, जब आप एलिमेंट 3 के अंदर होते हैं, तो यह बताने में विफल रहता है कि यह दिखाई दे रहा है या नहीं, क्योंकि हम केवल जाँच कर रहे हैं कि एलीमेंट पक्षों या कोनों से दिखाई दे रहा है या नहीं ।

और इसमें वह शामिल है crossSearchAlgorithmजो आपको visibleतब भी वापस आने की अनुमति देता है जब तत्व व्यूपोर्ट से बड़ा हो:

JSFiddle इसके साथ खेलने के लिए: http://jsfiddle.net/BerkerYuceer/grk5az2c/

यह कोड अधिक सटीक जानकारी के लिए बनाया गया है यदि तत्व का कोई हिस्सा दृश्य में दिखाया गया है या नहीं। प्रदर्शन विकल्प या केवल ऊर्ध्वाधर स्लाइड के लिए, इसका उपयोग न करें! यह कोड ड्राइंग मामलों में अधिक प्रभावी है।


1

एक बेहतर समाधान:

function getViewportSize(w) {
    var w = w || window;
    if(w.innerWidth != null)
        return {w:w.innerWidth, h:w.innerHeight};
    var d = w.document;
    if (document.compatMode == "CSS1Compat") {
        return {
            w: d.documentElement.clientWidth,
            h: d.documentElement.clientHeight
        };
    }
    return { w: d.body.clientWidth, h: d.body.clientWidth };
}


function isViewportVisible(e) {
    var box = e.getBoundingClientRect();
    var height = box.height || (box.bottom - box.top);
    var width = box.width || (box.right - box.left);
    var viewport = getViewportSize();
    if(!height || !width)
        return false;
    if(box.top > viewport.h || box.bottom < 0)
        return false;
    if(box.right < 0 || box.left > viewport.w)
        return false;
    return true;
}

12
आपको कोशिश करनी चाहिए और समझाएं कि आपका संस्करण बेहतर क्यों है। जैसा कि यह खड़ा है, यह कमोबेश अन्य समाधानों की तरह ही दिखता है।
एंडी ई

1
महान समाधान यह एक बॉक्स / स्क्रॉल है और खिड़की का उपयोग नहीं कर रहा है (केवल अगर यह निर्दिष्ट नहीं है)। दर पर एक नज़र डालें क्योंकि यह एक अधिक सार्वभौमिक समाधान है (इसे बहुत खोज रहा था)
teter

1

यह जितना आसान हो सकता है, IMO:

function isVisible(elem) {
  var coords = elem.getBoundingClientRect();
  return Math.abs(coords.top) <= coords.height;
}

0

यहां एक फ़ंक्शन है जो बताता है कि क्या कोई तत्व मूल तत्व के वर्तमान व्यूपोर्ट में दिखाई देता है :

function inParentViewport(el, pa) {
    if (typeof jQuery === "function"){
        if (el instanceof jQuery)
            el = el[0];
        if (pa instanceof jQuery)
            pa = pa[0];
    }

    var e = el.getBoundingClientRect();
    var p = pa.getBoundingClientRect();

    return (
        e.bottom >= p.top &&
        e.right >= p.left &&
        e.top <= p.bottom &&
        e.left <= p.right
    );
}

0

यह जांचता है कि क्या तत्व कम से कम आंशिक रूप से देखने में है (ऊर्ध्वाधर आयाम):

function inView(element) {
    var box = element.getBoundingClientRect();
    return inViewBox(box);
}

function inViewBox(box) {
    return ((box.bottom < 0) || (box.top > getWindowSize().h)) ? false : true;
}


function getWindowSize() {
    return { w: document.body.offsetWidth || document.documentElement.offsetWidth || window.innerWidth, h: document.body.offsetHeight || document.documentElement.offsetHeight || window.innerHeight}
}

0

मैं एक ही सवाल था और getBoundingClientRect () का उपयोग करके यह पता लगाया।

यह कोड पूरी तरह से 'जेनेरिक' है और इसे काम करने के लिए केवल एक बार लिखा जाना है (आपको इसे उस प्रत्येक तत्व के लिए नहीं लिखना है जिसे आप जानना चाहते हैं कि आप व्यूपोर्ट में हैं)।

यह कोड केवल यह देखने के लिए जांचता है कि यह व्यूपोर्ट में लंबवत है, क्षैतिज रूप से नहीं । इस स्थिति में, चर (सरणी) 'तत्व' उन सभी तत्वों को रखता है जिन्हें आप व्यूपोर्ट में लंबवत होने के लिए जाँच रहे हैं, इसलिए किसी भी तत्व को आप कहीं भी पकड़ सकते हैं और उन्हें वहां संग्रहीत कर सकते हैं।

'लूप के लिए', प्रत्येक तत्व के माध्यम से लूप करता है और यह देखने के लिए चेक करता है कि यह व्यूपोर्ट में लंबवत है या नहीं। उपयोगकर्ता द्वारा स्क्रॉल किए जाने पर यह कोड हर बार निष्पादित होता है ! यदि getBoudingClientRect ()। शीर्ष 3/4 से कम है (व्यूपोर्ट में तत्व एक चौथाई है), तो यह 'व्यूपोर्ट में' के रूप में पंजीकृत है।

चूंकि कोड सामान्य है, आप यह जानना चाहेंगे कि व्यूपोर्ट में कौन सा तत्व है। यह पता लगाने के लिए, आप इसे कस्टम विशेषता, नोड नाम, आईडी, वर्ग नाम और बहुत कुछ द्वारा निर्धारित कर सकते हैं।

यहां मेरा कोड है (मुझे बताएं कि क्या यह काम नहीं करता है? यह इंटरनेट एक्सप्लोरर 11, फ़ायरफ़ॉक्स 40.0.3, क्रोम संस्करण 45.0.2454.85 मीटर, ओपेरा 31.0.1889.174 और विंडोज 10 के साथ एज में परीक्षण किया गया है, [सफारी अभी तक नहीं ]) ...

// Scrolling handlers...
window.onscroll = function(){
  var elements = document.getElementById('whatever').getElementsByClassName('whatever');
  for(var i = 0; i != elements.length; i++)
  {
   if(elements[i].getBoundingClientRect().top <= window.innerHeight*0.75 &&
      elements[i].getBoundingClientRect().top > 0)
   {
      console.log(elements[i].nodeName + ' ' +
                  elements[i].className + ' ' +
                  elements[i].id +
                  ' is in the viewport; proceed with whatever code you want to do here.');
   }
};

0

यह आसान और छोटा उपाय है जो मेरे लिए काम कर रहा है।

उदाहरण : आप देखना चाहते हैं कि तत्व मूल तत्व में दिखाई देता है जिसमें ओवरफ्लो स्क्रॉल है।

$(window).on('scroll', function () {

     var container = $('#sidebar');
     var containerHeight = container.height();
     var scrollPosition = $('#row1').offset().top - container.offset().top;

     if (containerHeight < scrollPosition) {
         console.log('not visible');
     } else {
         console.log('visible');
     }
})

0

यहां सभी उत्तर निर्धारित कर रहे हैं कि तत्व पूरी तरह से व्यूपोर्ट में निहित है, न कि किसी तरह से दिखाई दे रहा है। उदाहरण के लिए, यदि दृश्य के तल पर केवल एक छवि दिखाई देती है, तो यहां समाधान "" बाहर "" मानते हुए विफल हो जाएंगे।

मेरे पास एक उपयोग का मामला था जहां मैं आलसी लोडिंग कर रहा हूं IntersectionObserver, लेकिन पॉप-इन के दौरान होने वाले एनिमेशन के कारण, मैं किसी भी चित्र का निरीक्षण नहीं करना चाहता था जो पहले से ही पेज लोड पर इंटरसेक्ट किए गए थे । ऐसा करने के लिए, मैंने निम्नलिखित कोड का उपयोग किया:

const bounding = el.getBoundingClientRect();
const isVisible = (0 < bounding.top && bounding.top < (window.innerHeight || document.documentElement.clientHeight)) ||
        (0 < bounding.bottom && bounding.bottom < (window.innerHeight || document.documentElement.clientHeight));

यह मूल रूप से देखने के लिए जाँच कर रहा है कि या तो ऊपर या नीचे की सीमा स्वतंत्र रूप से व्यूपोर्ट में है या नहीं। विपरीत छोर बाहर हो सकता है, लेकिन जब तक एक छोर अंदर है, यह कम से कम आंशिक रूप से "दृश्यमान" है।


-1

मैं इस फ़ंक्शन का उपयोग करता हूं (यह केवल तभी जांचता है कि जब x की आवश्यकता नहीं है, तो अधिकांश समय से y inscreen है)

function elementInViewport(el) {
    var elinfo = {
        "top":el.offsetTop,
        "height":el.offsetHeight,
    };

    if (elinfo.top + elinfo.height < window.pageYOffset || elinfo.top > window.pageYOffset + window.innerHeight) {
        return false;
    } else {
        return true;
    }

}

-3

इसी तरह की चुनौती के लिए, मैंने वास्तव में इस जिस्ट का आनंद लिया, जो स्क्रॉल इनटू व्यूआईफाइनेड () के लिए पॉलीफिल को उजागर करता है ।

उत्तर देने के लिए आवश्यक सभी कुंग फू इस ब्लॉक के भीतर हैं:

var parent = this.parentNode,
    parentComputedStyle = window.getComputedStyle(parent, null),
    parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
    parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
    overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,
    overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
    overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,
    overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
    alignWithTop = overTop && !overBottom;

thisउस तत्व को संदर्भित करता है जिसे आप जानना चाहते हैं कि क्या यह है, उदाहरण के लिए, overTopया overBottom- आपको बस बहाव मिलना चाहिए ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.