कैसे जांचा जाए कि कोई तत्व ऑफ-स्क्रीन है या नहीं


81

मुझे jQuery के साथ जांचने की आवश्यकता है यदि एक DIV तत्व स्क्रीन से नहीं गिर रहा है। तत्व सीएसएस विशेषताओं के अनुसार दिखाई और प्रदर्शित होते हैं, लेकिन उन्हें जानबूझकर ऑफ-स्क्रीन द्वारा रखा जा सकता है:

position: absolute; 
left: -1000px; 
top: -1000px;

मैं jQuery :visibleचयनकर्ता का उपयोग नहीं कर सका क्योंकि तत्व में एक शून्य-शून्य ऊँचाई और चौड़ाई है।

मैं कुछ भी फैंसी नहीं कर रहा हूं। यह पूर्ण स्थिति प्लेसमेंट है, जिस तरह से मेरा Ajax फ्रेमवर्क कुछ विजेट्स के छिपाने / दिखाने को लागू करता है।


मैंने इसका उत्तर इस 'डुप्लीकेट' प्रश्न पर दिया: stackoverflow.com/questions/5353934/…
टोकिमोन

जवाबों:


136

"ऑफस्क्रीन" की आपकी परिभाषा क्या है, इस पर निर्भर करता है। क्या यह व्यूपोर्ट के भीतर है, या आपके पृष्ठ की निर्धारित सीमाओं के भीतर है?

Element.getBoundingClientRect () का उपयोग करके आप आसानी से पता लगा सकते हैं कि आपका तत्व आपके व्यूपोर्ट (यानी ऑनस्क्रीन या ऑफस्क्रीन) की सीमाओं के भीतर है या नहीं:

jQuery.expr.filters.offscreen = function(el) {
  var rect = el.getBoundingClientRect();
  return (
           (rect.x + rect.width) < 0 
             || (rect.y + rect.height) < 0
             || (rect.x > window.innerWidth || rect.y > window.innerHeight)
         );
};

फिर आप इसे कई तरीकों से उपयोग कर सकते हैं:

// returns all elements that are offscreen
$(':offscreen');

// boolean returned if element is offscreen
$('div').is(':offscreen');

2
मुझे यह पसंद आया, लेकिन यह टूट जाता है अगर आपका तत्व एक स्क्रॉल करने योग्य कंटेनर के अंदर होता है - 2-स्क्रीन-लम्बे DIV के तल पर एक तत्व हमेशा "ऑफ़स्क्रीन" होगा क्योंकि खिड़की की ऊंचाई तत्व के ऑफसेटटॉप से ​​कम है।
कोडर

@scurker मुझे यह काम करने के लिए नहीं मिला। यहाँ समस्या के बारे में मेरा SO प्रश्न (jsFiddle के साथ) है: stackoverflow.com/questions/26004098/…
दुर्घटना

क्या मैं यह सोचने के लिए यहां गलत हूं कि अगर एल ने माता-पिता (निरपेक्ष या रिश्तेदार) को शरीर से पहले तैनात नहीं किया है?
फकीरी ​​मालेक

@fekirimalek आप सही हैं, मैंने उस खाते के लिए उदाहरण को अद्यतन किया है
स्कोरर

7
ध्यान दें कि वर्तमान में (जनवरी 2017) यह कम से कम क्रोम पर काम नहीं करेगा, क्योंकि Element.getBoundingClientRect () में x और y के बजाय गुण शीर्ष, दाएं, नीचे और बाएं हैं।
आसू

18

यहां एक jQuery प्लगइन है जो उपयोगकर्ताओं को यह जांचने की अनुमति देता है कि क्या ब्राउज़र के दृश्य व्यूपोर्ट में कोई तत्व गिरता है, ब्राउज़रों की स्थिति को ध्यान में रखते हुए।

$('#element').visible();

आप आंशिक दृश्यता के लिए भी जाँच कर सकते हैं:

$('#element').visible( true);

एक दोष यह है कि यह केवल ऊर्ध्वाधर स्थिति / स्क्रॉलिंग के साथ काम करता है, हालांकि यह मिश्रण में क्षैतिज स्थिति को जोड़ने के लिए पर्याप्त आसान होना चाहिए।


यह एक बहुत हल्का वजन प्लगइन है। मैं इसे जोड़ने के कुछ ही मिनटों के भीतर स्क्रॉल करने और जिम्मेदारी से काम करने पर एक निश्चित नावबार प्राप्त करने में सक्षम था। शानदार सुझाव।
नाप्स्तिर

यह प्लगइन बहुत हल्का है और लागू करने में काफी आसान है। इस मुद्दे को मैंने उप-मेनू के साथ हल किया।
थियो अनाथोस

9

पोर्ट के बाहर देखने के लिए प्लगइन की आवश्यकता नहीं है।

var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
var d = $(document).scrollTop();

$.each($("div"),function(){
    p = $(this).position();
    //vertical
    if (p.top > h + d || p.top > h - d){
        console.log($(this))
    }
    //horizontal
    if (p.left < 0 - $(this).width() || p.left > w){
        console.log($(this))
    }
});

1
यदि आप $(this).offsetइसके बजाय उपयोग करते हैं तो यह काम करेगा $this.position। अभी यह सिर्फ माता-पिता से दूरी की गणना कर रहा है, जो एक ऐसा डिव हो सकता है जो इसे पूरी तरह से लपेटता है।
रयान

