DOM文档对象模型(二)

DOM编程

动态脚本

//<script src='dd.js'></script>引入外部脚本
//动态添加外部脚本
let a=document.createElement('script')
a.src='dd.js'
document.body.appendChild(a)
/*<script>
function a(){
console.log('a')
}
</script>内部脚本*/
//动态添加内部脚本
let b =document.createElement('script')
b.text='function a(){console.log('a')}'
document.body.appendChild(b)
//b.appendChild(document.createTextNode('function a(){console.log('a')}'))

注意通过innerHTML属性创建的<script>元素永远不会执行.

动态样式

//<link href='dd.css' rel='stylesheet' type='text/css'>//添加外部css样式
//动态添加外部脚本
let a=document.createElement('link')
a.href='dd.css'
a.rel='stylesheet'
a.type='text/css'
let head=document.getElementByTagName('head')[0]
document.head.appendChild(a)
/*<style>
div{
    width:100px;
}
</style>
内部脚本*/
//动态添加内部脚本
let a=document.createElement('style')
a.stylesheet.cssText='div{width:100px}'
let head=document.getElementByTagName('head')[0]
document.head.appendChild(b)
//b.appendChild(document.createTextNode('div{width:100px}'))

操作表格

table元素的方法与属性:

caption 标题

tBodies 包含tbody元素的HTMLCollection

tFoot 指向tfoot元素

tHead 指向tHead元素

rows 表示所有行的Htmlcollection

createTHead()创建thead元素,返回引用

createTFoot()创建tfoot元素,返回引用

createCaption()创建caption元素,返回引用

deleteTHead()删除thead元素

deleteTFoot()删除tfoot元素

deleteCaption()删除caption元素

deleteRow(pos)删除给定位置的行

insertRow(pos)在行集合中给定位置插入一行

tbody元素的方法与属性:

rows 表示tbody元素所有行的Htmlcollection

deleteRow(pos)删除给定位置的行

insertRow(pos)在表元集合中给定位置插入一行,返回引用

tr元素 的方法与属性:

cells包含<tr>元素所有表元的HTMLCollection

deleteCell(pos)删除给定位置的表元

insertCell(pos)在表元集合给定位置插入一个表元,返回该表元的引用.

使用NodeList

通过node.Childnodes得到的为Nodelist对象.

通过Element.Attributes得到的为NamedNodeMap集合.

通过Document.getElementByTagName(),Document.getElementByName()返回的为HTMLCollection对象.

NodeList,NamedNodeMap,HTMLCollection都是实时查询的.

MutationObserver接口

MutationObserver可以在DOM发生改变时,异步执行回调.

基本用法

Mutation通过调用MutationObserver构造函数并传入一个回调函数来创建.

let observer=new MutationObserver((a)=>{console.log(a)})

observe()方法

新创建的MutationObserver实例不会关联到任何DOM节点,要把这个实例与DOM关联起来,需要使用observe()方法.

这个方法接收两个必需的参数:要观察的DOM节点,以及一个MutationObserverInit对象.

MutationObserverInit对象用于控制观察那些方面的变化,是一个键/值对形式配置选项 的字典(映射)

let server=new MutationObserver((a)=>{console.log(a)})
server.observe(document.body,{attributes:true})//绑定body的属性变化

回调中的console.log是后调用的,即异步调用.

回调与MutationRecord

每次回调都会收到MutationRecord实例数组,其中包含的信息包括发生了什么变化,以及DOM的哪一部分受到了影响.因此回调之前可能同时发生多个满足观察条件的事件,所以每次执行回调都会传入一个包含按顺序入队的MutationRecord实例的数组.

第二个参数为观察变化的mutationObserver实例.

let server=new MutationObserver((mutationRecords,mutationObserver)=>{console.log(mutationRecords,mutationObserver)})
MutationRecord实例的属性

target 被修改影响的目标节点

type 字符串表示变化的类型’attributes’,’characterData’,’childList’

