JQuery के साथ एक div की दृश्यमान ऊंचाई प्राप्त करें


86

मुझे स्क्रॉल करने योग्य क्षेत्र के भीतर एक div की दृश्यमान ऊंचाई को पुनः प्राप्त करने की आवश्यकता है। मैं अपने आप को jQuery के साथ बहुत सभ्य मानता हूं, लेकिन यह मुझे पूरी तरह से फेंक रहा है।

मान लीजिए कि मैंने एक काले आवरण के भीतर एक लाल रंग की डिव लगाई है:

ऊपर ग्राफिक में, jQuery फ़ंक्शन 248 div के दृश्य भाग को लौटाएगा।

एक बार जब उपयोगकर्ता उपर्युक्त ग्राफिक के रूप में div के शीर्ष पर स्क्रॉल करता है, तो यह 296 रिपोर्ट करेगा।

अब, उपयोगकर्ता द्वारा पिछले बार स्क्रॉल किए जाने के बाद, यह फिर से 248 रिपोर्ट करेगा।

जाहिर है कि मेरी संख्या उतनी सुसंगत और स्पष्ट नहीं होने वाली है, जितनी वे इस डेमो में हैं, या मैं उन नंबरों के लिए सिर्फ हार्ड कोड हूं।

मेरे पास एक सिद्धांत है:

  • खिड़की की ऊंचाई प्राप्त करें
  • डिव की ऊंचाई प्राप्त करें
  • विंडो के शीर्ष से div की प्रारंभिक ऑफसेट करें
  • उपयोगकर्ता स्क्रॉल के रूप में ऑफसेट प्राप्त करें।
    • यदि ऑफसेट सकारात्मक है, तो इसका मतलब है कि डिव का शीर्ष अभी भी दिखाई दे रहा है।
    • यदि यह नकारात्मक है, तो div के शीर्ष को खिड़की से ग्रहण किया गया है। इस बिंदु पर, डिव या तो खिड़की की पूरी ऊंचाई तक ले जा सकता है, या डिव के नीचे दिखाई दे सकता है
    • यदि div का निचला भाग दिखाई दे रहा है, तो उसके और खिड़की के नीचे के बीच के अंतर का पता लगाएं।

यह बहुत आसान लगता है, लेकिन मैं अभी इसके चारों ओर अपना सिर नहीं लपेट सकता। कल सुबह एक और दरार लूंगा; मुझे लगा कि आपमें से कुछ जीनियस मदद करने में सक्षम हो सकते हैं।

धन्यवाद!

अद्यतन: मैंने अपने दम पर यह पता लगाया, लेकिन लगता है कि नीचे दिए गए उत्तरों में से एक अधिक सुरुचिपूर्ण है, इसलिए मैं इसके बजाय इसका उपयोग करूंगा। जिज्ञासु के लिए, मैं यहाँ आया हूँ:

$(document).ready(function() {
    var windowHeight = $(window).height();
    var overviewHeight = $("#overview").height();
    var overviewStaticTop = $("#overview").offset().top;
    var overviewScrollTop = overviewStaticTop - $(window).scrollTop();
    var overviewStaticBottom = overviewStaticTop + $("#overview").height();
    var overviewScrollBottom = windowHeight - (overviewStaticBottom - $(window).scrollTop());
    var visibleArea;
    if ((overviewHeight + overviewScrollTop) < windowHeight) {
        // alert("bottom is showing!");
        visibleArea = windowHeight - overviewScrollBottom;
        // alert(visibleArea);
    } else {
        if (overviewScrollTop < 0) {
            // alert("is full height");
            visibleArea = windowHeight;
            // alert(visibleArea);
        } else {
            // alert("top is showing");
            visibleArea = windowHeight - overviewScrollTop;
            // alert(visibleArea);
        }
    }
});

मैं vh इकाइयों में देखूंगा। व्यूपोर्ट ऊंचाई की 1vh = 1/100 वीं। आप शायद उस के साथ एक समाधान मिल जाएगा। व्यूपोर्ट की ऊंचाई, तत्व की ऊंचाई, तत्वों की स्थिति और स्क्रॉल की स्थिति का पता लगाएं और तदनुसार गणना करें।
डेविडकॉन्ड्री

