https://msdn.microsoft.com/zh-cn/library/ie/dn265032(v=vs.85).aspx

将突变事件和属性更改事件迁移到突变观察者

Internet Explorer 11 中的突变观察者提供了对突变事件支持的所有相同方案的快速执行替换,以及对属性更改事件支持的方案的替换。

你可以使用突变事件和/或属性更改事件迁移现有代码,以使用突变观察者。

监视 DOM 突变的传统技术

Mutation events 在 Web 平台中扮演了关键角色。这些事件允许 Web 应用同步监视对网页的文档对象模型 (DOM) 中元素的动态更改。虽然突变事件很有用,但是我们也知道,由于它们的同步本质和运行它们的事件体系结构,它们会导致应用性能下降。

注意   已弃用突变事件(在 W3C DOM 级别 3 事件中定义),以支持突变观察者(W3C DOM4)。

属性更改事件提供与突变事件相似的行为。属性更改事件也会导致性能下降,因为它们需要传统浏览器事件系统才能正常工作。

注意  仅传统 attachEvent IE-only 事件注册模型支持 onpropertychange 事件,自 Windows Internet Explorer 9 开始已弃用(在 IE11 中已停止使用),以支持 W3C 标准“addEventListener”事件模型。

标识突变事件

突变事件最早在 Internet Explorer 9 中开始提供,可根据其名称轻松识别出来,其名称是一个字符串参数,传递到addEventListener 或 removeEventListener 平台 API:

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMAttrModified
  • DOMCharacterDataModified
注意  标准还定义了另外两个突变事件:DOMNodeInsertedIntoDocument 和DOMNodeRemovedFromDocument,但 Internet Explorer 不支持它们。

下面的示例展示了其中一个突变事件在 JavaScript 代码中为何种形式:

 
someElement.addEventListener("DOMAttrModified", function() {
//...
}, false);

DOMNodeInsertedDOMNodeRemoved 和 DOMSubtreeModified 突变事件监视元素子项的结构更改—向元素子项添加了元素或者删除了元素子项。DOMSubtreeModified 事件适用于这二者:删除或添加都会触发该事件。但是,它不包含关于触发原因的任何信息(你无法单独根据该事件来区分进行的是添加更改还是删除更改)。

DOMAttrModified 突变事件报告对元素的属性列表的更改。此单一事件包括与插入、删除或更改属性相关的信息。

DOMCharacterDataModified 突变事件报告对元素的文本内容的更改。文本内容组合成称作“文本节点”的逻辑单元,仅对现有文本节点的修改会触发 DOMCharacterDataModified 事件。如果插入/创建新的文本节点,则反而会将这些节点报告为 DOMNodeInserted 事件。

在代码中应当很容易就能找到突变事件,类似于在你常用的编辑器中使用“在文件中查找...”搜索功能一样。请记住,在addEventListener 方法中经常使用变量,因此请确保首先搜索突变事件字符串(“DOMNodeInserted”、“DOMNodeRemoved”等)的使用,然后仔细检查出现的所有 addEventListener 以确保将它们全部找出。

标识属性更改事件

可以通过与传统 attachEvent 或 detachEvent IE-only 事件注册 API 一起使用的 onpropertychange 事件名称标识属性更改事件。搜索出现的所有 attachEvent 并检查 onpropertychange 的第一个参数以在你的代码中找到这些使用情况。

属性更改事件在 DOM 元素的属性更改时触发。该事件不执行冒泡操作,自 Internet Explorer 9 开始已被弃用,以支持 W3C 标准“addEventListener”事件模型。该事件包括在事件 propertyName getter 中更改的属性的名称。遗憾的是,为了分派属性更改事件,同时还会计算很多其他事件属性,其中有些事件属性会强制布局引擎重新进行计算,从而导致使用这些事件的所有应用程序产生大量性能成本。

Unlike with mutation events,属性更改事件不会整齐映射到突变观察者。但是,如果感兴趣的属性名称反映在 HTML 属性中,就有可能使用突变观察者替换属性更改事件的使用。例如,id - 反映 id 属性;style.color - 反映在序列化的“style”属性中;className - 与 class 属性对应。

注意  对于未反映在 HTML 属性中的属性(例如 input 元素上的 value),可以使用称为“defineProperty”的ECMAScript 5 (JavaScript) 功能。本文档不介绍如何使用该对象迁移属性更改事件。defineProperty JavaScript API。

突变观察者有何不同

突变观察者不是基于 Web 平台的事件模型。这是一个重用区别,这使它们能够更快地进行分派,而无需在 DOM 元素层次结构中对事件执行冒泡操作。

