cbvirtua 1.0.90 → 1.0.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
MutationObserver
|
|
2
|
+
2024-08-29
|
|
3
|
+
296
|
|
4
|
+
阅读4分钟
|
|
5
|
+
|
|
6
|
+
前言
|
|
7
|
+
MutationObserver 是一个dom观察器,当dom发生改变前(willchanged),会执行其回调函数,自己观察会发现不少三方UI组件用到了
|
|
8
|
+
|
|
9
|
+
其会将回调添加到当前执行栈的末尾,且在其他异步任务之前执行((如I/O、计时器等)),对于高性能低延迟的场景非常好用,也避免了延迟调用出现的卡顿问题
|
|
10
|
+
|
|
11
|
+
MutationObserver
|
|
12
|
+
MutationObserver 创建观察很简单,直接 new MutationObserver 即可
|
|
13
|
+
|
|
14
|
+
new MutationObserver 创建监听回调
|
|
15
|
+
会在观察内容发生改变操作前,回调该函数,因为打印时会发件 target 节点的 childNodes 节点没有变化
|
|
16
|
+
|
|
17
|
+
第一个参数为变化数组,会按照顺序记录先后的改变操作(增删等),observer为我们的观察对象,可以取消、观察
|
|
18
|
+
|
|
19
|
+
let obser = new MutationObserver(
|
|
20
|
+
(mutations: MutationRecord[], observer: MutationObserver) => {
|
|
21
|
+
console.log(mutations);
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
回调返回值大致结构如下所示,主要用到第一个参数,第二个参数后面介绍,可用可不用
|
|
25
|
+
|
|
26
|
+
QQ_1724749432698.png
|
|
27
|
+
|
|
28
|
+
observer 开启监听,设置监听规则
|
|
29
|
+
通过调用其 observer 函数来启用监听,可以设置 config 参数,一般用 childList、subtree、characterDataOldValue 就足够了,参数使用如下所示
|
|
30
|
+
|
|
31
|
+
const dom = document.getElementById("pppp");
|
|
32
|
+
|
|
33
|
+
obser.observe(dom!, {
|
|
34
|
+
childList: true
|
|
35
|
+
});
|
|
36
|
+
config 属性如下所示,根据自己需要取即可
|
|
37
|
+
|
|
38
|
+
/** 设置一个属性本地名(不包含命名空间)的列表,如果并非所有属性更改都需要被观察,并且 attributes 为 true 或被省略。 */
|
|
39
|
+
attributeFilter?: string[];
|
|
40
|
+
/** 设置为 true,如果 attributes 为 true 或被省略,并且需要记录目标属性更改前的值。 */
|
|
41
|
+
attributeOldValue?: boolean;
|
|
42
|
+
/** 设置为 true,如果要观察目标属性的更改。如果指定了 attributeOldValue 或 attributeFilter,则可以省略此属性。 */
|
|
43
|
+
attributes?: boolean;
|
|
44
|
+
/** 设置为 true,如果要观察目标数据的更改。如果指定了 characterDataOldValue,则可以省略此属性。 */
|
|
45
|
+
characterData?: boolean;
|
|
46
|
+
/** 设置为 true,如果 characterData 为 true 或被省略,并且需要记录目标更改前的数据。 */
|
|
47
|
+
characterDataOldValue?: boolean;
|
|
48
|
+
/** 设置为 true,如果要观察目标子节点的更改。 */
|
|
49
|
+
childList?: boolean;
|
|
50
|
+
/** 设置为 true,如果要观察不只是目标,还有目标后代的更改。 */
|
|
51
|
+
subtree?: boolean;
|
|
52
|
+
disconnect取消监听
|
|
53
|
+
通过 disconnect 取消监听,有时为了避免不必要的监听,可以在合适的时机取消监听,在重新开启监听
|
|
54
|
+
|
|
55
|
+
obser.disconnect()
|
|
56
|
+
案例(让被删除节点恢复案例,部分水印防伪功能)
|
|
57
|
+
使用 MutationObserver 监听一个 pppp 的节点,检测到其删除操作后,我们给某个节点主动添加回来,一些水印防伪功能会用到,我们就做一个简易的防删除案例
|
|
58
|
+
|
|
59
|
+
//查找dom,用于监听其子节点
|
|
60
|
+
const dom = document.getElementById("pppp");
|
|
61
|
+
|
|
62
|
+
//设置改变前的回调
|
|
63
|
+
const obser = new MutationObserver(
|
|
64
|
+
(mutations: MutationRecord[], observer: MutationObserver) => {
|
|
65
|
+
mutations.forEach((node) => {
|
|
66
|
+
node.removedNodes.forEach((node) => {
|
|
67
|
+
dom?.appendChild(node);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
//添加回调
|
|
73
|
+
obser.observe(dom!, {
|
|
74
|
+
childList: true
|
|
75
|
+
});
|
|
76
|
+
这样完成了一个删除后的恢复功能,也可以根据需要调用 disconnect、observe方法,如果不想由于回调内部操作再次触发回调,需要这样做
|
|
77
|
+
|
|
78
|
+
例如:上面的删除后的追加操作,如果里面是不是单纯追加,而是重置操作,可能还有删除和追加操作,则再次删除操作可能会触发回调地狱,需要额外添加判断条件,如果使用 disconnect + observe则可以有效避免
|
|
79
|
+
|
|
80
|
+
此外,可能还会有很多情况,有时需要在操作的末尾,可能还会有其他dom操作,要延迟恢复监听的话,可以通过setTimeout 重新启动一个宏队列任务避免提前开启监听
|
|
81
|
+
|
|
82
|
+
毕竟其回调会被追加到当前执行栈的末尾,可以通过 setTimeout 会重新启动一个宏队列任务(优先级在执行中的微队列任务之后),以此解决监听时机问题
|
|
83
|
+
|
|
84
|
+
const obser = new MutationObserver(
|
|
85
|
+
(mutations: MutationRecord[], observer: MutationObserver) => {
|
|
86
|
+
observer.disconnect();
|
|
87
|
+
|
|
88
|
+
...我们的操作
|
|
89
|
+
|
|
90
|
+
observer.observe(dom!, {
|
|
91
|
+
childList: true,
|
|
92
|
+
});
|
|
93
|
+
//开启一个新的
|
|
94
|
+
// setTimeout(() => {
|
|
95
|
+
// observer.observe(dom!, {
|
|
96
|
+
// childList: true,
|
|
97
|
+
// });
|
|
98
|
+
// }, 0);
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
整体代码
|
|
102
|
+
function App() {
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const dom = document.getElementById("pppp");
|
|
105
|
+
//改变前的回调
|
|
106
|
+
const obser = new MutationObserver(
|
|
107
|
+
(mutations: MutationRecord[], observer: MutationObserver) => {
|
|
108
|
+
console.log(mutations);
|
|
109
|
+
observer.disconnect();
|
|
110
|
+
mutations.forEach((node) => {
|
|
111
|
+
node.removedNodes.forEach((node) => {
|
|
112
|
+
dom?.appendChild(node);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
observer.observe(dom!, {
|
|
116
|
+
childList: true,
|
|
117
|
+
});
|
|
118
|
+
// setTimeout(() => {
|
|
119
|
+
// observer.observe(dom!, {
|
|
120
|
+
// childList: true,
|
|
121
|
+
// });
|
|
122
|
+
// }, 0);
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
obser.observe(dom!, {
|
|
126
|
+
childList: true,
|
|
127
|
+
});
|
|
128
|
+
}, []);
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<div className="App">
|
|
132
|
+
<header className="App-header">
|
|
133
|
+
<img src={logo} className="App-logo" alt="logo" />
|
|
134
|
+
<p id="pppp">
|
|
135
|
+
Edit <code>src/App.tsx</code> and save to reload.
|
|
136
|
+
</p>
|
|
137
|
+
</header>
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
最后
|
|
142
|
+
自己也可以尝试将添加的文本信息换个颜色🤣
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1754406912466" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5115" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 81.408a422.4 422.4 0 1 0 422.4 422.4A422.4 422.4 0 0 0 512 81.408z m26.624 629.76a45.056 45.056 0 0 1-31.232 12.288 42.496 42.496 0 0 1-31.232-12.8 41.984 41.984 0 0 1-12.8-30.72 39.424 39.424 0 0 1 12.8-30.72 42.496 42.496 0 0 1 31.232-12.288 43.008 43.008 0 0 1 31.744 12.288 39.424 39.424 0 0 1 12.8 30.72 43.008 43.008 0 0 1-13.312 31.744z m87.04-235.52a617.472 617.472 0 0 1-51.2 47.104 93.184 93.184 0 0 0-25.088 31.232 80.896 80.896 0 0 0-9.728 39.936v10.24H475.648v-10.24a119.808 119.808 0 0 1 12.288-57.344A311.296 311.296 0 0 1 555.52 460.8l10.24-11.264a71.168 71.168 0 0 0 16.896-44.032A69.632 69.632 0 0 0 563.2 358.4a69.632 69.632 0 0 0-51.2-17.92 67.072 67.072 0 0 0-58.88 26.112 102.4 102.4 0 0 0-16.384 61.44h-61.44a140.288 140.288 0 0 1 37.888-102.4 140.8 140.8 0 0 1 104.96-38.4 135.68 135.68 0 0 1 96.256 29.184 108.032 108.032 0 0 1 36.352 86.528 116.736 116.736 0 0 1-25.088 73.216z" fill="" p-id="5116"></path></svg>
|