oldValue 如果在MutationObserverInit对象中启用(attributeOldvalue或characterData Oldvalue为true),会设置这个属性为被替代的值.childList这个属性始终为null

attributeName 对于’attributes’类型的变化,这里保存被修改属性的名字.其他为null

attributeNamespace 对于使用命名空间的’attributes’类型的变化,这里保存被修改的属性名称其他为NULL.

addedNodes 对于’childList’类型 的变化,返回添加节点的NodeList,默认为空

removeNodes 对于’childList’类型 的变化,返回删除节点的NodeList,默认为空

PreviousSibling 对于’childList’类型 的变化,返回添加节点的前一个同胞节点

nextSibling 对于’childList’类型 的变化,返回添加节点的后一个同胞节点

disconnect()方法

如果要提前终止执行回调,可以调用disconnect()方法

调用disconnect方法,不仅会停止之后变化事件的回调,也会抛弃已经加入任务队列的执行回调.

let a=new MutationObserver((a,b)=>{console.log(a,b)})
a.observe(document,{childNode:true})
a.append(document.createElement('div'));
a.disconnect();
//如果不想抛弃进入任务队列的回调
//settimeout(a.disconnect();a.append(document.createElement('div'));,0)异步使用
a.append(document.createElement('div'));

takeRecords()方法

清除记录队列,返回其中的所有MutationRecord实例.

希望断开与观察目标的联系,又想处理记录队列中的MutationRecord实例时比较有用.

复用MutationObserver

多次调用observe()方法,可以复用一个MutationObserver对象观察多个不同的目标节点.

而调用disconnect()会断开所有观测目标.

重用MutationObserver

调用disconnect()并不会结束MutationObserver的生命,还可以重新调用observe()方法,重新关联目标节点.

MutationObserverInit与观察范围

MutationObserverInit对象用于控制对目标节点的观察范围.

下表列出了MutationObserverInit对象的属性

attributes

设为 true 以观察受监视元素的属性值变更。默认值为 false。

attributeFilter

字符串数组,表示要观察那些属性的变化,把这个值设置成true,会将attributes的值转化为true,默认值为观察所有属性

attributeOldValue

布尔值,表示MutationRecord是否记录变化之前的属性值,把这个值设置成true,会将attributes的值转化为true,默认值为false

characterData

布尔值,表示修改字符数据是否触发变化事件

characterDataOldValue

布尔值,表示MutationRecord是否记录变化之前的属性值,把这个值设置成true,会将characterData的值转化为true,默认值为false

childList

布尔值,设为 true 以监视目标节点(如果 subtree 为 true,则包含子孙节点)添加或删除新的子节点。默认值为 false。

subtree

布尔值,表示除了目标节点,是否观察目标节点的子树(后代),如果为false,则只观察目标节点的变化,如果 subtree 为 true,则观察目标节点以及其子孙节点的变化

性能.内存与垃圾回收

1.MutationObserver的引用

MutationObserver实例与目标节点的引用关系是非对称的.MutationObserver拥有 对要观察目标节点的弱引用,因为弱引用,所有不会妨碍垃圾回收机制回收目标节点.

而目标节点却拥有对MutationObserver的强引用,如果目标对象 从DOM中被移除,然后被垃圾回收,则关联的MutationObserver也会被垃圾回收.

2.MutationRecord的引用

记录队列中的每个MutationRecord实例至少包含对已有DOM节点的引用.如果变化是ChildList类型,则会包含多个节点的引用.记录队列和回调处理的默认行为是耗尽这个队列,处理每个MutationRecord,然后让他们超出作用域被垃圾回收.

有时候可能需要保存某个观察者的完整变化记录,保存这些MUtationRecord实例,也就是要保持他们引用的节点,妨碍垃圾回收机制回收节点.如果需要尽快释放内存,建议从每个MutationRecord中抽取出最有用的信息.然后保存到一个新对象中.