मान लें कि आंतरिक DIV पर मार्जिन है, चारों ओर "10px" कहें। मैं यह देखने के लिए स्क्रॉल ऊंचाई का पता लगाऊंगा कि क्या यह "10" पास है, तो मुझे बस मूल तत्व की ऊंचाई मिलेगी, इसे स्क्रॉल ऊंचाई के आधार पर घटाएं।

यदि बाकी सब विफल हो जाता है, तो मैं इस स्क्रिप्ट को देख रहा हूं, जो ऐसा लगता है कि आपको जिस उद्देश्य की आवश्यकता है वह पूरा हो सकता है: larsjung.de/fracs
davidcondrey

जवाबों:


57

यहां एक त्वरित और गंदी अवधारणा है। यह मूल रूप offset().topसे खिड़की के शीर्ष के तत्व की तुलना करता है, और खिड़की offset().top + height()के नीचे तक:

function getVisible() {    
    var $el = $('#foo'),
        scrollTop = $(this).scrollTop(),
        scrollBot = scrollTop + $(this).height(),
        elTop = $el.offset().top,
        elBottom = elTop + $el.outerHeight(),
        visibleTop = elTop < scrollTop ? scrollTop : elTop,
        visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
    $('#notification').text(visibleBottom - visibleTop);
}

$(window).on('scroll resize', getVisible);

उदाहरण का बेड़ा

संपादित करें - छोटा अद्यतन भी जब विंडो का आकार बदला जा रहा है तो तर्क प्रदर्शन करें।


मैं divकोड को दोहराए बिना कई s के लिए इसे सेट करने में समस्या कर रहा हूं । क्या इसे करने का कोई तरीका है?
जैकोब डेव

2
यहाँ @Rev तुम जाओ: jsfiddle.net/b5DGj/1 । मैंने प्रत्येक फ़ंक्शन को अपने स्वयं के फ़ंक्शन कॉल के लिए अलग कर दिया। आप आगे भी जा सकते हैं और आपके लिए ऐसा करने के लिए एक प्लगइन परिभाषित कर सकते हैं।
रोरी मैकक्रॉसन

मैंने JQuery प्लगइन के रूप में कार्य करने के लिए @ RoryMcCrossan के दृष्टिकोण को फिर से लिखा है और इसे नीचे दिए गए उत्तर के रूप में पोस्ट किया है - इसमें उस प्रारूप में अधिक सामान्य प्रयोज्यता हो सकती है।
माइकल लमली

"खिड़की" की परवाह किए बिना कभी-कभी एक तत्व अतिप्रवाह या माता-पिता के तत्वों के कारण आंशिक रूप से छिपाया जा सकता है
नादव बी

55

व्यूपोर्ट में एक तत्व (ऊंचाई) px की मात्रा की गणना करें

फिडल डेमो

यह छोटा फ़ंक्शनpx एक तत्व की राशि लौटाएगा जो (ऊर्ध्वाधर) व्यूपोर्ट में दिखाई देता है :

function inViewport($el) {
    var elH = $el.outerHeight(),
        H   = $(window).height(),
        r   = $el[0].getBoundingClientRect(), t=r.top, b=r.bottom;
    return Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H));
}

उपयोग की तरह:

$(window).on("scroll resize", function(){
  console.log( inViewport($('#elementID')) ); // n px in viewport
});

बस।


jQuery .inViewport()प्लगइन

jsFiddle डेमो

ऊपर से आप तर्क निकाल सकते हैं और इस तरह एक प्लगइन बना सकते हैं :

/**
 * inViewport jQuery plugin by Roko C.B.
 * http://stackoverflow.com/a/26831113/383904
 * Returns a callback function with an argument holding
 * the current amount of px an element is visible in viewport
 * (The min returned value is 0 (element outside of viewport)
 */
