佛山三水区有没有网站建设公司,上海做网站最低价,网址导航哪个好?,网站如何关闭了解Web API的DOM和BOM引言正文一、DOM操作1、DOM的本质2、DOM节点操作#xff08;1#xff09;property形式#xff08;2#xff09;attribute形式3、DOM结构操作#xff08;1#xff09;新增/插入节点#xff08;2#xff09;获取子元素列表#xff0c;获取父元素1property形式2attribute形式3、DOM结构操作1新增/插入节点2获取子元素列表获取父元素3删除子元素4、DOM性能1对DOM查询做缓存2将频繁操作改为一次性操作5、回顾二、BOM操作1、navigator2、screen3、location4、history结束语引言
在现代的开发中vue和react都是很流行的开发框架框架虽好用但是框架的原理还是基于 DOM 操作去实现。如果一个前端工程师只会框架不会 DOM 那基本上是很容易被淘汰的。因为框架的存活时间我们谁也说不准且技术更新迭代也特别快说不定三五年就会被淘汰了都有可能。所以扎实的学会 js 的基础原理不要被框架和一些外部事件所迷惑对自己会有一个更好的竞争力提升。
本文将讲解 JS 中 Web API 的 DOM 和 BOM 操作。
正文
一、DOM操作
DOM操作即Document Object Model文档对象模型。下面通过几个知识点来分析DOM的本质、节点操作、结构操作以及 DOM 的性能。
1、DOM的本质
DOM的本质就是一棵 树 是树结构。
我们从早起xml说起xml是一种可扩展性的标准语言早期基本是用xml来对DOM进行编写。具体形式如下
?xml version 1.0 encoding UTF-8?
notetoTony/tofromAbby/fromheadingLondon/headingbodyHave a nice day!/bodyothera/ab/b/other
/note我们可以看到一层一层的下来层层递进很像一棵树。 回到现在我们基本上用的是 html 来进行编写。 html 也是一种特定的 xml 只不过它是有自己的一套规范比如说我们常见的 p 标签 span 标签 li 标签等等。引用百度来做一个解释 大家可以看到上面一层一层递进的关系把整个 html 渲染出来形成我们看到的页面这一层层递进的关系其实就是 DOM 树所以也可以说 DOM 是从 html 文件解析出来的一棵树。
2、DOM节点操作
DOM节点主要有两种操作一种是property操作另一种是attribute操作。下面让我们来看看这两种操作。
1property形式
html代码
div iddiv1 classcontainerp文段 1/pp文段 2/pp文段 3/p
/div
div iddiv2img srchttps://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u2144980717,2336175712fm58 alt
/divJS代码
/*** property形式*/const pList document.querySelectorAll(p);const p1 pList[0];p1.style.width 100px; //修改样式console.log(p1.style.width); //获取样式p1.className red; //修改class名称console.log(p1.className); //获取class名称// 获取nodeName和nodeTypeconsole.log(p1.nodeName); //打印节点名称pconsole.log(p1.nodeType); //打印节点类型普通的DOM节点元素为1文本类型是3控制台打印结果如下 从上面的结果中可以看到通过修改 DOM 的 JS 变量从而操作 DOM 最终得到我们想要的结果。
2attribute形式
html代码
div iddiv1 classcontainerp文段 1/pp文段 2/pp文段 3/p
/div
div iddiv2img srchttps://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u2144980717,2336175712fm58 alt
/divJS代码
/*** attribute形式*/const pList document.querySelectorAll(p);const p1 pList[0];p1.setAttribute(data-name, immoc);console.log(p1.getAttribute(data-name));p1.setAttribute(style, font-size:50px;);console.log(p1.getAttribute(style));控制台打印结果如下 从上面的结果中可以看到通过修改 DOM 结构的节点属性最终得到我们想要的结果。
综上所述 porperty 和 attribute 这两种操作类型主要有以下区别
property修改对象属性不会体现到 html 结构中attribute修改 html 属性会改变 html 结构即标签结构两者都有可能引起DOM重新渲染但 attribute 引起 DOM 重新渲染的可能性更大因为它会改动 html 的结构。所以在实际开发中可以选择的话尽量渲染 property 去操作 DOM 。
3、DOM结构操作
通过上面的了解我们都明白了DOM是一种树结构。那既然是树结构就应该可以对节点进行增删改的操作。
因此DOM结构操作主要有以下三种类型
新增/插入节点获取子元素列表获取父元素删除子元素。
接下来对这三种类型进行讲解。
1新增/插入节点
先附上html代码。
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/title
/head
bodydiv iddiv1 classcontainerp id p1文段 1/pp文段 2/pp文段 3/p/divdiv iddiv2 img srchttps://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u2144980717,2336175712fm58 alt/divscript src./你的文件路径.js/script
/body
/html此时执行状态如下。 如果此时要给 div1 新增一个子节点 p 代码如下。
// 新建节点
const newP document.createElement(p);
newP.innerHTML this is newP;
// 插入节点
div1.appendChild(newP);此时浏览器执行状态如下。 大家可以看到 div1 成功新增了一个节点这就是关于新增节点操作的具体流程。
那如果在此基础上要移动一个节点呢具体操作如下。
// 移动节点 - 把p1移动到div2中来
const p1 document.getElementById(p1);
div2.appendChild(p1);此时浏览器执行状态如下。 2获取子元素列表获取父元素
在上面的基础上我们来看看获取父元素和子元素列表的流程。
// 获取父元素
console.log(p1.parentNode);// 获取子元素列表
const div1ChildNodes div1.childNodes;
console.log(div1ChildNodes); //此处获取的包含p标签以及p标签下面的文本因此需要一层过滤
const div1ChildNodesP Array.prototype.slice.call(div1.childNodes).filter(child {if(child.nodeType 1){return true;}else{return false;}
});
console.log(div1ChildNodesP, div1ChildNodesP);此时浏览器执行状态如下。 3删除子元素
在上面操作的基础上我们现在对 div1 中的第一个 p 节点进行移除。
// 移除元素
div1.removeChild(div1ChildNodesP[0]);此时浏览器执行状态如下。 以上就是对DOM结构的新增、移动、获取子父元素以及删除子元素的一个操作相信大家对DOM结构的增删改有了一个新的了解。接下来我们讲解DOM性能。
4、DOM性能
为什么要对DOM做性能优化呢原因在于 DOM 操作是非常“昂贵”的每一次操作都很有可能引发浏览器的重排和重绘因此要避免频繁的 DOM 操作。那如何做到避免频繁的 DOM 操作给 DOM 进行性能优化呢主要有以下两个方面给 DOM 操作进行性能优化
对 DOM 查询做缓存将频繁操作改为一次性操作
接下来将对这两种方法进行讲解。
1对DOM查询做缓存
// 不缓存 DOM 查询结果
for(let i 0; i document.getElementsByTagName(p).length; i){// 每次循环都会计算length频繁进行 DOM 查询
}// 缓存 DOM 查询结果
const pList document.getElementsByTagName(p);
const length pList.length;
for(let i 0; i length; i){// 缓存length只进行一次 DOM 查询
}分析以上两段代码在第一段当中每次循环的时候都会计算 length 频繁的对 DOM 进行查询如此频繁的操作可想对程序都不是不太好的。
因此通过优化我们写出第二段代码。在第二段代码中把 length 放在外部进行缓存等到每次循环的时候只需要进行一次 DOM 查询而不用像第一段一样频繁操作极大提高了性能。
2将频繁操作改为一次性操作
我们来看一个例子。比如说我们先在要通过操作 DOM 来一次性插入10个列表。
在正常情况下我们想象的操作如下
html代码
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/title
/head
bodydiv iddiv1 classcontainerp id p1文段 1/pp文段 2/pp文段 3/p/divdiv iddiv2 img srchttps://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u2144980717,2336175712fm58 alt/divul idlist/ulscript src./你的路径.js/script
/body
/htmljs代码
const list document.getElementById(list);for(let i 0; i 10; i){const li document.createElement(li);li.innerHTML List item ${i};list.appendChild(li);
}此时浏览器执行状态如下。 按照预想的呈现出了我们想要的结果且看着好像也没什么问题。但是呢这就违反了我们所说的一次性操作 DOM 的原则因为它在频繁的操作 DOM 一直在频繁操作中修改。因此我们可以通过以下方法来对性能做一个优化
/*** 频繁操作改为一次性操作*/
const list document.getElementById(list);// 创建一个文档片段此时还没有插入到 DOM 结构中
const frag document.createDocumentFragment();for(let i 0; i 15; i){const li document.createElement(li);li.innerHTML List item ${i};//先插入文档片段frag.appendChild(li);
}// 都完成之后再统一插入到 DOM 结构中
list.appendChild(frag);执行后浏览器也同样效果呈现出来了。 通过代码我们可以发现通过创建一个文档片段来对节点进行一个缓存等到全部节点操作都完成以后再统一插入到 DOM 结构中。这种方法也极大提高了程序中的性能。
5、回顾
最后我们用几个题目来回顾DOM的知识点。
1DOM是哪一种数据结构
DOM是一种树的数据结构DOM也常被称为DOM树。
2DOM操作的常用API 3attribute和property的区别
两者主要有以下区别
property修改对象属性不会体现到 html 结构中attribute修改 html 属性会改变 html 结构即标签结构两者都有可能引起DOM重新渲染但 attribute 引起 DOM 重新渲染的可能性更大因为它会改动 html 的结构。所以在实际开发中可以选择的话尽量渲染 property 去操作 DOM 。
4一次性插入多个DOM节点需考虑性能怎么操作
可以通过创建一个Fragment的文档片段来对节点进行一个缓存等到 全部节点操作 都完成以后再统一插入到 DOM 结构中从频繁执行改为一次执行。
二、BOM操作
BOM即Brouse Object Model浏览器对象模型。下面通过几个知识点来了解浏览器的BOM操作。
1、navigator
navigator 主要用到 userAgent 属性 navigator.userAgent 表示获取浏览器的用户代理字符串。如以下代码操作
//navigator
const ua navigator.userAgent;
console.log(ua);
const isChrome ua.indexOf(Chrome);
console.log(isChrome);此时浏览器打印如下。 从上图中可以看到通过 userAgent 可以获取到当前所使用浏览器的内核信息。
2、screen
screen 主要用到width和height属性screen.width表示获取当前屏幕的宽度sceen.height表示获取当前屏幕的高度。如以下代码操作
// screen
console.log(screen.width); //获取屏幕宽度
console.log(screen.height); //获取屏幕高度此时浏览器打印如下。 从上图中可以看到通过 screen.width 和 screen.height 可以获取到当前屏幕的宽度和高度。
3、location
location 主要用到 href/protocol/pathname/search/hash 属性具体含义如下代码所示。
// location
console.log(location.href); //获取整个网址
console.log(location.protocol); //获取网址协议
console.log(location.pathname); //获取网址域名
console.log(location.search); //获取网址中的一些参数
console.log(location.hash); //获取哈希值即#号后面的值此时浏览器打印如下。 相信从上图的演示之后大家对 location 属性的应用有了有一定的了解。
4、history
history 主要用到 back 和 forward 属性当网页执行history.back()代码时会将当前网页向后退一页当网页执行history.forward()代码时会将当前网页向前进一页。如以下代码操作
// history
history.back(); //对网页进行后退
history.forward(); //对网页进行前进此时浏览器打印如下。 从上图中可以看到通过 history.back() 和 history.forward() 可以让当前浏览页面进行前进或者后退操作。
结束语
JS 的基础知识规定了 ECMA 的语法标准而 Web API 则是网页操作的 API 是 W3C 的标准。如果要说两者的关系那自然是 ES 标准是 Web API 的基础。在实际应用开发中只有两者结合才能真正做到实际应用。所以不管是 ES 标准还是 Web API 中的 DOM 和 BOM 操作在实际开发中都是至关重要的内容。
关于 DOM 和 BOM 的操作就讲到这里啦如有疑问欢迎评论区评论或私信我交流~ 关注公众号 星期一研究室 不定期分享学习干货 如果这篇文章对你有用记得点个赞加个关注哦~