页面只不过是颗树,JS怎样操作方式这棵树?
JS操作方式没法。让应用程序往window上有两个document。
JS用document操作方式页面
“用document第一类操作方式整座页面”此种价值观就叫作文件格式第一类数学模型(Document Object Model)
读懂两个历史事实:DOM极难用
下科白他们会想配套措施化解那个痛点(PCB)。
假如你真的DOM天真,千万别揣测他们,你真的是对的。
DOM的USB结构设计的十分反人类文明,引致后端开发人员不得不采用jQuery去操作方式DOM。而后Vue、ReactEngilbert。他们坎氏Vue或React来替代操作方式DOM。
他们从不会用DOM便携式的机能操作方式DOM,即使毕竟是反人类文明。
但他们却是ThoubalDOM,要不然看不懂 交互式DOM 和 jQuery。
其他
1.斜线表达式不全力支持this,有斜线表达式就无法有this!
2.在html里,无论有啥字符单厢拉出两个字符。
3.JS里头的特性泛称为properties,HTML里头的特性泛称为attributes。
DOM提供更多的大部份表达式(API)
有许多API
1.window.id或是间接id //最慢
2.document.getElementById(id)
3.document.getElementsByTagName(div)[0] //找到大部份标签名为div的第1个元素
4.document.getElementsByClassName(red)[0] //找到大部份class名为red的第1个元素
5.document.querySelector(#id)
6.document.querySelectorAll(#id)[0]
用哪两个
1.工作中用querySelector和querySelectorAll
2.做demo间接用id
3.要兼容IE的才用getElement(s)ByXXX
代码:window.onclick=()=>{console.
变态
document.all是IE发明的奇葩,第6个falsy值。
document.all以前用来区分是否是IE(现在document.all默认为假)
都是第一类。
只需要搞清第一类自身有哪些特性,以及它的原型有哪些即可。
div 原型链
元素的 自身特性 和 6层原型链js的大部份第一类都有个隐藏特性,那个隐藏特性指向了第一类的原型。
div.__proto__===HTMLDivElement.prototype
节点Node?元素Element?怎么区分?
节点分为标签和文字
节点包括下面几种不同的节点:
x.nodeType得到两个数字
1表示元素Element,也叫标签Tag
3表示文本Text
8表示注释Comment
9表示文件格式Document
例子
由于div是由HTMLDivElement那个表达式构造出来的,所以那个构造表达式往this(div)上添加了hidden特性、…
也继承了Element,Element给this加了id、…
也是Node构造的,Node给this加了childNodes/firstChild…
每一层构造表达式单厢给this上有特性
节点的增删改查
一.增
创建两个标签节点
let div1=document.createElement(div)
document.createElement(style)
document.createElement(script)
document.createElement(li)
创建两个文本节点
let text1=document.createTextNode(你好)
标签里头插入文本
1 div1.appendChild(text1)
2 推荐
let div1=document.createElement(div)
div1.innerText=你好 或是 div1.textContent=你好
但无法用div1.appendChild(你好)
不同的原型提供更多了不同的表达式,但无法混着用!
插入页面中
这时只会创建到内存不会显示到页面
你创建的标签默认处于JS线程中,必须把它插到head(`<style>或<link>`)或是body里头才会生效。
document.body.appendChild(div1)或是 已在页面中的元素.appendChild(div1)
appendChild
代码
页面中有 div#test1 和 div#test2
let div=document.createElement(div)
test1.appendChild(div)
test2.appendChild(div)
请问最终div出现在哪里?
test2里头。即使两个元素无法出现在两个地方,除非复制一份。
二.删
1 parentNode.removeChild(childNode)
2 childNode.remove() 注意:不全力支持ie
例子
怎样彻底删除节点?
div2.remove()
div2=null
三.改
1.改特性
(1)写标准特性
1 改class:div1.className=red 会覆盖之前的,id=”div1″
2 改class:div1.classList.add(green)
改style:div1.style=width:200px;color:blue; 会覆盖之前的
改style的一部分:div1.style.width=200px
大小写:div1.style.backgroundColor=white //大部份用-隔开的,用大写替代
改data-* 特性:div1.dataset.x=fuck 添加自定义特性
e(data-x)或是div1.dataset.x
例
(2)读标准特性
查看样式、id、class:div1.style/id/className
1 div2.classList/a.href
2 div2.getAttribute(class)/a.getAttribute(href)
2种方法都行,读样式、id、class时都一样,只是在读链接时值有点不同:
用href时,有可能应用程序会自动加一些东西。
例子
(3)改on开头的特性(改事件处理表达式)
div1.onclick默认为null
默认点击div不会有任何事发生
但假如你把div1.onclick改成两个表达式fn,那么点击div时应用程序就会调用那个表达式。
而且是这样调用的fn.call(this,event)event是第1个参数
div1会被当作this,event则包含了点击事件的大部份信息,如坐标
假如需要this,就无法用斜线表达式,用function才能得到this。即使斜线表达式不全力支持this。
div1.addEventListener是升级版的div1.onclick,后面会说
点击后,this 和 x 是应用程序用call传进来的
(4)改内容 //id=”div1″
改文本内容
div1.innerText=xxx或是 div1.textContent=xxx
改html内容
div1.innerHTML=`<p> <strong>重要</strong> </p>`
字符限制在2万以内超出应用程序会卡死
改标签
div1.innerHTML=
div1.appendChild(div2)
先清空再加内容
(5)改爸爸
newParent.appendChild(div1)
查
查爸爸
node.parentNode或是node.parentElement
查爷爷
node.parentNode.parentNode
例子
查子代
2 node.children
当子代变化时,两者也会实时变化吗?
单厢实时变化。querySelectorAll不会实时更新
let c=document.querySelectorAll(li)
console.log(test.children.length) //2
查兄弟姐妹
1 node.parentNode.childNodes //需要排除他们以及大部份的文本节点,更麻烦
2 node.parentNode.children //需要排除他们
查看老大
node.firstChild
查看老幺
node.lastChild
查看上两个哥哥/姐姐
node.previousSibling
查看下两个弟弟/妹妹
node.nextSibling //包含文本节点
可以避开文本节点node.previousElementSibling
例子
遍历两个div里头的所有元素
DOM 操作方式跨线程(高级知识)
应用程序机能划分:应用程序分为渲染引擎和JS引擎
跨线程操作方式
各线程各司其职
js引擎无法操作方式页面,只能操作方式js
渲染引擎无法操作方式js,只能操作方式页面
document.body.appendChild(div1)
这句js是怎样改变页面的?
跨线程通信
当应用程序发现js在body里头加了个”div1″第一类
应用程序就会通知渲染引擎在页面里也新增两个div元素
新增的div1元素大部份特性都照抄div1第一类
时间浪费在应用程序。应用程序发现后去通知线程,那个是要时间的。所以操作方式会比其他操作方式慢。
为什么要分两个线程?
让每一块都变的简单,好优化。
变得慢可以优化其他的点,比如可以单独给渲染做优化。
插入新标签的完整过程
在div1放入页面之前,你对div1大部份的操作方式都属于js线程内的操作方式。
把div1放入页面之时,应用程序会发现JS的意图,就会通知渲染线程在页面中渲染div1对应的元素。
把div1放入页面之后,你对div1的操作方式都有可能会触发重新渲染
div1.id=newId可能会重新渲染,也可能不会
div1.title=new可能会重新渲染,也可能不会
例子
假如连续对div1多次操作方式,浏览器可能会合并成一次操作方式,也可能不会
特性同步
标准特性
对div1的标准特性的修改,会被应用程序同步到页面中
比如id、className、title
data-*特性
会同步
非标准特性
对非标准特性的修改,则只会停留在js线程中,不会同步
假如你有自定义特性想被同步,可以采用data-作为前缀
property vs attribute
JS特性泛称为properties,HTML特性泛称为attributes。property特性
js线程中div1的大部份特性,叫作div1的property
attribute也是特性
渲染引擎中div1对应标签的特性,叫作attribute
区别
大部份时候,同名的property和attribute值相等
但假如不是标准特性,那么它俩只会在一开始时相等
但注意attribute只全力支持字符串
property全力支持字符串、布尔等类型
面试题
为什么DOM操作方式比较慢?
时间浪费在应用程序。应用程序发现后去通知线程,那个是要时间的。所以操作方式会比其他操作方式都慢。