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. Ajax中什么时候用同步,什么时候用异步?

    AJAX中根据async的值不同分为同步(async = false)和异步(async = true)两种执行方式:在W3C的教程中推荐使用异步执行: $.ajax({ type: "po ...

  2. Linux下打开超大文件方法

    在Linux下用VIM打开大小几个G.甚至几十个G的文件时,是非常慢的. 这时,我们可以利用下面的方法分割文件,然后再打开. 1 查看文件的前多少行 head -10000 /var/lib/mysq ...

  3. Sobel Derivatives

    https://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html ...

  4. go语言log包的学习(log,Logger)

    package main; import ( "log" "os" "time" "fmt" ) func main() ...

  5. Mysql: Specified key was too long; max key length is 1000 bytes

    在使用quartz持久化的时候,笔者使用的mysql,为了以后方便迁移数据,笔者的Mysql默认引擎MyISAM 于是顺理成章的执行了quartz-2.2.3\docs\dbTables\tables ...

  6. Vue 安装脚手架 工具 vue-cli (最新)

    假如您安装过旧版脚手架工具(vue-cli),您可以通过 npm uninstall vue-cli -g 或 yarn global remove vue-cli卸载. Vue CLI 需要Node ...

  7. python 面向对象编程 之 元类

    元类是类的类,使我们自定义的类,即我们用class定义类本质就是元类,是类的模板 四步走: 一:控制class定义类的过程 1.先拿到类名 2.在拿到基类 3.执行类体代码,得到名称空间的dict 4 ...

  8. mybatis入门--mybatis和hibernate比较

    mybatis和hibernate的比较 Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵 ...

  9. 一个比较有意思的SDN网络技术相关blog/doc

    http://feisky.xyz/sdn/linux/index.html 涵盖了目前主流的网络技术,所有比较有意思的内容全都覆盖了 SDN网络 目录 基本网络 TCP/IP标准模型 DHCP与DN ...

  10. 通过 ulimit 改善系统性能

    系统性能一直是一个受关注的话题,如何通过最简单的设置来实现最有效的性能调优,如何在有限资源的条件下保证程序的运作,ulimit 是我们在处理这些问题时,经常使用的一种简单手段.ulimit 是一种 l ...