DOM: Document Object Model(文档对象模型)
DOM树:
回流和重绘
重绘(repaint):
当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此损耗较少。
常见的重绘操作有:
- 改变元素颜色
- 改变元素背景色
-
回流(reflow):
又叫重排(layout)。当元素的尺寸、结构或者触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。
常见的回流操作有: 页面初次渲染
- 浏览器窗口大小改变
- 元素尺寸/位置/内容发生改变
- 元素字体大小变化
- 添加或者删除可见的 DOM 元素
- ……
重点:回流必定会触发重绘,重绘不一定会触发回流。重绘的开销较小,回流的代价较高。
DOM 操作
1、获取元素
1.1 根据id名获取
document.getElementById(idName)
1.2 根据标签名获取
document.getElementsByTagName(tagName) // 返回一个集合 (类数组对象) 从整个文档获取element.getElementsByTagName(tagName) // 从element的后代元素中获取
1.3 根据类名获取(不兼容ie6~8)
document.getElementsByClassName(className) // 返回一个集合(类数组对象) 从整个文档获取element.getElementsByClassName(className) // 从element的后代中获取
1.4 根据 name 属性值获取
正常的规范中,咱们只会给表单元素起name值,如果给其它元素设置name,在ie9以下版本浏览器不兼容,是获取不到的, 所以为了这种情况,咱们以后养成习惯,只给表单元素用name,非表单元素不用name
document.getElementsByName() //返回集合 只有document才有该方法
1.5 根据选择器获取
注意:querySelector 和querySelectorAll 在ie6-ie8 下不兼容
document.querySelector(选择器) //选择器第一个满足选择器条件的document.querySelectorAll(选择器) //选择所有满足选择器条件的,返回nodeList(类数组对象)element.querySelector(选择器)element.querySelectorAll(选择器)
1.6 document.head
获取Head元素对象
1.7 document.body
获取body元素对象
1.8 document.documentElement
2、获取一屏幕的宽度或者高度,兼容所有的浏览器
// 获取一屏幕的高度var vH = document.documentElement.clientHeight || document.body.clientHeight;// 偶去一屏幕的宽度var vW = document.documentElement.clientWidth || document.body.clientWidth;
3、练习题:
获取页面中所有name属性值为 “hehe” 的元素标签
<!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>Document</title><style></style></head><body><div class="box1"><input type="text" name="hehe"></div><input class="box1" name="hehe"></body></html><script>function getElementsByName(value){var allTag=document.getElementsByTagName("*");var names=[];for(var i=0;i<allTag.length;i++){var item=allTag[i];if(item.name==value){names.push(item);}}return names;}var ary=getElementsByName("hehe")</script>
getAttribute() ====>该方法返回指定属性名的属性值。
需求:获取指定范围下所有name属性值为 “hehe” 的元素标签
<!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>Document</title></head><body><div id="main"><div class="box1"><input type="text" name="hehe" id="input1"><div name="hehe" id="div2">111</div></div><input class="box1" name="hehe"></div></body></html><script>var omain = document.getElementById("main");function getName(context, name, attr) {var tags = context.getElementsByTagName("*");var ary = [];for (var i = 0; i < tags.length; i++) {if (tags[i].getAttribute(name) == attr) {ary.push(tags[i])}}return ary;}var res = getName(omain, "name", "hehe");console.log(res);</script>
4、id小妙招
直接把id当成变量去用的时候,可以获取相应的id元素。(浏览器的机制)
<div id="box1">111</div><script>console.log(box1)</script>
2、节点
- 文档节点
- 属性节点
- 元素节点
- 文本节点
-
2.1 文档节点
nodeType(节点类型):9
- nodeName(节点名称):”#document”
nodeValue(节点值):null
document.nodeType;document.nodeNamedocument.nodeValue;
2.2 属性节点
nodeType:2
- nodeName:属性名
- nodeValue:属性值
getAttributeNode() 方法从当前元素中通过名称获取属性节点。
<a href="http://www.baidu.com" id="a1">百度</a>var a1=a1.getAttributeNode("href");// 获取属性节点console.log(a1.nodeType);//2console.log(a1.nodeName);//"href"; 属性名console.log(a1.nodeValue);//"http://www.baidu.com"; 属性值
2.3 元素节点
- nodeType:1
- nodeName:大写的标签名
- nodeValue:null
```javascript百度
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!111
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!111
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!111
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
> 自己手动封装一个previousElementSibling,要兼容。```javascript<!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>Document</title><style></style></head><body><span id="span1">1</span><ul id="main"><!-- 我是注释 --><li>选择珠峰的,都是明智的!</li><li>选择珠峰的,都是明智的!</li><li>选择珠峰的,都是明智的!</li><li>选择珠峰的,都是明智的!</li></ul><span id="span2">2</span></body></html><script>function previousElmentSibling(ele){var pre=ele.previousSibling;while(pre&&pre.nodeType!==1){pre=pre.previousSibling;}return pre;}console.log(previousElmentSibling(span2))</script>
DOM 的增删改
1、createElement:创建一个元素
document.createElement("div");
2、createTextNode: 创建一个文本节点
var otext=document.createTextNode("哈哈!");
3、appendChild:把元素追加到一个容器的末尾
语法:[context].appendChild([元素]);
<div id="id1"></div><script>var odiv = document.createElement("div");id1.appendChild(odiv);console.log(id1)</script>
4、insertBefore: 把一个元素插入到另一个元素的前面
首先要指定一个父节点
var insertedNode = 父节点.insertBefore(要插入的节点, 插在这个节点之前)
var insertedNode = parentNode.insertBefore(newNode, referenceNode)
- newNode:将要插入的节点
- referenceNode:被参照的节点(即要插在该节点之前)
- insertedNode:插入后的节点
parentNode:父节点
<div id="id1"><p class="p1" id="p1">这是P1</p></div><script>var div = document.getElementById('id1');var p1 = document.getElementById('p1');var odiv = document.createElement("div");var returnDom = div.insertBefore(odiv, p1);console.log(div)</script>
5、cloneNode:把某一个节点进行克隆
【ele】.cloneNode();浅克隆: 只是克隆了一个节点,里面的内容还有样式都没克隆
【ele】.cloneNode(true);深克隆:把节点包含的所有内容进行克隆
<div id="id1"><p class="p1" id="p1">这是P1</p></div><script>var res = id1.cloneNode();var res2 = id1.cloneNode(true)console.log(res)console.log(res2)</script>
6、removeChild:移除某个节点
【context】.removeChild(ele);
<div id="id1">1111<p class="p1" id="p1">这是P1</p></div><script>id1.removeChild(p1);console.log(id1)</script>
7、set/get/removeAttribute
设置/获取/删除 当前元素的某一个自定义属性
setAttribute
- getAttribute
- removeAttribute
基于键值对方式 增删改:修改当前对象的堆内存空间完成的(在堆内存空间可以看到)box.setAttribute("index", 1);box.getAttribute("index");box.removeAttribute("index");console.log(box)// 设置// box["aa"] = 22;// 获取// box["aa"]//移除// delete box["aa"];
基于Attribute dom方法增删改,是修改html结构来完成的(此种方法设置的在结构上可以看到)
以上两种方式不能混用
