使用jQuery获取div的可见高度

Jac*_*Dev 83 javascript jquery height visible

我需要在可滚动区域内检索div的可见高度.我认为自己与jQuery相当不错,但这完全让我失望.

假设我在黑色包装中有一个红色div:

在上图中,jQuery函数将返回248,即div的可见部分.

一旦用户滚过div的顶部,如上图所示,它将报告296.

现在,一旦用户滚过div,它将再次报告248.

显然,我的数字不会像在这个演示中那样一致和清晰,或者我只是对这些数字进行硬编码.

我有一点理论:

  • 获取窗口的高度
  • 获得div的高度
  • 从窗口顶部获取div的初始偏移量
  • 用户滚动时获取偏移量.
    • 如果偏移为正,则意味着div的顶部仍然可见.
    • 如果它是负数,那么div的顶部已被窗口黯然失色.此时,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);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

Ror*_*san 56

这是一个快速而肮脏的概念.它基本上将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);
Run Code Online (Sandbox Code Playgroud)

示例小提琴

edit - 小型更新,以便在调整窗口大小时执行逻辑.

  • @Rev在这里你去:http://jsfiddle.net/b5DGj/1/.我将每个元素分隔为它自己的函数调用.您甚至可以进一步定义一个插件来为您执行此操作. (2认同)

Rok*_*jan 50

计算视口中元素(高度)的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));
}
Run Code Online (Sandbox Code Playgroud)

使用如下:

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

而已.


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));
Run Code Online (Sandbox Code Playgroud)

使用如下:

$("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
Run Code Online (Sandbox Code Playgroud)

您的选择器将动态监听窗口scroll,resize但也会通过第一个回调函数参数返回DOM上的初始值px.


Mic*_*ley 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
}
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式调用:

$("#myDiv").visibleHeight();
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

  • 如果窗口变大并且块可以容纳,请勿使用。这就是为什么我们需要重置块的高度:$(this).css('height',''); http://jsfiddle.net/b5DGj/144/ (2认同)