前面有IntersectionObserver观察器实现页面懒加载的功能,原理就是观察dom是否进入视口。那么如果不管是否可见或者要实现随时监听,则需要使用MutationObserver。
示例代码:
1 filterObserve: function(_id) {
2 if ($("#"+_id+" form t-form-item").length<5) return null
3 //选择一个需要观察的节点
4 var targetNode = document.getElementById(_id);
5 // var targetNode = document.getElementsByClassName('query-searchBox')[0]//多页面
6 // 设置observer的配置选项
7 var config = { childList: true,attributes: false, subtree: true//, characterData: true
8 };
9
10 // 当节点发生变化时的需要执行的函数
11 var callback = function(mutationsList, observer) {
12 for(var mutation of mutationsList) {
13 if (mutation.type == 'childList') {
14 // console.error('A child node has been added or removed.');
15 // 已展开,直接不设最大高度(或者500)
16 if ($(".searchBox-box .icon-retract")[0]) {
17 $("#"+_id).css("max-height", 'unset')
18 }
19 else// 已折叠,只计算第一行的高度
20 if ($(".searchBox-box .icon-retractno")[0]) {
21 var mHeight = 0
22 $("#"+_id+" form t-form-item").each((index, el)=>{// TODO,待优化,提示文字内容变化的情况下,怎么获取到变化前的高度?变化后大,则不再遍历;变化后小,则遍历
23 if ($(el).find('t-form-explain')[0] && index<4) {
24 mHeight = Math.max(mHeight, $(el).find('t-form-explain').height())
25 }
26 })
27 $("#"+_id).css("max-height", 36+mHeight+'px')//$("#querySearchBox").height()
28 }
29 }
30 }
31 };
32
33 // 创建一个observer示例与回调函数相关联
34 var observer = new MutationObserver(callback);
35
36 //使用配置文件对目标节点进行观测
37 observer.observe(targetNode, config);
38 return observer
39 },
40 filterDisObserve: function(observer) {
41 if (observer) observer.disconnect();
42 }
背景:
监听搜索框内的dom变化,以便动态调整框的高度。因为有展开和折叠的功能,所以使用动态调整高度的方案(也可以通过显示或隐藏可折叠区来控制,如此一来就不需要关心高度计算问题了,相对更加合理,后边有该方案的改法)。
使用:
在页面dom加载完成后建立观察者,在页面销毁时进行注销
1 ngAfterViewInit() {
2 // this.toggleFilter()
3 this.filterObserver = ngtpAdapt.filterObserve("querySearchBoxCommonList")
4 }
5 ngOnDestroy() {
6 ngtpAdapt.filterDisObserve(this.filterObserver)
7 }
方案二:
去除高度限制,在展开折叠时控制第4项之后的表单元素的显隐
1 ngAfterViewInit() {
2 this.toggleFilter()
3 // this.filterObserver = ngtpAdapt.filterObserve("querySearchBoxCommonList")
4 }
5 // ngOnDestroy() {
6 // ngtpAdapt.filterDisObserve(this.filterObserver)
7 // }
8 toggleFilter() {
9 ngtpAdapt.showHideFilter(this.showQueryMore=!this.showQueryMore)
10 }
1 showHideFilter: function(bol) {
2 $(".query-searchBox form t-form-item").each((index, el)=>{
3 if (index>3) {
4 $(el)[bol?'show':'hide']()
5 }
6 })
7 }
补充:
config
是一个具有布尔选项的对象,该布尔选项表示“将对哪些更改做出反应”:
childList
——node
的直接子节点的更改,subtree
——node
的所有后代的更改,attributes
——node
的特性(attribute),attributeFilter
—— 特性名称数组,只观察选定的特性。characterData
—— 是否观察node.data
(文本内容),
其他几个选项:
attributeOldValue
—— 如果为true
,则将特性的旧值和新值都传递给回调(参见下文),否则只传新值(需要attributes
选项),characterDataOldValue
—— 如果为true
,则将node.data
的旧值和新值都传递给回调(参见下文),否则只传新值(需要characterData
选项)。
然后,在发生任何更改后,将执行“回调”:更改被作为一个 MutationRecord 对象列表传入第一个参数,而观察器自身作为第二个参数。
MutationRecord 对象具有以下属性:
type
—— 变动类型,以下类型之一:"attributes"
:特性被修改了,"characterData"
:数据被修改了,用于文本节点,"childList"
:添加/删除了子元素。
target
—— 更改发生在何处:"attributes"
所在的元素,或"characterData"
所在的文本节点,或"childList"
变动所在的元素,addedNodes/removedNodes
—— 添加/删除的节点,previousSibling/nextSibling
—— 添加/删除的节点的上一个/下一个兄弟节点,attributeName/attributeNamespace
—— 被更改的特性的名称/命名空间(用于 XML),oldValue
—— 之前的值,仅适用于特性或文本更改,如果设置了相应选项attributeOldValue
/characterDataOldValue
。
有一个方法可以停止观察节点:
observer.disconnect()
—— 停止观察。
当我们停止观察时,观察器可能尚未处理某些更改。在种情况下,我们使用:
observer.takeRecords()
—— 获取尚未处理的变动记录列表,表中记录的是已经发生,但回调暂未处理的变动。
这些方法可以一起使用