首页 > 代码库 > 深入理解DOM事件类型系列第三篇——变动事件

深入理解DOM事件类型系列第三篇——变动事件

×
目录
[1]删除节点 [2]插入节点 [3]特性节点[4]文本节点

前面的话

  变动(mutation)事件能在DOM中的某一部分发生变化时给出提示,这类事件非常有用,但都只能使用DOM2级事件处理程序,且由于浏览器兼容性不好,所以用的不广泛

 

删除节点

  删除节点时,涉及到DOMNodeRemoved事件、DOMNodeRemovedFromDocument事件和DOMSubtreeModified事件这三个事件,下面将详细介绍

DOMNodeRemoved

  在使用removeChild()或replacechild()从DOM中删除节点时,会触发DOMNodeRemoved事件。而event.relatedNode属性中包含着对目标节点父节点的引用。在这个事件触发时,节点尚未从其父节点删除,因此其parentNode属性仍然指向父节点。该事件会冒泡

  [注意]IE8-浏览器不支持

<div id="box" style="height: 30px;width: 100px;">    <div id="inBox">1</div></div><button id="btn">删除子节点</button><script>inBox.addEventListener(DOMNodeRemoved,function(e){    e = e || event;    e.relatedNode.style.background = lightblue;});btn.onclick = function(){    box.removeChild(inBox);}</script>

<iframe style="width: 100%; height: 80px;" src="http://sandbox.runjs.cn/show/5655q6iv" frameborder="0" width="320" height="240"></iframe>

DOMNodeRemovedFromDocument

  如果被移除的节点包含子节点,那么在其所有子节点以及这个被移除的节点上会相继触发DOMNodeRemovedFromDocument事件,这个事件不会冒泡,目标target指向被移除的节点

  [注意]该事件只有chrome/safari/opera浏览器支持

