How to check if an element is off-screen

后端 未结 7 1768
太阳男子
太阳男子 2020-11-27 11:39

I need to check with jQuery if a DIV element is not falling off-screen. The elements are visible and displayed according CSS attributes, but they could be intentionally plac

相关标签:
7条回答
  • 2020-11-27 11:58

    No need for a plugin to check if outside of view port.

    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))
        }
    });
    
    0 讨论(0)
  • 2020-11-27 11:58

    Well... I've found some issues in every proposed solution here.

    • You should be able to choose if you want entire element to be on screen or just any part of it
    • Proposed solutions fails if element is higher/wider than window and kinda covers browser window.

    Here is my solution that include jQuery .fn instance function and expression. I've created more variables inside my function than I could, but for complex logical problem I like to divide it into smaller, clearly named pieces.

    I'm using getBoundingClientRect method that returns element position relatively to the viewport so I don't need to care about scroll position

    Useage:

    $(".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 
    

    Source:

    $.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);
    };
    
    0 讨论(0)
  • 2020-11-27 11:59

    There's a jQuery plugin here which allows users to test whether an element falls within the visible viewport of the browser, taking the browsers scroll position into account.

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

    You can also check for partial visibility:

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

    One drawback is that it only works with vertical positioning / scrolling, although it should be easy enough to add horizontal positioning into the mix.

    0 讨论(0)
  • 2020-11-27 12:03
    • Get the distance from the top of the given element
    • Add the height of the same given element. This will tell you the total number from the top of the screen to the end of the given element.
    • Then all you have to do is subtract that from total document height

      jQuery(function () {
          var documentHeight = jQuery(document).height();
          var element = jQuery('#you-element');
          var distanceFromBottom = documentHeight - (element.position().top + element.outerHeight(true));
          alert(distanceFromBottom)
      });
      
    0 讨论(0)
  • 2020-11-27 12:09

    You could check the position of the div using $(div).position() and check if the left and top margin properties are less than 0 :

    if($(div).position().left < 0 && $(div).position().top < 0){
        alert("off screen");
    }
    
    0 讨论(0)
  • 2020-11-27 12:10

    Depends on what your definition of "offscreen" is. Is that within the viewport, or within the defined boundaries of your page?

    Using Element.getBoundingClientRect() you can easily detect whether or not your element is within the boundries of your viewport (i.e. onscreen or offscreen):

    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)
             );
    };
    

    You could then use that in several ways:

    // returns all elements that are offscreen
    $(':offscreen');
    
    // boolean returned if element is offscreen
    $('div').is(':offscreen');
    
    0 讨论(0)
提交回复
热议问题