7

खैर ... मुझे यहां हर प्रस्तावित समाधान में कुछ मुद्दे मिले हैं।

  • आपको यह चुनने में सक्षम होना चाहिए कि क्या आप चाहते हैं कि संपूर्ण तत्व स्क्रीन पर या इसके किसी भी हिस्से में हो
  • प्रस्तावित समाधान विफल हो जाता है यदि तत्व विंडो से अधिक / व्यापक है और थोरा ब्राउज़र विंडो को कवर करता है।

यहाँ मेरा समाधान है कि jQuery .fnउदाहरण समारोह और शामिल हैं expression। मैंने अपने फंक्शन के अंदर और अधिक वैरिएबल बनाए हैं जितना मैं कर सकता था, लेकिन जटिल तार्किक समस्या के लिए मैं इसे छोटे, स्पष्ट रूप से नामित टुकड़ों में विभाजित करना पसंद करता हूं।

मैं ऐसी getBoundingClientRectविधि का उपयोग कर रहा हूं जो तत्व स्थिति को व्यूपोर्ट में अपेक्षाकृत अधिक लौटाता है इसलिए मुझे स्क्रॉल स्थिति की देखभाल करने की आवश्यकता नहीं है

माइलेज :

$(".some-element").filter(":onscreen").doSomething();
$(".some-element").filter(":entireonscreen").doSomething();
$(".some-element").isOnScreen(); // true / false
$(".some-element").isOnScreen(true); // true / false (partially on screen)
$(".some-element").is(":onscreen"); // true / false (partially on screen)
$(".some-element").is(":entireonscreen"); // true / false 

स्रोत :

$.fn.isOnScreen = function(partial){

    //let's be sure we're checking only one element (in case function is called on set)
    var t = $(this).first();

    //we're using getBoundingClientRect to get position of element relative to viewport
    //so we dont need to care about scroll position
    var box = t[0].getBoundingClientRect();

    //let's save window size
    var win = {
        h : $(window).height(),
        w : $(window).width()
    };

    //now we check against edges of element

    //firstly we check one axis
    //for example we check if left edge of element is between left and right edge of scree (still might be above/below)
    var topEdgeInRange = box.top >= 0 && box.top <= win.h;
    var bottomEdgeInRange = box.bottom >= 0 && box.bottom <= win.h;

    var leftEdgeInRange = box.left >= 0 && box.left <= win.w;
    var rightEdgeInRange = box.right >= 0 && box.right <= win.w;


    //here we check if element is bigger then window and 'covers' the screen in given axis
    var coverScreenHorizontally = box.left <= 0 && box.right >= win.w;
    var coverScreenVertically = box.top <= 0 && box.bottom >= win.h;

    //now we check 2nd axis
    var topEdgeInScreen = topEdgeInRange && ( leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally );
    var bottomEdgeInScreen = bottomEdgeInRange && ( leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally );

    var leftEdgeInScreen = leftEdgeInRange && ( topEdgeInRange || bottomEdgeInRange || coverScreenVertically );
    var rightEdgeInScreen = rightEdgeInRange && ( topEdgeInRange || bottomEdgeInRange || coverScreenVertically );

    //now knowing presence of each edge on screen, we check if element is partially or entirely present on screen
    var isPartiallyOnScreen = topEdgeInScreen || bottomEdgeInScreen || leftEdgeInScreen || rightEdgeInScreen;
    var isEntirelyOnScreen = topEdgeInScreen && bottomEdgeInScreen && leftEdgeInScreen && rightEdgeInScreen;

    return partial ? isPartiallyOnScreen : isEntirelyOnScreen;

};

$.expr.filters.onscreen = function(elem) {
  return $(elem).isOnScreen(true);
};

$.expr.filters.entireonscreen = function(elem) {
  return $(elem).isOnScreen(true);
};

1
मुझे Make_footer_down.js मिलता है: 8 अनकैप्ड टाइपर्रर: वहाँ उर फ़ंक्शंस का उपयोग करने की कोशिश करते समय अपरिभाषित की संपत्ति 'getBoundingClientRect' नहीं पढ़ सकते हैं।
लुडविग डब्ल्यू

हाय लूर ... मैंने $ ("# divId") के साथ कोशिश की। isOnScreen (सच); जहाँ 'divId' ऑफ़स्क्रीन था और इसने मुझे 'असत्य' लौटाया; इसलिए, मुझे इसका काम लग रहा है
अनिर्बान


1
  • दिए गए तत्व के शीर्ष से दूरी प्राप्त करें
  • उसी दिए गए तत्व की ऊंचाई जोड़ें। यह आपको स्क्रीन के शीर्ष से दिए गए तत्व के अंत तक की कुल संख्या बताएगा।
  • फिर आपको बस इतना करना है कि कुल दस्तावेज़ ऊंचाई से घटाएं

    jQuery(function () {
        var documentHeight = jQuery(document).height();
        var element = jQuery('#you-element');
        var distanceFromBottom = documentHeight - (element.position().top + element.outerHeight(true));
        alert(distanceFromBottom)
    });
    

-1

आप का उपयोग करके div की स्थिति की $(div).position()जाँच कर सकते हैं और जाँच सकते हैं कि बाईं और शीर्ष मार्जिन गुण 0 से कम हैं:

if($(div).position().left < 0 && $(div).position().top < 0){
    alert("off screen");
}

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