本文总结了JavaScript中监听DOM高度变化的几种常用方法。针对图片加载或内容动态改变导致的高度获取不准问题,介绍了基于DOMNodeInserted的传统监听、兼容性较好的MutationObserver API,以及现代但需Polyfill支持的ResizeObserver。文章还提供了针对动画和旧版浏览器的兼容方案,帮助开发者根据实际需求选择合适方案。

前言
在实际开发中,有时需要实时监听DOM元素尺寸的变化。例如,在图片尚未完全加载时直接获取DOM高度,往往会导致数值不准确。因此,通过监听DOM高度变化来确保获取到最终正确的高度值变得尤为重要。本文将简要列举几种实现这一目标的方法。
监听dom树变化DOMNodeInserted
可以通过监听DOMNodeInserted事件来检测子元素是否发生变更,不过这种方式的准确度有限,并不推荐作为首选方案。
var dom = document.getElementById('dom');
var height = dom.offsetHeight;
dom.addEventListener('DOMNodeInserted', function () {
var newHeight = dom.offsetHeight;
if (newHeight !== height) {
console.log('dom高度变化了');
height = newHeight;
}
});MutationObserver 构造函数
MutationObserver API专门用于监视DOM结构的变动。无论是节点的增删、属性的修改,还是文本内容的更新,该API都能捕获到通知。目前主流浏览器包括IE11及以上版本均支持此功能,兼容性表现良好,可以放心使用。
MutationObserver构造函数接收一个回调函数作为参数,该回调函数包含两个参数:第一个参数是记录变动的数组,第二个参数则是观察器本身的实例。
var observer = new MutationObserver(function (mutations, observer){
mutations.forEach(function (mutaion) {
console.log(mutation);
})
})MutationObserver 的应用
var haoroomsId = document.getElementById('haorooms');
var MutationObserver = window.MutationObserver || window.webkitMutationObserver || window.MozMutationObserver;
var recordHeight = 0;
var mutationObserver = new MutationObserver(function (mutations) {
console.log(mutations);
let height = window.getComputedStyle(haoroomsId).getPropertyValue('height');
if (height === recordHeight) {
return;
}
recordHeight = height;
console.log('高度变化了');
// 之后更新外部容器等操作
})
mutationObserver.observe(haoroomsId, {
childList: true, // 子节点的变动(新增、删除或者更改)
attributes: true, // 属性的变动
characterData: true, // 节点内容或节点文本的变动
subtree: true // 是否将观察器应用于该节点的所有后代节点
})对于CSS动画(animation)或变换(transform)等无法直接通过常规方式监听高度的情况,可以在动画执行完毕后监听高度变化。
el.addEventListener('animationend', onHeightChange)
el.addEventListener('transitionend', onHeightChange)ResizeObserver
ResizeObserver是一项较新的API,目前仍处于实验阶段,因此浏览器兼容性尚不理想。更多详细信息可参考MDN上的ResizeObserver - Web API 接口参考文档。
其使用方式非常简洁直观。
// create an Observer instance
const resizeObserver = new ResizeObserver((entries) =>
console.log('Body height changed:', entries[0].target.clientHeight)
);
// start observing a DOM node
resizeObserver.observe(document.body);ResizeObserver Polyfill
鉴于该实验性API的兼容性局限,可以使用Polyfill进行补充支持。
ResizeObserver Polyfill通过事件冒泡机制,在顶层document上监听动画的transitionend事件;
同时监听window的resize事件;
此外,利用MutationObserver监听document元素;
为了兼容IE11以下版本,则通过DOMSubtreeModified事件监听document元素。
/**
* Initializes DOM listeners.
*
* @private
* @returns {void}
*/
ResizeObserverController.prototype.connect_ = function () {
// Do nothing if running in a non-browser environment or if listeners
// have been already added.
if (!isBrowser || this.connected_) {
return;
}
// Subscription to the "Transitionend" event is used as a workaround for
// delayed transitions. This way it's possible to capture at least the
// final state of an element.
document.addEventListener('transitionend', this.onTransitionEnd_);
window.addEventListener('resize', this.refresh);
if (mutationObserverSupported) {
this.mutationsObserver_ = new MutationObserver(this.refresh);
this.mutationsObserver_.observe(document, {
attributes: true,
childList: true,
characterData: true,
subtree: true
});
}
else {
document.addEventListener('DOMSubtreeModified', this.refresh);
this.mutationEventsAdded_ = true;
}
this.connected_ = true;
};小结
以上即为JavaScript中监听DOM变化的几种方法总结。如果项目无需兼容老旧浏览器,建议直接使用最新的ResizeObserver;若需兼容旧环境,可结合ResizeObserver与Polyfill方案使用。
总结
到此这篇关于JS监听dom高度变化方法的文章就介绍到这了,更多相关JS监听dom高度变化内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!