sf-utils2 sf-utils2
版本v3.3.3-beta1
首页
  • 01.快速开始 🔥
  • 02.基础-Base
  • 03.对象-Object
  • 04.数组-Array
  • 05.方法-Function
  • 06.字符串-String
  • 07.数学-Math
  • 08.dom
  • 09.拓展
  • webpack5.x教程学习 (opens new window)
  • 例子
  • 教程 🔥
  • 例子配置
企业级后台模版 (opens new window)
版本v3.3.3-beta1
首页
  • 01.快速开始 🔥
  • 02.基础-Base
  • 03.对象-Object
  • 04.数组-Array
  • 05.方法-Function
  • 06.字符串-String
  • 07.数学-Math
  • 08.dom
  • 09.拓展
  • webpack5.x教程学习 (opens new window)
  • 例子
  • 教程 🔥
  • 例子配置
企业级后台模版 (opens new window)
  • 快速开始

  • 基础-Base

  • 对象-Object

  • 数组-Array✨✨✨

  • 方法-Function

  • 字符串-String

  • 数学-Math

  • 文件-Buffer

  • 节点-dom

    • 序言 👏
    • _constant
    • getHttpBlob【获取远程二进制数据流】
    • downloadFile【http下载文件】
    • loadJsSync【单个加载js文件】
    • loadJsOrCssMulSync【批量加载远程css和js文件】
    • getAbsOffsetTop【距离父滚动区域顶部绝对距离】 🔥
    • getParentScrollElement【获取父元素滚动元素】 🔥
    • isScroll【是否是滚动容器】
    • scrollToX【水平滚动到某个具体位置】 🔥
    • scrollToY【垂直滚动到某个具体位置】 🔥
    • scrollToElement【滚动到某个dom元素】 🔥
    • isElementInContainer【元素是否整体在容器内】
    • batchElsPosInContainer【批量 dom 元素在 父的滚动视图位置】 🔥
    • isElementVisibleInViewport【是否可见在某个股东元素上】 🔥
    • observerElementMutation【监听dom元素属性变化】 🔥
      • 1.示例
        • 打印结果:
      • 2.入参说明
        • 主参数
        • options 说明
        • 实例对象方法
      • 3.源码
    • print【打印】 🔥
    • partialCb【分片加载】
    • domUtils【dom方法操作基础】 🔥
  • 拓展

  • nodejs

目录

observerElementMutation【监听dom元素属性变化】 🔥

描述

监听 dom 元素属性变化,支持回调函数处理,例如宽度、高度、class 类变化 等等

# 1.示例

推荐打开控制查看 dom元素节点 开始监听 设置容器高度300px 设置容器高度400px 设置容器高度100px
box-1
box-2
box-3
box-4
box-5
box-6
box-7
box-8
box-9
box-10
<template>
  <div>
    <el-divider content-position="left">推荐打开控制查看 dom元素节点 {{ listen ? '监听中...' : '' }}</el-divider>

    <el-button type="primary" @click="listen = !listen">{{ listen ? '停止监听' : '开始监听' }}</el-button>
    <el-button @click="onSetScrollHeight('300px')">设置容器高度300px</el-button>
    <el-button @click="onSetScrollHeight('400px')">设置容器高度400px</el-button>
    <el-button @click="onSetScrollHeight('100px')">设置容器高度100px</el-button>
    <el-button type="primary" @click="onForceUpdate" v-if="listen">强制刷新</el-button>

    <div
      class="batchElsPosInContainer-view"
      style="overflow-x: hidden; overflow-y: auto; height: 400px;border: 1px solid chocolate;"
      ref="scrollView"
    >
      <div :class="`batchElsPosInContainer-box-${item}`" v-for="item in total" :key="item">box-{{ item }}</div>
    </div>
  </div>
</template>

<script>
import { observerElementMutation, setStyle } from 'sf-utils2'

