JS监听dom高度变化方法总结

23,672次阅读
没有评论

共计 2855 个字符,预计需要花费 8 分钟才能阅读完成。

前言

有时候我们需要监听 dom 的变化,例如有时候图片未加载完就取 dom 的高度,这样会导致高度不正确,所以需要监听 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 构造函数

Mutation Observer API 用来监视 DOM 变动。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 // 是否将观察器应用于该节点的所有后代节点
})

针对动画 animation、transform 监听不到的情况,可以在动画完成监听高度就可以了

  el.addEventListener('animationend', onHeightChange)

    el.addEventListener('transitionend', onHeightChange)

ResizeObserver

ResizeObserver 是新的 API, 处于实验阶段,因此,兼容性不太好,文档:https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver

使用很简单

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

小结

以上就是总结的 js 如何监听 dom 变化的方法,假如你不用兼容老的浏览器,可以用最新的 ResizeObserver,当然也可以用 ResizeObserver,配合 Polyfill 来进行。

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于1970-01-01发表,共计2855字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)