JavaScript DOM扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JavaScript DOM扩展</title>
<link rel="stylesheet" href="./assets/transitions.css">
</head>

<body>
<div class="box" id="box" name="box" title="box" lang="en" dir="ltr">
<!-- <ul id="list">
<li>第一个节点</li>
<li>第二个节点</li>
<li>第三个节点</li>
<li>第四个节点</li>
<li>第五个节点</li>
</ul> -->
</div>
<script type="text/javascript">
// 立即执行函数
(function () {
// 严格模式
"use strict";
// JavaScript单线程设计的初衷就是为了操作DOM元素
// Node类型
// if (someNode.nodeType === Node.ELEMENT_NODE) {
// // 在IE中无效
// console.log("node is an element");
// if (someNode.nodeType === 1) {
// // 适用所有浏览器
// console.log("node is an element");
// }
// }
// nodeName的值是元素的标签名 nodeValue的值始终是null
// if (someNode.nodeType === 1) {
// value = someNode.nodeName;
// }

// 节点关系 childNodes firstNode lastNode parentNode nextSibling perviousSlibling
// var firstChild = someNode.childNodes[0];
// var secondChild = someNode.childNodes.item[1];
// var count = someNode.childNodes.length;

// 操作节点
// appendChild() 向childNodes列表的末尾添加一个节点
// insertBefore() 参数:要插入的节点,作为参照的节点。 被插入的节点会变成参照节点前的一个同胞节点previousSlibing,同时方法被返回。如果参照节点为null,则执行结果与appendChild()相同。
// replaceChild() 参数:要插入的节点,要替换的节点。
// removeChild() 参数:要移出的节点
// 其他方法: cloneNode() 用于创建调用这个方法的节点的一个完全相同的副本。
// var list = document.getElementById('list');
// var clist = list.cloneNode(true);
// console.log(clist.childNodes.length)
// var clonelist = list.cloneNode(false);
// console.log(clonelist.childNodes.length)

// document方法
// 对HTML的引用
var html = document.documentElement;
console.log(html === document.childNodes[0]);
console.log(html === document.firstChild);
// 对Body的引用
var body = document.body;
// 对<!DOCTYPE>的引用
var doctype = document.doctype;
// 设置文档标题
document.title = '标题';
// 取得完整URL
console.log(document.URL);
// 取得域名
console.log(document.domain);
// 取得来源页面的URL
console.log(document.referrer);
// 查找元素
// document.getElementById('id') 通过元素ID获取节点。
var div = document.getElementById('box');
// document.getElementByName('name') 通过元素Name获取节点。
var box = document.getElementsByName('box');
// document.getElementByTabName('div') 通过元素标签获取节点。
var tagDiv = document.getElementsByTagName('div');
// htmlControl
console.log(tagDiv.length);
console.log(tagDiv.item(0).className);
// document.getElementByTagName('*') 返回所有注释的节点
console.log(document.getElementsByTagName('*'));
// 特殊集合
// document.anchors 包含文档中所有带name特性的a元素
console.log(document.anchors);
// document.forms 包含所当中所有form元素
console.log(document.forms);
// document.images 包含文档中所有image元素
console.log(document.images);
// document.links 包含文档中所有带有href特性的a元素
console.log(document.links);
// Dom一致性检测 浏览器支持此给定名称及版本的功能,则返回true
var hasXmlDom = document.implementation.hasFeature('XML', '1.0');
console.log(hasXmlDom);
// 文档写入
document.writeln('我是无敌的!'); // 会在字符串末尾添加一个换行\n
document.write('我就是超级无敌宇宙赛亚人!'); // 要写入输出流的文本
document.open() // 打开网页的输出流
document.close() // 关闭网页的输出流
// element类型
var dbox = document.getElementById('box');
// 适用于任何文档
if(dbox.tagName.toLowerCase === 'div'){
return true;
}
// html元素
console.log(dbox.id);
console.log(dbox.className);
console.log(dbox.title);
console.log(dbox.lang);
console.log(dbox.dir);
// 取得特性
console.log(dbox.getAttribute('id'));
// 删除特性
console.log(dbox.removeAttribute('class'))
// 设置特性
console.log(dbox.setAttribute('class','box'));
// attributes 属性
// attributes.getNamedItem(name) 返回nodeName属性等于name的节点
// attributes.removeNamedItem(name) 从列表中移除nodeName属性等于name的节点
// attributes.setNamedItem(node) 向列表中添加节点,以节点的nodeName属性为索引
// attributes.item(pos) 返回位于数字pos位置出的节点
console.log(dbox.attributes.length);
// attributes.specified 默认值为false
console.log(dbox.attributes.specified);
// 创建元素
var div = document.createElement('div')
document.getElementById('box').appendChild(div);
// 元素的子节点
for(var i = 0; i < document.childNodes.length; i++){
if(dbox.childNodes[i].nodeType === 1){
return true;
}
}
// Text类型
// appendData(text) 将text添加到节点的末尾
// deleteData(offset, count) 从offset指定位置开始删除count个字符
// instertData(offset, text) 在offset指定的位置插入text
// replaceData(offset, count, text) 用text替换从offset指定的位置开始到offset+count为止处的文本
// splitText(offset) 从offset指定的位置将当前文本节点分成两个文本节点
// substringData(offset, count) 提取从offset指定的位置开始到offset+count为止出的字符串
// length属性

// 创建文本节点
document.createTextNode('文本节点')
// 规范化文本节点
// normalize()
// 分割文本节点
// splitText(offset: unsigned long)

// Comment类型 CDATASection类型
// comment类型、CDATASection类型与text类型继承自相同的基类,因此它拥有除splitText()之外的所有字符串操作方法。

// DocumentType类型
console.log(document.doctype)
// DocumentFragment类型
// document fragment 是一种轻量级文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源。
// 创建文档片段
document.createDocumentFragment()

// Attr类型
// Attr对象有三个属性:name, value, specified

// Dom操作技术
// 动态脚本
var js = document.createElement('script');
js.type = 'text/javascript';
document.body.appendChild(js);

// 动态样式
function loadStyle(url){
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = url;
var head = document.getElementsByTagName('head')[0];
head.appendChild(link);
}

loadStyle("style.css");

// 操作表格
// <table> 的属性和方法
// caption 保存着对<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) 向rows集合中指定位置插入一行

// <tbody> 的属性和方法
// rows 保存<tbody>元素中的HTMLCollection
// deleteRow(pos) 删除指定位置的行
// insertRow(pos) 向rows集合中指定位置插入一行

// <tr> 的属性和方法
// cells 保存着<tr>元素中单元格的HTMLCollection
// deleteCell(pos) 删除指定位置的单元格
// insertCell(pos) 向cells集合中的指定为会插入一个单元格,返回对新插入的单元格的引用

// 使用NodeList

// querySelector() 方法 接收一个CSS选择符,返回与该模式匹配的第一个元素,没有则返回null
var body = document.querySelector('body');


// querySelectorAll() 方法 接收一个CSS选择符,返回与该模式匹配的所有元素,没有则返回null
var stongs = document.querySelectorAll('p strong');

// matchesSelector() 方法 接收一个CSS选择符,如果调用元素与该选择符匹配,则返回true,否则,返回false.
matchesSelector(document.body, "body.page1")

// 元素遍历
// childElementCount 返回子元素的个数
// firstElementChild 指向第一个子元素:firstChild的元素版
// lastElementChild 指向最后一个子元素:lastChild的元素版
// previousElementSibling 指向前一个同辈元素:previousSibling的元素版
// nextElementSibling 指向后一个同辈元素:nextSibling的元素版

// HTML
// 与类相关的扩充
// getElementsByClassName()方法 接收一个参数,即一个包含一或多个类名的字符串,返回带有指定类的所有元素的NodeList

// classList属性 这个classList属性是新集合类型DOMTokenList的实例
// add(value) 将给定的字符串值添加到列表中。如果值已经存在,就不添加了
// contains(value) 表示列表中是否存在给定的值,返回true/false
// remove(value) 从列表中删除给定的字符串
// toggle(value) 如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它

// 焦点管理
// document.activeElement 属性
// HTML5添加了辅助管理DOM焦点的功能。首先是document.activeElement属性。这个属性始终会引用DOM中当前获得焦点的元素
// document.hasFocus()方法 确定文档是否获得了焦点

// HTMLDocument的变化
// readyState属性值:loading,正在加载文档 | complete,已经加载完文档
// 兼容模式 compatMode的属性
if (document.compatMode === "CSS1Compat") {
console.log('Standards mode');
} else {
console.log('Quirks mode');
}
// head属性 document.head

// 字符集属性
document.charset = "UTF-8";

//自定义数据属性
// 设置值
// document.getElementById('box').dataset.appId = 123
// document.getElementById('box').dataset.myname = "Michael"

// if (document.getElementById('box').dataset.myname) {
// console.log(document.getElementById('box').dataset.myname);
// }

// 插入标记
// div.innerHTML = "<input type=\"hidden\"><script>alert('hi');<\/script>";

// outerHTML属性
// 返回调用他的元素及所有子节点的HTML标签
// div.outerHTML = "<p>This is a paragrph.</p>"

// insertAdjacentHTML()方法
// beforebegin 在当前元素之前插入一个紧邻的同辈元素
// element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>");
// afterbegin 在当前元素之下插入一个新的子元素火灾第一个子元素之前再插入新的子元素
// element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>");
// beforeend 在当前元素之下插入新的子元素或最后一个子元素之后再插入新的子元素
// element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>");
// afterend 在当前元素之后插入一个紧邻的同辈元素
// element.insertAdjacentHTML("afterend", "<p>Hello world!</p>");


// 内存和性能问题
// 在替换子节点可能会导致浏览器的内存占用问题。在使用innerHTML、outerHTML、insertAdjacentHTML方法时,最好手工删除要被替换的元素的所有回见处理程序和JavaScript对象属性。

// scrollIntoView()方法
// 可以在所有HTML元素上调用,通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视口中。
// 传入true作为参数,或者不传入任何参数时,串口滚动之后会让调用元素的顶部与视口尽可能平齐
// 传入false作为参数,调用元素会尽可能全部出现在视口中,(可能的话,调用元素的底部会与视口顶部平齐。)不过顶部不一定平齐

// 让元素可见
// document.forms[0].scrollIntoView();

// 文档模式
// <meta http-equiv="X-UA-Compatible" content = 'IE=IEVersion'>
// IEVersion:
// Edge:始终以最新的文档模式来渲染页面。忽略文档类型声明。
// EmulateIE9:如果有文档类型声明,则以IE9标准模式渲染页面,否则将文档模式设置为IE5。
// EmulateIE8:如果有文档类型声明,则以IE8标准模式渲染页面,否则将文档模式设置为IE5。
// EmulateIE7:如果有文档类型声明,则以IE7标准模式渲染页面,否则将文档模式设置为IE5。
// 9:强制以IE9标准模式渲染页面,忽略文档类型声明。
// 8:强制以IE8标准模式渲染页面,忽略文档类型声明。
// 7:强制以IE7标准模式渲染页面,忽略文档类型声明。
// 5:强制以IE5标准模式渲染页面,忽略文档类型声明。

// children属性 只包含元素中同样还是元素的子节点
// var childCount = element.children.length;

// contains()方法
// 调用contains()方法的应该是祖先节点,也就是搜索开始的节点,这个方法接收一个参数,即要检查的后代节点。返回值 true/false
// document.documentElement.contains(document.body);

// 插入文本

// innerText 属性 可以操作元素中包含的所有文本内容,包括子文档树中的文本。
// div.innerText = "Hello world!"

// outerText 属性 读取文本内容
// console.log(div.outerText)

// 滚动
// scrollIntoViewIfNeeded() 只在当前元素在视口中不可见的情况下,才滚动浏览器窗口或容器元素,最终让它可见。
// scrollByLines() 将元素的内容滚动指定的行高
// scrollByPages() 将元素的内容滚动指定的页面高度,具体高度由元素的高度决定。
// document.body.scrollIntoViewIfNeeded(true)
// 将页面主体滚动5行
// document.body.scrollByLines(5)
// 将页面主体滚动1页
// document.body.scrollByPages(-1)
})();
</script>
</body>

</html>