DOM2级定义了如下变动事件:

  1. DOMSubtreeModified:
    在DOM结构中发生任何变化时触发。这个事件在其他任何事件触发后都会触发。
  2. DOMNodeInserted:
    在一个节点作为子节点被插入到另一个节点中时触发
  3. DOMNodeRemoved:
    在节点从其父节点中被移除时触发
  4. DOMNodeInsertIntoDocument:
    在一个节点被直接插入文档或通过子树间接插入文档之后触发。这个事件在DOMNodeInserted之后触发
  5. DOMNodeRemovedFromDocument:
    在一个节点被直接从文档中移除或通过子树间接从文档中移除之前触发。这个事件在DOMNodeRemoved之后触发 
  6. DOMAttrModified:在特性被修改之后触发
  7. DOMCharacterDataModified:在文本节点的值发生变化时触发。

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

var isSupported = document.implementation.hasFeature('MutationEvents','2.0'); 

IE8之前的版本不支持任何变动事件

由于DOM3级事件模块作废了很多变动事件

  • 删除节点
    在使用removeChild()和replaceChild()从DOM中删除节点时:
    首先触发DOMNodeRemoved事件
    这个事件的目标(event.target)是被删除的节点
</head>
<body style='height:3000px;'> <ul id='myList'>
<li>Item 1</li>
</ul>
<div id="div1"></div>
<script>
var EventUtil = {
addHandler: function(element,type,handler){//添加事件
if (element.addEventListener)
{
element.addEventListener(type,handler,false);
}else if (element.attachEvent)
{
element.attachEvent('on'+type,handler);
}else {
element['on'+type] = handler;
}
},
getEvent: function(event){//获得事件对象
return event || window.event;
},
getTarget: function(event){//获得事件元素
return event.target || event.srcElement;
},
preventDefault: function(){//取消默认事件行为
if (event.preventDefault)
{
event.preventDefault();
}else {
event.returnValue = false;
}
},
removeHandler: function(element,type,handler){//取消事件
if (element.removeEventListener)
{
element.removeEventListener(type,handler,false)
}else if (element.dettchEvent)
{
element.dettchEvent('on'+type,handler);
}else {
element['on'+type] = null;
}
},
stopPropagation: function(event){//取消冒泡机制
if (event.stopPropagation)
{
event.stopPropagation();
}else {
event.cancleBubble = true;
}
},
getRelatedTarget: function(event){
if (event.relatedTarget)
{
return event.relatedTarget;//标准下返回相关元素
}else if (event.toElement)
{
return event.toElement;//mouseout事件触发,保存相关元素
}else if (event.fromElement)
{
return event.fromElement;//mouseover事件触发,保存相关元素
}
},
getButton: function(event){//鼠标按钮兼容
if (document.implementation.hasFeature('MouseEvents','2.0'))//标准下
{
return event.button;
}else {
switch (event.button)//非标准下
{
case 0:
case 1:
case 3:
case 5:
case 7:
return 0;
case 2:
case 6:
return 2;
case 4:
return 1;
}
}
},
getWheelDelta: function(event){//滚轮事件兼容
//所以要兼容,写两个函数函数
//client的兼容性必须先写出来
if (event.wheelDelta)
{
/*
兼容opear9.5以前版本的正负相反,mousewheel
*/
return (window.client.engine.opera && window.client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta);
}else {
/*
兼容firefox正负和3的倍数的问题,DOMMouseScroll
*/
return -event.detail*40;
}
},
getCharCode: function(event){//键盘事件兼容
if (typeof event.charCode == 'number')//首先检测按键有没有代表的字符,如果没有就没有charCode,为undefined
{
return event.charCode;
}else {
return event.keyCode
}
}
} EventUtil.addHandler(window,'load',function(event){
var list = document.getElementById('myList'); EventUtil.addHandler(document,'DOMSubtreeModified',function(event){
console.log('--------------------------------------------');
console.log( 'DOMSubtreeModified:改变DOM结构' );
console.log(event.type);
console.log(event.target);
});
EventUtil.addHandler(document,'DOMNodeRemoved',function(event){
console.log('--------------------------------------------');
console.log( 'DOMNodeRemoved:删除节点' );
console.log(event.type);
console.log(event.target);
console.log(event.relatedNode);
}); EventUtil.addHandler(list.firstChild,'DOMNodeRemovedFromDocument',function(event){
console.log('--------------------------------------------');
console.log( 'DOMNodeRemovedFromDocument:从文档中删除节点' );
console.log(event.type);
console.log(event.target);
}); list.parentNode.removeChild(list);
});
</script>

执行顺序是:

  1. 删除节点:DOMNodeRemove
  2. 从document中删除节点:DOMNodeRemovedFromDocument
  3. 改变DOM结构:DOMSubtreeModified
  •  插入节点