;(function($, win) {
  $.fn.inViewport = function(cb) {
     return this.each(function(i,el) {
       function visPx(){
         var elH = $(el).outerHeight(),
             H = $(win).height(),
             r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
         return cb.call(el, Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H)));  
       }
       visPx();
       $(win).on("resize scroll", visPx);
     });
  };
}(jQuery, window));

उपयोग की तरह:

$("selector").inViewport(function(px) {
  console.log( px ); // `px` represents the amount of visible height
  if(px > 0) {
    // do this if element enters the viewport // px > 0
  }else{
    // do that if element exits  the viewport // px = 0
  }
}); // Here you can chain other jQuery methods to your selector

आपके चयनकर्ता गतिशील रूप से खिड़की को सुनेंगे scrollऔर resizeपहले तैयार कॉलबैक फ़ंक्शन तर्क डोम तैयार पर प्रारंभिक मूल्य भी लौटाएंगे px


एंड्रॉइड क्रोम पर काम करने के लिए आपको <meta name="viewport" content="width=your_size">हेड html सेक्शन में जोड़ना पड़ सकता है ।
userlond

@userlond आपके योगदान के लिए धन्यवाद, लेकिन मुझे यकीन नहीं है कि content="width=1259"बहुमत के लिए उपयुक्त हो सकता है। क्या आपने content="width=device-width, initial-scale=1"इसके बजाय कोशिश की है ?
रोको सी। बुल्जन

साइट में निश्चित चौड़ाई के साथ विरासत टेम्पलेट है और यह उत्तरदायी नहीं है ... मुझे लगता है कि आपका सुझाव बहुमत के लिए ठीक होगा। तो स्पष्ट करने के लिए: यदि रोको सी। बुल्जन का समाधान काम नहीं करता है, तो <meta name="viewport" content="your_content">घोषणा को जोड़ने की कोशिश करें :)
userlond

यह इतना भयानक और इतना करीब है कि मैं क्या खोज रहा हूं। मैं खिड़की के नीचे तत्वों से दूरी की गणना कैसे कर सकता हूं? इसलिए मैं सामग्री के अंत को देखने से पहले अधिक सामग्री लोड कर सकता हूं। उदाहरण के लिए, अगर खिड़की से बीबॉटम 200 </ b> एबैक्स आग।
Thom

1
@ अच्छी तरह से, उपरोक्त विधि किसी भी अन्य विशिष्ट मानों को नहीं लौटाती है (इसे visible height pxकिसी वस्तु के रूप में अधिक सामान वापस करने के लिए विस्तारित किया जा सकता है । इस तरह के विचार के लिए इस फ़िडल को देखें: jsfiddle.net/RokoCB/6xjj5gyy (ओपन डेवलपर कंसोल) लॉग देखने के लिए)
रोको सी। बुल्जन

11

ऊपर Rory के दृष्टिकोण का एक संस्करण है, सिवाय एक jQuery प्लगइन के रूप में कार्य करने के लिए। यह उस प्रारूप में अधिक सामान्य प्रयोज्यता हो सकती है। महान जवाब, रोरी - धन्यवाद!

$.fn.visibleHeight = function() {
    var elBottom, elTop, scrollBot, scrollTop, visibleBottom, visibleTop;
    scrollTop = $(window).scrollTop();
    scrollBot = scrollTop + $(window).height();
    elTop = this.offset().top;
    elBottom = elTop + this.outerHeight();
    visibleTop = elTop < scrollTop ? scrollTop : elTop;
    visibleBottom = elBottom > scrollBot ? scrollBot : elBottom;
    return visibleBottom - visibleTop
}

निम्नलिखित के साथ बुलाया जा सकता है:

$("#myDiv").visibleHeight();

jsFiddle


2
जब खिड़की बड़ी हो जाए और ब्लॉक फिट हो सके तो काम न करें। इसलिए हमें ब्लॉक की ऊँचाई को रीसेट करने की आवश्यकता है: $ (यह) .css ('ऊंचाई', ''); jsfiddle.net/b5DGj/144
अधिकतम कोषेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.