Dom
JavaScript操作网页的接口,全称为“文档对象模型(Document Object Model)。 有这几个概念:文档、元素、节点
1.DOM本质
DOM树是结构,树是由DOM元素和属性节点组成的,DOM的本质是把html结构化成js可以识别的树模型;
有了树模型,就有了层级结构,层级结构是指元素和元素之间的关系父子,兄弟。
2.操作DOM
2.1获取dom
2.1.1通过id获取 document.getElementById
//通过id获取到的是单个元素
<body>
<div id="box"></div>
</body>
</html>
<script>
//通过id获取到的是单个元素
let oBox=document.getElementById("box")
console.log(oBox); //<div id="box"></div>
</script>
2.1.2通过class名来获取 document.getElementClassName
//通过tag标签来获取 获取到的是集合,一组元素,但不是数组
<body>
<div class="box"></div>
</body>
</html>
<script>
//通过class类名来获取 获取到的是集合,一组元素,但不是数组,
let oBox2=document.getElementsByClassName("box")
console.log(oBox2); //HTMLCollection [div.box]
</script>
2.1.3通过标签名来获取 documen.getElementByTagName
//通过tag标签来获取 获取到的是集合,一组元素,但不是数组,
<body>
<div class="box"></div>
</body>
</html>
<script>
//通过tag标签来获取 获取到的是集合,一组元素,但不是数组,
let oBox2=document.getElementsByTagName("div")
console.log(oBox2); //HTMLCollection [div.box]
//同上面的一样
</script>
2.1.4通过name来获取 document.getElementsByName
//通过tag标签来获取 获取到的NodeList节点集合
<body>
<div class="box" name="boxs"></div>
</body>
</html>
<script>
//通过tag标签来获取 获取到的NodeList节点集合
let oBox2=document.getElementsByName("boxs")
console.log(oBox2); //NodeList [div.box]
</script>
2.1.5 h5中新增了两种,通过选择器进行获取dom元素
//通过querySelector获取到的是单个元素 document.querySelector(".类名")
<body>
<div class="box" name="boxs"></div>
</body>
</html>
<script>
//通过querySelector获取到的是单个元素
let oBox=document.querySelector(".box")
console.log(oBox); //<div class="box" name="boxs"></div>
</script>
//通过querySelectorAll获取到的是单个元素 document.querySelector(".类名")
<body>
<div class="box">123</div>
<div class="box">321</div>
</body>
</html>
<script>
//通过querySelector获取到的是NodeList节点结合
let oBox=document.querySelectorAll(".box")
console.log(oBox); //NodeList [div.box]
//可以通过下标进行获取到某个元素
let oBox=document.querySelectorAll(".box")[0]
console.log(oBox);//获取到类名为box的第一个元素
</script>
2.1.6如何获取body呢? document.body
2.1.7如何获取html呢?document.document.Element
2.2 增(添加节点)
简述一下innerHTML和innerText的区别?
innerHTML能够识别带有标签的内容,innerText无法识别标签;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
width: 300px;
height: 300px;
border: 2px solid #ccc;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
<script>
let oBox=document.querySelector(".box")
// oBox.innerHTML="hello 冯丫丫"
// oBox.innerHTML="<h2>哈哈哈哈</h2>" //页面显示的h2标签的样式
// oBox.innerText="hello 冯丫丫2"
// oBox.innerText = "<h2>哈哈哈哈</h2>" //页面显示的是<h2>哈哈哈哈</h2>,无法识别
</script>
2.2.1 创建元素节点 document.createElement
<body>
<div class="father"></div>
</body>
</html>
<script>
//1.获取father这个盒子
let fa=document.querySelector(".father")
//在创建之前页面中只有father盒子
//2.创建节点元素
let tag=document.createElement("h1")
//3.创建的节点元素添加到父节点中
fa.appendChild(tag)
//添加成功后
// < div class="father" >
// <h1></1>
//</div >
//4.创建文本元素
let text = document.createTextNode('hello')
tag.appendChild(text)
//为了使增加的节点在页面效果更明显,将内容添进去
</script>
2.2.2删除 removeChild
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
// 现获取父
let oUl=document.querySelector('ul')
// 再获取子
let oLi=document.querySelectorAll('li')[1]
//父节点删除子节点
oUl.removeChild(oLi)
2.2.3替换 replaceChild
// 现获取父
let oUl=document.querySelector('ul')
// 再获取子
let oLi=document.querySelectorAll('li');
// 必须是同一个父
oUl.replaceChild(oLi[1],oLi[0])
2.2.4插入 insertBefore
替换的元素必须是在同一个父节点中的子节点才可以实现替换
// 现获取父
let oUl=document.querySelector('ul')
// 再获取子
let oLi=document.querySelectorAll('li');
let other=document.createElement('a')
other.innerText='百度'
// 必须是同一个父
oUl.insertBefore(other,oLi[1])
2.2.5文档碎片 createDocumentFragment
方法一:我们可以使用for循环进行遍历添加;这种方法虽然可以实现但是性能并不良好,可能会造成回流
//获取ul
let oUl = document.querySelector("ul")
//for循环
for (var i = 0; i < 3; i++) {
let dot = document.createElement('li');
dot.innerHTML = `${i + 4}`
oUl.appendChild(dot)//通过appendChild把创建的li添加进去
}
那么什么是回流呢?什么是重绘呢?两者有什么区别呢?
1.回流:页面中元素的尺寸,布局,隐藏等改变而需要重新构建页面,就会引起回流。
2.重绘:页面中元素属性发生改变,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如
background-color
。则就叫称为重绘。3.区别:回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流
当页面布局和几何属性改变时就需要回流
比如:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变
方法二: 优化项目,提高性能 应用场景: 注:当页面某个dom需要添加多个子元素时,我们可以先创建文档碎片,再把多个元素放入碎片,最后把碎片添加到页面的某个元素中
// 创建文档碎片
let oUl = document.querySelector("ul") //先获取到ul
let frag = document.createDocumentFragment();//创建文档碎片
for (var i = 0; i < 3; i++) {
let dot = document.createElement('li');
dot.innerHTML = `${i + 4}`
frag.appendChild(dot)//把创建的多个元素放在文档碎片中
}
oUl.appendChild(frag)//把碎片添加到页面某个元素中
3.Dom节点的Attribute和Property有和区别?
Attribute:修改html属性,会改变html结构
Property:修改对象属性,不会体现到html结构中
两者都有可能引起Dom重新渲染;