在使用appendChild()、replaceChild()、insertBefore()向DOM中插入节点时,

执行顺序是:

  1. DOMNodeInserted事件:这个事件的目标是插入的节点,而event.relatedNode属性中包含一个对父节点的引用。这个事件是冒泡的
  2. DOMNodeInsertedIntoDocument事件:这个事件不冒泡,因此必须在插入节点之前为它添加这个事件处理程序。这个事件的目标是被插入的节点。
  3. DOMSubtreeModified:DOM结构发生变化触发

例子:

<body style='height:3000px;'>
<div id="div1"></div>
<script>
var EventUtil = {
addHandler: function(element,type,handler){//添加事件
if (element.addEventListener)
{
element.addEventListener(type,handler,false);
}else if (element.attachEvent)
{
element.attachEvent('on'+type,handler);
}else {
element['on'+type] = handler;
}
},
getEvent: function(event){//获得事件对象
return event || window.event;
},
getTarget: function(event){//获得事件元素
return event.target || event.srcElement;
},
preventDefault: function(){//取消默认事件行为
if (event.preventDefault)
{
event.preventDefault();
}else {
event.returnValue = false;
}
},
removeHandler: function(element,type,handler){//取消事件
if (element.removeEventListener)
{
element.removeEventListener(type,handler,false)
}else if (element.dettchEvent)
{
element.dettchEvent('on'+type,handler);
}else {
element['on'+type] = null;
}
},
stopPropagation: function(event){//取消冒泡机制
if (event.stopPropagation)
{
event.stopPropagation();
}else {
event.cancleBubble = true;
}
},
getRelatedTarget: function(event){
if (event.relatedTarget)
{
return event.relatedTarget;//标准下返回相关元素
}else if (event.toElement)
{
return event.toElement;//mouseout事件触发,保存相关元素
}else if (event.fromElement)
{
return event.fromElement;//mouseover事件触发,保存相关元素
}
},
getButton: function(event){//鼠标按钮兼容
if (document.implementation.hasFeature('MouseEvents','2.0'))//标准下
{
return event.button;
}else {
switch (event.button)//非标准下
{
case 0:
case 1:
case 3:
case 5:
case 7:
return 0;
case 2:
case 6:
return 2;
case 4:
return 1;
}
}
},
getWheelDelta: function(event){//滚轮事件兼容
//所以要兼容,写两个函数函数
//client的兼容性必须先写出来
if (event.wheelDelta)
{
/*
兼容opear9.5以前版本的正负相反,mousewheel
*/
return (window.client.engine.opera && window.client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta);
}else {
/*
兼容firefox正负和3的倍数的问题,DOMMouseScroll
*/
return -event.detail*40;
}
},
getCharCode: function(event){//键盘事件兼容
if (typeof event.charCode == 'number')//首先检测按键有没有代表的字符,如果没有就没有charCode,为undefined
{
return event.charCode;
}else {
return event.keyCode
}
}
} EventUtil.addHandler(window,'load',function(event){
var oDiv = document.getElementById('div1');
var oSpan = document.createElement('span');
oSpan.id = 'span1';
function add(){
oDiv.appendChild(oSpan);
}
function DOMSubtreeModified(event){
event = EventUtil.getEvent(event);
console.log('----------------------------------------');
console.log(event.type);
console.log(event.target);
//console.log(event.relatedNode);
} function DOMNodeInserted(event){
event = EventUtil.getEvent(event);
console.log('----------------------------------------');
console.log(event.type);
console.log(event.target);
console.log(event.relatedNode);
} function DOMNodeInsertedIntoDocument(event){
event = EventUtil.getEvent(event);
console.log('----------------------------------------');
console.log(event.type);
console.log(event.target);
//console.log(event.relatedNode);
} EventUtil.addHandler(oDiv,'click',add);
EventUtil.addHandler(document,'DOMSubtreeModified',DOMSubtreeModified);
EventUtil.addHandler(document,'DOMNodeInserted',DOMNodeInserted);
EventUtil.addHandler(oSpan,'DOMNodeInsertedIntoDocument',DOMNodeInsertedIntoDocument);
}); </script>
</body>

由于DOMSubtreeModified和DOMNodeInserted事件是冒泡的,所以它们的事件处理程序是添加到文档上的,

在将oSpan插入到其父节点之前,先将DOMNodeInsertedIntoDocument事件的事件处理程序添加给oSpan。

最后用appendChild()来添加这个oSpan;

此时事件开始依次触发。

首先是在新的oSpan元素上触发DOMNodeInserted事件,其relatedNode是oDiv元素,

然后触发oSpan元素上的DOMInsertedIntoDocument事件

