javaScript事件(八)事件类型之变动事件

释放双眼,带上耳机,听听看~!

DOM2级的变动(mutation)事件能在DOM中某一部分发送变化时给出提示。变动事件为XML或HTML DOM设计的,并不特定于某种语言。DOM2级定义了如下变动事件。

  • DOMSubtreeModifined:在DOM结构发生任何变化的时候。这个事件在其他事件触发后都会触发。
  • DOMNodeInserted:当一个节点作为子节点被插入到另一个节点中时触发。
  • DOMNodeRemoved:在节点从其父节点中移除时触发。
  • DOMNodeInsertedIntoDocument:在一个节点被直接插入文档或通过子树间接插入文档之后触发。这个事件在DOMNodeInserted之后触发。
  • DOMNodeRemovedFromDocument:在一个节点被直接从文档移除或通过子树间接从文档移除之触发。这个事件在DOMNodeRemoved之后触发。
  • DOMAttrModified:在特性被修改之后触发。
  • DOMCharacterDataModified:在文本节点的值发生变化时触发。

使用下面点可以检测出浏览器是否支持变动事件:


1
2
1var isSupported=document.implementation.hasFeature("MutationEvents","2.0");
2

IE8及更早版本不支持任何变动事件,其他浏览器支持也有差异:

javaScript事件(八)事件类型之变动事件

DOM3废弃了很多变动事件。下面是一些仍然得到支持的事件。

1、删除节点

在使用removeChld()或replacedChild()从DOM中删除节点时,首先会触发DOMNodeRemoved事件。这个事件的目标(event.target) 是被删除的节点,而event.replatedNode属性中包含着对目标节点父节点的引用。

  • 在这个事件被触发时,节点尚未从其父节点删除,因此其parentNode属性仍然指向父节点(与event.relatedNode相同)。这个事件会冒泡,因此可以在DOM的任何层次上面处理它。
  • 如果被移除的节点包含子节点,那么在其所有子节点,以及这个被移除的节点 上会相继触发DOMNodeRemovedFromDocument事件。但这个事件不会冒泡,所以只有直接指定给其中一个子节点的事件处理程序才会被调用。这个事件的目标是相应的子节点或者那个被移除的节点,除此之外event对象中不包含其他信息。
  • 紧随其后触发的是DOMSubtreeModified事件。这个事件的目标是被移除节点的父节点;此时的event对象也不会提供与事件相关的其他信息。

例子:


1
2
3
4
5
6
7
8
1<body>
2<ul id="myList">
3    <li>Item 1</li>
4    <li>Item 2</li>
5    <li>Item 3</li>
6</ul>
7</body>
8

要移除<ul>元素,此时,就会依次触发以下事件。

  1. <ul>元素上触发DOMNodeRemoved事件,event.replatedNode为document.body
  2. <ul>元素上触发DOMNodeRemovedFromDocument事件。
  3. <ul>元素子节点的每个<li>元素

及文本节点上触发DOMNodeRemovedFromDocument事件。

  1. 在document.body上触发DOMSubtreeModified事件。因为<ul>是document.body的直接子元素。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1&lt;script type=&quot;text/javascript&quot;&gt;
2EventUtil.addHandler(window,&quot;load&quot;,function(event){
3    var list=document.getElementById(&quot;myList&quot;);
4    EventUtil.addHandler(document,&quot;DOMSubtreeModified&quot;,function(event){
5        console.log(event.type);
6        console.log(event.target);
7    });
8    EventUtil.addHandler(document,&quot;DOMNodeRemoved&quot;,function(event){
9        console.log(event.type);
10        console.log(event.target);
11        console.log(event.relatedNode);
12    });  
13    //不冒泡,所以添加到ul的第一个子节点(在兼容DOM的浏览器中是一个文本节点)
14    EventUtil.addHandler(list.firstChild,&quot;DOMNodeRemovedFromDocument&quot;,function(event){
15        console.log(event.type);
16        console.log(event.target);
17    });
18});
19&lt;/script&gt;
20

从文档中移除<ul>结果如下:

javaScript事件(八)事件类型之变动事件

2、插入节点

在使用appendChild(),replaceChild()或insertBefore()向DOM中插入节点时,首先会触发DOMNodeInserted事件。这个事件的目标是被插入的节点,而event.relatedNode属性中包含一个对父节点的引用。

  • 在这个事件被触发时,节点已经被插入到新的父节点中。这个事件会冒泡,因此可以在DOM的任何层次上面处理它。
  • 紧接着,会在新插入的节点上面触发触发DOMNodeInsertedIntoDocument事件。这个事件不冒泡,因此必须在插入节点之前未它添加这个事件处理程序。这个事件的目标是被插入的节点,除此之外event对象中不包含其他信息。
  • 最后一个触发的事件是DOMSubtreeModified事件,触发于新插入节点的父节点。

还是上面的例子:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1EventUtil.addHandler(window,&quot;load&quot;,function(event){
2    var list=document.getElementById(&quot;myList&quot;);
3    var item=document.createElement(&quot;li&quot;);
4    item.appendChild(document.createTextNode(&quot;Item 4&quot;));
5
6    EventUtil.addHandler(document,&quot;DOMSubtreeModified&quot;,function(event){
7        console.log(event.type);
8        console.log(event.target);
9    });
10    EventUtil.addHandler(document,&quot;DOMNodeInserted&quot;,function(event){
11        console.log(event.type);
12        console.log(event.target);
13        console.log(event.relatedNode);
14    });
15    EventUtil.addHandler(list.firstChild,&quot;DOMNodeInsertedIntoDocument&quot;,function(event){//不冒泡
16        console.log(event.type);
17        console.log(event.target);
18    });
19    list.appendChild(item);
20});
21

执行结果:

首先在新<li>元素项上触发DOMNodeInserted事件,其relatedNode是<>ul元素。

然后触发新<li>元素上的DOMNodeInsertedIntoDocument事件,最后触发<ul>元素上的DOMSubtreeModified事件。

javaScript事件(八)事件类型之变动事件

 

给TA打赏
共{{data.count}}人
人已打赏
安全技术

对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)

2021-8-18 16:36:11

安全技术

C++ 高性能服务器网络框架设计细节

2022-1-11 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索