而且,突变观察者的目标是在通知你的观察者之前记录多项更改。它们批量提供突变记录,以避免在你的应用中滥发此类事件。相比之下,突变事件是同步发送的,可以中断正常的代码执行来通知你应用发生突变。尽管突变观察者采用延迟的通知模型,但仍可保证你的应用的观察者可以在下一个重画之前收到(并有机会处理)所有突变记录。

这两项更改会影响你的应用必须如何调整来支持突变观察者。

突变观察者注册

必须首先创建突变观察者,然后才能在指定元素上注册它们。要创建突变观察者,请使用 JavaScript new 运算符并指定回调方法:

 
var mutationObserver = new MutationObserver(callback);

你提供给突变观察者构造函数的回调将不同于你可能对当前突变事件事件使用的回调。下面将进行详细说明。

创建观察者后,现在你指示它观察特定元素。通常,这与你之前在其上注册突变事件的元素相同:

 
mutationObserver.observe(someElement, options);

如果你未保存对该元素的引用,则突变观察者实例将由 Web 平台保留在内存中(只要它正在观察至少一个元素)。如果你未保存对观察者的引用,仍可以通过观察者的回调引用它(它将是回调范围中的 this 对象,也是回调函数的第二个参数)。

选项参数是一个简单的 JavaScript 对象,具有你必须提供的用来精确描述要观察何种突变的属性。属性选项与之前提到的突变的三个类别相对应:

  • childList
  • 属性
  • characterData

childList 选项的值为 true 时,意味着“观察到对此元素的子元素的更改”(既包括删除也包括添加)。此选项包括作为此元素的子项添加或删除的文本节点。

attribute 选项的值为 true 时,意味着“观察到对此元素的属性的更改”(既包括删除也包括添加和更改)。

characterData 选项为 true 时,意味着“观察到对此元素的文本节点的更改”(对文本节点值的更改,不包括将文本节点整个删除或全新添加时的情况)。

第四个选项“subtree”也很重要。前三个选项(默认)只孤立观察其目标元素,而不考虑它的任何后代(其子树)。要监视指定元素及其所有后代,请将“subtree”属性设置为 true。由于突变事件具有在 DOM 中冒泡的特征,所以需要使用“subtree”选项来维持与在上级元素上注册的突变事件的均衡。

下表描述了突变观察者选项与突变事件名称之间的对应关系:

突变事件 突变观察者选项 注意
DOMNodeInserted { childList: true, subtree: true } 回调必须手动忽略已删除节点的记录
DOMNodeRemoved { childList: true, subtree: true } 回调必须手动忽略已添加节点的记录
DOMSubtreeModified { childList: true, subtree: true } 现在回调可以区分已添加和已删除的节点
DOMAttrModified { attributes: true, subtree: true }  
DOMCharacterDataModified { characterData: true, subtree: true }  
注意  利用突变观察者,还有可能合并多个选项来同时观察 childList、attributes 和 characterData。

最后,还有几个选项用于保存属性和字符数据更改的上一个值,以及用于优化对观察有重要意义的属性的范围:

  • attributeOldValue 和 characterDataOldValue 选项的值为 true 时,会在发生属性或 characterData 更改时保存上一个值。
  • attributeFilter 选项具有属性名称的字符串数组,将观察限定在指定的属性范围内。此选项仅在 attributes 选项设置为 true 时有意义。

利用此信息,以前针对突变事件注册的任何代码都可以替换为针对突变观察者注册的代码:

 
// Watch for all changes to the body element's children
document.body.addEventListener("DOMNodeInserted", nodeAddedCallback, false);
document.body.addEventListener("DOMNodeRemoved", nodeRemovedCallback, false);

现在成为:

 
// Watch for all changes to the body element's children
new MutationObserver(nodesAddedAndRemovedCallback).observe(document.body,
{ childList: true, subtree: true });

突变观察者回调

使用两个参数调用突变观察者回调函数:

  • 记录列表
  • 对正在调用回调的突变观察者对象的引用

如果你正在对突变观察者重用突变事件回调,请小心。当发生相关突变时,MutationObserver 将在 MutationRecord对象中记录你请求的更改信息并调用你的回调函数,但直到当前范围内的所有脚本都运行之后才会进行此记录和调用。自上次调用回调后,有可能发生多个突变(每一个突变由单个 MutationRecord 表示)。

“记录”参数是一个 JavaScript 数组,由 MutationRecord 对象组成。该数组中的每个对象都代表在观察的元素上发生的一个突变。

记录具有下列属性:

MutationRecord 属性 说明

type

此记录所记录的突变的类型。可能值:attributescharacterDatachildList

target

在其上记录突变的元素。类似于 event.target 或 event.srcElement

addedNodesremovedNodes

作为此突变的一部分添加或删除的一组节点;仅在 type 是 childList 时才有意义。这些数组可以为空。

previousSiblingnextSibling

添加或删除的节点的上一个或下一个同辈;仅在 type 是 childList 时才有意义。这些值可以为 null