最后触发oDiv上的DOMSubtreeModified事件

变动事件_DOM2级的变动事件(mutation)的更多相关文章

  1. Javascript高级编程学习笔记(66)—— 事件(10)变动事件

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

  2. javaScript事件机制深入学习(事件冒泡,事件捕获,事件绑定方式,移除事件方式,阻止浏览器默认行为,事件委托,模拟浏览器事件,自定义事件)

    前言 JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间.可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码.这种在传统软 ...

  3. Javascript高级编程学习笔记(71)—— 模拟事件(1)DOM事件模拟

    事件,指的是网页中某个特定的交互时刻 一般来说事件由浏览器厂商负责提供,一般由用户操作或者其它浏览器功能来触发 但是有一类特殊的事件,那就是由我们开发人员通过JS触发的事件 这些事件和浏览器创建的事件 ...

  4. JavaScript事件详解-jQuery的事件实现(三)

    正文 本文所涉及到的jQuery版本是3.1.1,可以在压缩包中找到event模块.该篇算是阅读笔记,jQuery代码太长.... Dean Edward的addEvent.js 相对于zepto的e ...

  5. JavaScript事件详解-Zepto的事件实现(二)【新增fastclick阅读笔记】

    正文 作者打字速度实在不咋地,源码部分就用图片代替了,都是截图,本文讲解的Zepto版本是1.2.0,在该版本中的event模块与1.1.6基本一致.此文的fastclick理解上在看过博客园各个大神 ...

  6. 深入理解DOM事件机制系列第二篇——事件处理程序

    × 目录 [1]HTML [2]DOM0级 [3]DOM2级[4]IE[5]总结 前面的话 事件处理程序又叫事件侦听器,实际上就是事件的绑定函数.事件发生时会执行函数中相应代码.事件处理程序有HTML ...

  7. 深入理解DOM事件机制系列第一篇——事件流

    × 目录 [1]历史 [2]事件冒泡 [3]事件捕获[4]事件流 前面的话 javascript操作CSS称为脚本化CSS,而javascript与HTML的交互是通过事件实现的.事件就是文档或浏览器 ...

  8. js事件(一)之事件流

    1.事件流定义 事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流. 事件传播的顺序对应浏览器的两种事件流模型:捕获型事件流和冒泡型事 ...

  9. JavaScript事件详解-zepto的事件实现

    zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...

随机推荐

  1. Bootstrap(10) 进度条媒体对象和 Well 组件

    一.Well 组件这个组件可以实现简单的嵌入效果. <!-- //嵌入效果 --> <div class="well">Bootstrap</div& ...

  2. call指令和ret指令配合实现子程序调用

    子程序的框架如下. 标号: 指令 ret 具有子程序的源程序的框架如下. assume cs:code code segment main: : : call sub1 : : mov ax,4c00 ...

  3. mui 注意事项

    1>一切内容都要包裹在mui-content中 顶部导航栏(.mui-bar-nav).底部工具条(.mui-bar-footer).底部选项卡(.mui-bar-tab)放在.mui-cont ...

  4. mysql 存储过程 与 循环

    mysql 操作同样有循环语句操作,三种标准循环模式:while, loop,repeat, 外加一种非标准循环:goto [在c或c#中貌似出现过类型循环但是一般不建议用!] 一般格式为:delim ...

  5. (转)Android开发之封装标题栏

    文章转自 CoderAbsolom  的 http://blog.csdn.net/qq_14923661/article/details/52003447 写在前面: 标题栏这个部分,绝大多数App ...

  6. mybatis入门--#{}和${}的区别

    我们知道,在mybatis中,sql语句是需要我们自己写的.跟在普通的sql不一样的是,我们在使用mybatis框架的时候,使用的占位符不是 ? 而是 #{} 有时候还会出现这个符号 ${} 这些符号 ...

  7. PAT 1089 狼人杀-简单版(20 分)(代码+测试点分析)

    1089 狼人杀-简单版(20 分) 以下文字摘自<灵机一动·好玩的数学>:"狼人杀"游戏分为狼人.好人两大阵营.在一局"狼人杀"游戏中,1 号玩家 ...

  8. com_pc-mcu

    #include <REG52.H> unsigned char UART_buff; bit New_rec = , Send_ed = , Money = ; void main (v ...

  9. Spring 注解(二)注解工具类 AnnotationUtils 和 AnnotatedElementUtils

    Spring 注解(二)注解工具类 AnnotationUtils 和 AnnotatedElementUtils Spring 系列目录(https://www.cnblogs.com/binary ...

  10. Netty 源码 ChannelHandler(四)编解码技术

    Netty 源码 ChannelHandler(四)编解码技术 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.拆包与粘 ...