<div id="box" style="height: 30px;width: 100px;">    <div id="inBox">1</div></div><button id="btn">删除子节点</button><script>inBox.addEventListener(DOMNodeRemovedFromDocument,function(e){    e = e || event;    console.log(e.target.innerHTML)//1});btn.onclick = function(){    box.removeChild(inBox);}</script>

DOMSubtreeModified

  在DOM结构中发生任何变化时都会触发DOMSubtreeModified事件,该事件在其他任何事件触发后都会触发

  该事件的目标是被移除节点的父节点

  [注意]IE8-浏览器不支持

<div id="box" style="height: 30px;width: 100px;">    <div id="inBox">1</div></div><button id="btn">删除子节点</button><script>box.addEventListener(DOMSubtreeModified,function(e){    e = e || event;    console.log(e.type)//DOMSubtreeModified});btn.onclick = function(){    box.removeChild(inBox);}</script>

顺序

  删除节点时,事件触发的先后顺序是DOMNodeRemoved事件、DOMNodeRemovedFromDocument事件和DOMSubtreeModified事件

<div id="box" style="height: 30px;width: 100px;">    <div id="inBox">1</div></div><div id="result"></div><button id="btn">删除子节点</button><script>inBox.addEventListener(DOMNodeRemoved,handler);box.addEventListener(DOMSubtreeModified,handler);inBox.addEventListener(DOMNodeRemovedFromDocument,handler);function handler(e){    e = e || event;    result.innerHTML += e.type + ;;}btn.onclick = function(){    box.removeChild(inBox);}</script>

<iframe style="width: 100%; height: 90px;" src="http://sandbox.runjs.cn/show/w8uvth5e" frameborder="0" width="320" height="240"></iframe>

插入节点

  插入节点时涉及到DOMNodeInserted事件、DOMNodeInsertedIntoDocument事件及DOMSubtreeModified事件,下面将详细介绍

DOMNodeInserted

  在使用appendChild()、replaceChild()或insertBefore()向DOM中插入节点时,首先触发DOMNodeInserted事件

  这个事件的目标是被插入的节点,而event.relatedNode属性中包含一个对父节点的引用

  在这个事件触发时,节点已经被插入到了新的父节点中。这个事件是冒泡的,因此可以在DOM的各个层次上处理它

  [注意]IE8-浏览器不支持

<div id="box" style="height: 30px;width: 100px;"></div><button id="btn">插入节点</button><script>box.addEventListener(DOMNodeInserted,function(e){    e = e || event;    e.relatedNode.style.background = lightblue;});btn.onclick = function(){    document.body.appendChild(box);}</script>

<iframe style="width: 100%; height: 80px;" src="http://sandbox.runjs.cn/show/zqsaoq9l" frameborder="0" width="320" height="240"></iframe>

DOMNodeInsertedIntoDocument

  在新插入的节点上面会触发DOMNodeInsertedIntoDocument事件。这个事件不冒泡,因此必须在插入节点之前为它添加这个事件处理程序。这个事件的目标是被插入的节点

  [注意]该事件只有chrome/safari/opera浏览器支持

<div id="box" style="height: 30px;width: 100px;"></div><button id="btn">插入节点</button><script>box.addEventListener(DOMNodeInsertedIntoDocument,function(e){    e = e || event;    box.style.background = lightblue;});btn.onclick = function(){    document.body.appendChild(box);}</script>

<iframe style="width: 100%; height: 80px;" src="http://sandbox.runjs.cn/show/g1kqebo1" frameborder="0" width="320" height="240"></iframe>

顺序

  插入节点时,事件触发的先后顺序是DOMNodeInserted事件、DOMNodeInsertedIntoDocument事件和DOMSubtreeModified事件 

<div id="box" style="height: 30px;width: 100px;"></div><div id="outer"></div><div id="result"></div><button id="btn">插入子节点</button><script>box.addEventListener(DOMNodeInserted,handler);outer.addEventListener(DOMSubtreeModified,handler);box.addEventListener(DOMNodeInsertedIntoDocument,handler);function handler(e){    e = e || event;    result.innerHTML += e.type + ;;}btn.onclick = function(){    outer.appendChild(box);}</script>

<iframe style="width: 100%; height: 90px;" src="http://sandbox.runjs.cn/show/akw81lwb" frameborder="0" width="320" height="240"></iframe>

特性节点

DOMAttrmodified

  当特性被修改后,DOMAttrmodified事件被触发

  [注意]该事件只有firefox和IE8+浏览器支持

<div id="box" title="123" style="height: 30px;width: 100px;"></div><button id="btn">修改特性</button><script>box.addEventListener(DOMAttrModified,handler);function handler(e){    e = e || event;    box.innerHTML = e.type;}btn.onclick = function(){    box.setAttribute(title,abc);}</script>

 

文本节点

DOMCharacterDataModified

  当文本节点的值发生变化时,触发DOMCharacterDataModified事件

  [注意]该方法只有chrome/safari/opera浏览器支持

<div id="box"  style="height: 30px;width: 100px;">abc</div><button id="btn">修改文本</button><script>box.addEventListener(DOMCharacterDataModified,handler);function handler(e){    e = e || event;    console.log(e)    box.style.background = pink;}btn.onclick = function(){    box.innerHTML = 123;}</script>

<iframe style="width: 100%; height: 80px;" src="http://sandbox.runjs.cn/show/bwimepcz" frameborder="0" width="320" height="240"></iframe>

最后

  上面7个变动事件,浏览器兼容性都不是太好。唯三过得去就是DOMNodeInserted、DOMNodeRemoved和DOMSubtreeModified这三个事件,不兼容IE8-浏览器

<script type="text/javascript">// 0){ return; } if(select[i].getBoundingClientRect().top <= 0 && select[i+1]){ if(select[i+1].getBoundingClientRect().top > 0){ change(oCon.children[i+2]) } }else{ change(oCon.children[select.length+1]) } }}document.body.onmousewheel = wheel;document.body.addEventListener(‘DOMMouseScroll‘,wheel,false);var oCon = document.getElementById("content");var close = oCon.getElementsByTagName(‘span‘)[0];close.onclick = function(){ if(this.innerHTML == ‘显示目录‘){ this.innerHTML = ‘ב; this.style.background = ‘‘; oCon.style.border = ‘2px solid #ccc‘; oCon.style.width = ‘‘; oCon.style.height = ‘‘; oCon.style.overflow = ‘‘; oCon.style.lineHeight = ‘30px‘; }else{ this.innerHTML = ‘显示目录‘; this.style.background = ‘#3399ff‘; oCon.style.border = ‘none‘; oCon.style.width = ‘60px‘; oCon.style.height = ‘30px‘; oCon.style.overflow = ‘hidden‘; oCon.style.lineHeight = ‘‘; }}for(var i = 2; i < oCon.children.length; i++){ oCon.children[i].onmouseover = function(){ this.style.color = ‘#3399ff‘; } oCon.children[i].onmouseout = function(){ this.style.color = ‘inherit‘; if(this.mark){ this.style.color = ‘#3399ff‘; } } oCon.children[i].onclick = function(){ change(this); } }function change(_this){ for(var i = 2; i < oCon.children.length; i++){ oCon.children[i].mark = false; oCon.children[i].style.color = ‘inherit‘; oCon.children[i].style.textDecoration = ‘none‘; oCon.children[i].style.borderColor = ‘transparent‘; } _this.mark = true; _this.style.color = ‘#3399ff‘; _this.style.textDecoration = ‘underline‘; _this.style.borderColor = ‘#2175bc‘; }// ]]></script><script type="text/javascript" src="http://files.cnblogs.com/files/xiaohuochai/contextMenu.js"></script>

深入理解DOM事件类型系列第三篇——变动事件