export default {
  data() {
    return {
      total: 10,
      listen: false // 开始监听
    }
  },

  watch: {
    listen: {
      handler(newVal) {
        if (this._observerMuation) {
          newVal ? this._observerMuation.start() : this._observerMuation.end()
        }
      }
    }
  },

  mounted() {
    // 先初始化,获取到observerElementMutation 实例对象
    this._observerMuation ||= observerElementMutation({
      callback: () => {
        alert('监听到高度变化了')
      },
      options: { el: this.$refs.scrollView }
    })
  },
  methods: {
    onSetScrollHeight(val) {
      // 设置dom style
      setStyle(this.$refs.scrollView, 'height', val)
    },

    onForceUpdate() {
      this._observerMuation && this._observerMuation?.forceUpdate()
    }
  }
}
</script>
<style>

.batchElsPosInContainer-view {
  overflow-x: hidden;
  overflow-y: auto;
  height: 400px;
  border: 1px solid chocolate;
  margin: 12px 0;
}
.batchElsPosInContainer-view > div {
  background: #eee;
  padding: 20px;
  text-align: center;
}
.batchElsPosInContainer-view > div + div {
  margin-top: 12px;
}

</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
显示代码 复制代码 复制代码

# 打印结果:


# 2.入参说明

# 主参数

参数 说明 类型 是否必填 默认值
callback 监听变化后,要执行自定义的回调函数 Function - -
options 选项, 详情查看 👇 Object - -

# options 说明

参数 说明 类型 是否必填 默认值
el 监听目标的 dom 元素 HtmlElement - -
attribute 监听的属性集合 Array<String> - -
observerOptions 一个可选的
MutationObserverInit (opens new window) 对象
Object - -

# 实例对象方法

参数 说明 类型 是否必填 默认值
init 初始化 Function - -
forceUpdate 强制执行,刷新 Function - -
start 开始监听 Function - -
end 结束监听 Function - -

# 3.源码

源码,点开查看 👈
import debounce from '../base/debounce'
import getStyle from './getStyle'
import { _MutationObserver } from './_constant'

/**
 * 监听元素属性变化,例如宽度、高度
 * @param {Function} callback
 * @param {Object} options
 * @returns {*}
 */
function observerElementMutation({
  callback = () => {},
  options = {
    el: null,
    attribute: ['height'],
    observerOptions: {
      attributes: true,
      childLIst: true,
      attributeOldValue: true,
      subtree: true
    }
  }
}) {
  observerElementMutation.fn = observerElementMutation.prototype = {
    start() {
      if (!this.observer) {
        // console.error('[warning] 缺少初始化参数')
        this.init()
      }
      this.observer.observe(this.defaultOptions.el, this.defaultOptions.observerOptions)
      return this
    },
    forceUpdate() {
      Object.keys(this.recordOldValue).forEach(v => {
        this.recordOldValue[v] = getStyle(this.defaultOptions.el, v)
      })
      callback.apply(this, arguments)
      return this
    },
    end() {
      if (this.observer) {
        console.warn('[end] 卸载监听成功')
        this.observer.disconnect()
        this.observer.takeRecords()
        this.observer = null
      }
      return this
    },
    init() {
      this.defaultOptions = {
        el: null,
        attribute: ['height'],
        ...options,
        observerOptions: {
          attributes: true,
          childLIst: true,
          attributeOldValue: true,
          subtree: true,
          ...(options.observerOptions || {})
        }
      }
      this.recordOldValue = this.defaultOptions.attribute.reduce((pre, cur) => {
        if (cur) pre[cur] = null
        return pre
      }, {})
      const observerCallback = mutationList => {
        if (
          Object.keys(this.recordOldValue).every(v => {
            if (this.recordOldValue[v] !== getStyle(this.defaultOptions.el, v)) {
              this.recordOldValue[v] = getStyle(this.defaultOptions.el, v)
              return false
            }
            return true
          })
        )
          return
        callback.apply(this, arguments)
      }
      const debounceDivResizeHandler = debounce(observerCallback.bind(this), 300)
      this.observer = new _MutationObserver(debounceDivResizeHandler)
      return this
    }
  }
  observerElementMutation.fn.init.prototype = observerElementMutation.fn
  return new observerElementMutation.fn.init()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
上次更新: 2025/07/01, 14:52:29
isElementVisibleInViewport【是否可见在某个股东元素上】 🔥
print【打印】 🔥

← isElementVisibleInViewport【是否可见在某个股东元素上】 🔥 print【打印】 🔥→

Theme by Vdoing | Copyright © 2022-2025 bianpengfei
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×