attributeNameattributeNamespace

已添加、删除或更改的属性的名称和命名空间。如果记录类型不是“属性”,值将为 null

oldValue

该属性的上一个值始终为 characterData。如果突变观察选项不包括attributeOldValue 或 characterDataOldValue 标志,或者 type 是childList,则该值可能为 null

IE 11中 onpropertychange失效的更多相关文章

  1. Cocos2d-x v3.11 中的新内存模型

    Cocso2d-x v3.11 一项重点改进就是 JSB 新内存模型.这篇文章将专门介绍这项改进所带来的新研发体验和一些技术细节. 1. 成果 在 Cocos2d-x v3.11 之前的版本中,使用 ...

  2. 从linux0.11中起动部分代码看汇编调用c语言函数

    上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...

  3. C++ 11 中的右值引用

    C++ 11 中的右值引用 右值引用的功能 首先,我并不介绍什么是右值引用,而是以一个例子里来介绍一下右值引用的功能: #include <iostream>    #include &l ...

  4. IOS中的Block与C++11中的lambda

    ios中的block 可以说是一种函数指针,但更确切的讲,其实际上其应该算是object-c对C++11中lambda的支持或者说是一个语言上的变体,其实际内容是一样的,C++的lambda我已经有简 ...

  5. 在Windows 8.1及IE 11中如何使用HttpWatch

    提示:HttpWatch现已更新至v9.1.8,HttpWatch v9.1及以上的版本现都已支持Windows 7,8,8.1和IE 11. 如果你的HttpWatch专业版授权秘钥允许进入vers ...

  6. 第三方支付过程中session失效问题

    第三方支付过程中session失效问题 时间 2015-05-13 12:36:23  IT社区推荐资讯 原文  http://itindex.net/detail/53436-session-问题 ...

  7. C++11中对类(class)新增的特性

    C++11中对类(class)新增的特性 default/delete 控制默认函数 在我们没有显式定义类的复制构造函数和赋值操作符的情况下,编译器会为我们生成默认的这两个函数: 默认的赋值函数以内存 ...

  8. callable object与新增的function相关 C++11中万能的可调用类型声明std::function<...>

    在c++11中,一个callable object(可调用对象)可以是函数指针.lambda表达式.重载()的某类对象.bind包裹的某对象等等,有时需要统一管理一些这几类对象,新增的function ...

  9. [转载] C++11中的右值引用

    C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...

随机推荐

  1. C# 将本地文件远程拷贝到其他电脑(转)

    string newpath = System.IO.Path.GetFullPath(@"////10.144.26.252//d$//quyuan//图片" +"// ...

  2. Java - 14 Java 日期时间

    java.util包提供了Date类来封装当前的日期和时间. Date类提供两个构造函数来实例化Date对象. 第一个构造函数使用当前日期和时间来初始化对象. Date( ) 第二个构造函数接收一个参 ...

  3. uWSGI, Gunicorn, 啥玩意儿?

    因为nginx等优秀的开源项目,有不少本来不是做服务器的同学也可以写很多服务器端的程序了.但是在聊天中会发现,大家虽然写了不少代码,但是对wsgi是什么,gunicorn是什么,反向代理又是什么并不了 ...

  4. linux杂项

    重装后激活root帐号并设置密码 sudo passwd root sudo: netstat:找不到命令 安装net-tools:sudo apt-get install net-tools Com ...

  5. idea error:Command line is too long

    今天在正在本地运行的项目中写了一个无关项目的测试类,执行main函数时报错如下: 解决方案: 找到项目根目录下的.idea/workspace.xml,添加内容: <component name ...

  6. django---单表操作之展示书籍列表

    下面使用python console对数据库进行增删改查 下面我们来举个例子在页面上展示记录 结果: 注意html里面变量的写法 {% for book in book_list %} <tr& ...

  7. ROS Industrial 简介

    ROS_I means ROS Industrial ROS_I 解决了哪些问题: 1. 让自动化可以互相协作,操纵器.末端执行器.感知系统/传感器,移动平台,周边设备,都可只用一种语言(ROS me ...

  8. 阿里云 putty链接服务器出现 server refused our key

    阿里云 putty链接服务器出现 server refused our key 创建了密钥对绑定实例,puttygen生成ppk,putty配置参数,连接,一步一步来的,结果出现 server ref ...

  9. mysql 外键引发的删除失败

    mysql> TRUNCATE TABLE role ; ERROR 1701 (42000): Cannot truncate a table referenced in a foreign ...

  10. pig简介

    Apache Pig是MapReduce的一个抽象.它是一个工具/平台,用于分析较大的数据集,并将它们表示为数据流.Pig通常与 Hadoop 一起使用:我们可以使用Apache Pig在Hadoop ...