检测文档高度变化

Ste*_*ins 58 javascript domdocument

我正试图检测我的document身高何时发生变化.一旦它,我需要运行一些功能来帮助组织我的页面布局.

我不是在找window.onresize.我需要整个文档,它比窗口大.

我如何观察这种变化?

vsy*_*ync 63

function onElementHeightChange(elm, callback){
    var lastHeight = elm.clientHeight, newHeight;
    (function run(){
        newHeight = elm.clientHeight;
        if( lastHeight != newHeight )
            callback();
        lastHeight = newHeight;

        if( elm.onElementHeightChangeTimer )
            clearTimeout(elm.onElementHeightChangeTimer);

        elm.onElementHeightChangeTimer = setTimeout(run, 200);
    })();
}


onElementHeightChange(document.body, function(){
    alert('Body height changed');
});
Run Code Online (Sandbox Code Playgroud)

现场演示

  • 我知道我在这里挖了一个旧帖子,但checkDocumentheight函数会不断运行,对吧?这似乎会减慢浏览器一遍又一遍地检查文档高度的速度. (5认同)
  • @Cloudkiller - 是的它经常运行,是的它会伤害性能,但我知道没有更好的方法. (5认同)
  • @ShashwatTripathi - 我认为没有理由不这样做.请调试它并解释哪一段代码不起作用.iPad也是一种设备,而不是浏览器.哪个浏览器有问题? (4认同)
  • 很好的答案!+1!真遗憾,没有针对此更改的标准事件! (2认同)

Jak*_*ake 25

您可以在要监视的元素内部使用零宽度的absolute位置iframe进行高度更改,并resize在其上侦听事件contentWindow.例如:

HTML

<body>
  Your content...
  <iframe class="height-change-listener" tabindex="-1"></iframe>
</body>
Run Code Online (Sandbox Code Playgroud)

CSS

body {
  position: relative;
}
.height-change-listener {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  height: 100%;
  width: 0;
  border: 0;
  background-color: transparent;
}
Run Code Online (Sandbox Code Playgroud)

JavaScript(使用jQuery但可以适应纯JS)

$('.height-change-listener').each(function() {
  $(this.contentWindow).resize(function() {
    // Do something more useful
    console.log('doc height is ' + $(document).height());
  });
});
Run Code Online (Sandbox Code Playgroud)

如果由于某种原因你已经height:100%设置,body你需要找到(或添加)另一个容器元素来实现它.如果要iframe动态添加,则可能需要使用该<iframe>.load事件来附加contentWindow.resize侦听器.如果你想在IE7以及浏览器中使用它,你需要将*zoom:1hack 添加到容器元素中,并且还要监听元素本身的"专有" resize事件<iframe>(将contentWindow.resize在IE8-10中复制).

这是一个小提琴 ......

  • 如果有人想要这个作为npm包:https://github.com/bertyhell/element-height-observer (4认同)
  • @Tim-“ 100vh”将是视口(也就是窗口)的高度,而我们希望文档的高度(即内容,不是同一件事)能够检测到何时该变化(由100%提供)。(通过`window.resize`事件很容易检测出视口高度何时改变。) (3认同)

Dan*_*ana 12

只是我的两分钱.如果您有任何机会使用角度,那么这将完成工作:

$scope.$watch(function(){ 
 return document.height();
},function onHeightChange(newValue, oldValue){
 ...
});
Run Code Online (Sandbox Code Playgroud)

  • 你的意思是$(document).height(); ? (3认同)
  • 这不起作用,它只会检查角度范围内的高度$ digest,它不包括高度可以改变的许多其他方式,如css动画,图像加载和任何不触发角度摘要的js代码(例如,非角度的库 (2认同)

jps*_*der 12

更新:2020

现在有一种方法可以使用新的ResizeObserver来完成此操作。这允许您在元素更改大小时收听整个元素列表。基本用法相当简单:

const observer = new ResizeObserver(entries => {
  for (const entry of entries) {
    // each entry is an instance of ResizeObserverEntry
    console.log(entry.contentRect.height)
  }
})
observer.observe(document.querySelector('body'))
Run Code Online (Sandbox Code Playgroud)

一个缺点是目前仅支持 Chrome/Firefox,但您可以在那里找到一些可靠的 polyfill。这是我写的一个codepen示例:

https://codepen.io/justin-schroeder/pen/poJjGJQ?editors=1111

  • 自 3 月 24 日发布的 Safari 13.1 起,已支持该功能。 (2认同)

Mar*_*arc 5

正如 vsync 所提到的,没有事件,但您可以使用计时器或将处理程序附加到其他地方:

// get the height
var refreshDocHeight = function(){
    var h = $(document).height();
    $('#result').html("Document height: " + h);
};

// update the height every 200ms
window.setInterval(refreshDocHeight, 200);

// or attach the handler to all events which are able to change 
// the document height, for example
$('div').keyup(refreshDocHeight);
Run Code Online (Sandbox Code Playgroud)

这里找到jsfiddle