第九章-DOM部分笔记
从JS基础到JS-web-API
- JS 基础规定 JS 语法,它是ECMA262组织规定的。
- JS-web-API 是用于网页操作的API,它是由W3C规定的。
- 前者是后者的基础,两者结合才能真正实际应用。
js基础知识:
- 变量的类型和计算
- 原型和原型链
- 作用域和闭包
- 异步操作...
JS-web-API包括
- DOM(文档对象模型)
- BOM(浏览器对象模型)
- 事件绑定
- ajax操作
- 存储...
DOM(Document Object Model,文档对象模型)
目前流行的vue、react框架,都对DOM进行了封装,并且避免我们直接操作DOM。但DOM操作一直是前端工程师必备的基础知识,因此必须掌握这一部分的知识。可以参考这篇文章
DOM的本质
DOM可以理解为浏览器把拿到的 html 代码,结构化为一个浏览器可以识别并且可以通过 Javascript 操作的模型。参考这篇文章
DOM节点操作
1. 获取DOM节点的几种操作
根据id获取元素,返回id值对应的元素(单个)
var idObj = document.getElementById(“元素的id名”);
根据标签名获取元素,返回一个包含所有span标签的伪数组
var spans = document.getElementsByTagName(“span”);`
根据name属性值获取,返回一个name属性值为hobby的伪数组
```javascript
var inputs= document.getElementsByName(‘hobby’);
根据类名获取元素,返回一个类名为main的伪数组
var mains = document.getElementsByClassName(“main”);
根据选择器获取元素,
这是根据id选择器获取元素,返回单个元素
var text = document.querySelector(‘#text’);
这是根据类选择器获取元素,返回一个伪数组
var boxes = document.querySelectorAll(‘.box’);
Attribute 和 Property
Attribute 和 Property 的区别
- Attribute 是 HTML 标签上的特性,它的值只能是字符串
- Property 是 DOM 中的属性,是 JavaScript 里的对象
简单理解:attribute 是 DOM 节点自带的属性,例如 html 中常用的 id、class、title等属性,
而 property 是这个 DOM 元素作为对象,其附加的内容,如childNodes、firstChild等。
有以下代码:
<div id='box'>
<div id="div1" class="divClass" title="divTitle" title1="divTitle1"></div>
</div>
<script>
var box=document.getElementById("box");
var div1 = document.getElementById("div1")
console.log(box.childNodes)
console.log(div1.attributes);
console.log(div1.title1)
</script>
对于 id 为 div1 的 div,它的 property 内容如下:(部分)
可以发现有一个名为 "attributes" 的属性,类型是 NamedNodeMap,同时有"id"和"className"、"title"等基本的属性,但没有"titles"这个自定义的属性。
也就验证了:property 中有 attribute 自带的属性,但是没有自定义属性。
console.log(div1.id); //div1
console.log(div1.className); //divClass
console.log(div1.title); //divTitle
console.log(div1.title1); //undefined
可以发现,html 标签中的属性,"id" 和 "className"、"title" 会在 div1 上创建,而 "titles" 不会被创建。这是由于,每一个DOM对象都会有它默认的基本属性,而在创建的时候,它只会创建这些基本属性,我们在TAG标签中自定义的属性是不会直接放到DOM中的。
我们可以在 上面打印出的 property 中的 attributes 属性中找到 title1。
"title1" 被放在了 attributes 这个对象里,这个对象按顺序记录了我们在 html 标签中定义的属性和属性的数量。
从这里可以看出: attributes 是属于 property 的一个子集,它保存了HTML标签上定义属性
property 和 attribute 的区别
-
property: 修改对象属性,不会体现到 html 结构中
-
attribute: 修改 html 属性,会修改 html 结构
-
两者都有可能引起DOM的重新渲染
结论:
-
property能够从attribute中得到同步;
-
attribute不会同步property上的值;
-
attribute和property之间的数据绑定是单向的,attribute->property;
-
更改property和attribute上的任意值,都会将更新反映到HTML页面中;
这部分内容参考这篇文章
DOM结构操作
1. 新增/插入节点
- document.write(“标签代码及内容”);
//document.write("标签代码及内容"); 会把原来页面上所有的内容都给覆盖掉
document.getElementById("btn").onclick=function () {
document.write("<p>这是一个p</p>");
};
- 对象.innerHTML=”标签及代码”;
//点击按钮,在div中创建一个p标签
//第二种方式创建元素: 对象.innerHTML="标签代码及内容";
document.getElementById("btn").onclick=function () {
document.getElementById("btn").innerHTML="<p>窗前明月光,疑是地上霜,举头望明月,低头思故乡</p>";
};
- document.createElement(“标签及内容”); 创建完成之后需要追加到父级元素中
//创建元素
//document.createElement("标签名字");对象
//把元素追加到父级元素中
//点击按钮,在div中创建一个p
document.getElementById("btn").onclick = function () {
//创建元素的
var pObj = document.createElement("p");
pObj.innerText = "这是一个p";
//把创建后的子元素追加到父级元素中
document.getElementById("dv").appendChild(pObj);
};
2. 获取子元素/父元素
var div1 = document.getElementById('div1')
var parent = div1.parentElement // 只能有一个父元素
var children = div1.childNodes //可以有多个子元素
console.log(parent)
console.log(children[1])
3. 删除一个元素
var div1 = document.getElementById('div1')
var children = div1.childNodes //可以有多个子元素
div1.removeChild(children[1]) // 移除元素
优化DOM操作性能
- DOM操作非常昂贵,避免频繁操作DOM
- 对DOM查询做缓存
- 将频繁操作改为一次性操作
对DOM查询做缓存
将频繁操作改为一次性操作,创建一个文档片段 document.createDocumentFragment()
,先插入到文档片段中,最后一次性将内容插入DOM结构中