DOM编程

简介: DOM编程

热身

获取元素,也叫标签

window,idxxx或者之际idxxx
document.getElementById('idxxx')
document.getElementsByTagName('div')[0]
document.getElementsByClassName('red')[0]
document.querySelector('#idxxx')
document.querySelectorAll('.red')[0]

用哪个??

工作中用querySelector 和 querySelectorAll

做demo直接用idxxx,千完别让人发现

要兼容IE的可怜虫才用getElement(s)ByXXX

获取特定元素

获取html元素
document.documentElement
获取head元素
document.head
获取body元素
document.body
获取窗口 -(窗口不是元素)
window
获取所有元素
document.all
这个doument.all是个奇葩,第6个Falsy值

获取到的元素是个啥

先然是一个对象,我们需要高清它的原型

抓一只div对象过来看看

  • console.dir(div1)看原型链
  • 告诉你一个秘密,Chorme显示错了
  • 自身属性:className、id、style等等
  • 第一层原型HTMLDivElement.prototype
  • 这里面是所有div共有的属性,不用细看
  • 第二层原型HTMLElementprototype
  • 这里面是所有HTML标签共有的属性,不用细看
  • 第三层原型Element.prototype
  • 这里面是所有XML、HTML标签的共有属性,你不会以为浏览器只能展示HTML吧
  • 第四层原型Node.protoype
  • 这里面是所有节点共有的属性,节点包括XML标签文本注释、HTML标签文本注释等等
  • 第五层原型EventTarget.protoype
  • 里面最重要的函数属性是addEventListener
  • 最后一层原型就是Object.prototype

节点?元素?傻傻分不清楚

节点Node包括以下几种

x.nodeType得到一个数组

1表示元素Element,也叫标签Tag

3表示文本Text

8表示注释Comment

9表示文档Document

11表示文档片段DocumentFragment

记住1和2就行了

创建一个标签节点

let div1 =document.createElement('div')
document.createElement('style')
document.createElement('script')
document.createElement('li')

创建一个文本节点

text1 = document.createTextNode('你好')

标签里面插入文本

div1.appendChild(text1)
div1.innerText = '你好' 
或者
div1.textContent='你好'
但是不能用!!
div1.appendChild('你好')

插入页面中

你创建的标签默认处于JS线程中

你必须把它查到head或者body里面,它才会生效

document.body.appenChild(div)
//或者
已在页面中的元素.appendChild(div)

appendChild

页面中有div#test1和div#test2
let div =document.createElement('div')
test1.appendChild(div)
tast2.appendCHild(div)
它会只出现在!!!
test2里面!!!
一个元素不能出现再两个地方
除非复制一份
怎么复制?
let div2 = div1.cloneNode(true)
后面的true代表深拷贝,节点子孙后代全都拷贝

两种方法

旧方法:

parentNode.removeChild(childNode)

新方法:

childNode.remove()

思考:

如果一个node被移出页面,(DOM树)

那么它还可以再次回到页面中吗

可以的,他只是从树里面删掉了,还再内存里

document.body.appendChild(div2)

写标准属性

改class:div.className = 'red blue' (全覆盖)
改class:div.classList.add('red')
改style:div.style = 'width:100px;color:blue;'
改style的一部分:div.style.width = '200px'
大小写:div.style.backgroundColor = 'white'
改data-* 属性: div.dataset.x = 'frank'

读标准属性

div.classList / a.href
div.getAttribute('class')  <-好用点 / a.getAttribute('href')
两种方法都可以,但值可能稍微有些不同

该事件处理函数

div.onclick默认为null

默认点击div不会有任何事情发生

但是如果你把div.onclick改为一个函数fn

那么点击div的时候,浏览器就会调用这个函数

并且是这样调用的

fn.call(div,event)

div会被当作this

event则包含了点击事件的所有信息,如坐标

div.addEventListener

是div.onclick的升级版,之后再说

改内容

改文本

div.innerText = 'xxx'
div.textContent = 'xxx'
两者几乎没有区别

改HTML内容

div.innerHTML = '<strong>重要内容</strong>'

改标签

div.innerHTML = '' //先清空
ddiv.appendChild(div2) //再加内容

改爸爸

想要找一个新爸爸?
newParent.appendChild(div)
直接这样就可以了,直接从原来的地方消失

查爸爸
node.parentNode 或者node.parentElement
查爷爷
node.parentNode.parentNode
查子代
node.childNodes或者node.children
思考:当子代变化时,两者也会实时变化吗?
会实时变化length
用querySelectorAll查找到获取
之后再把其中一个删除了,上面获取的也不会发生改变
查兄弟姐妹
node.parentNode.childNodes  不能算自己
node.parentNOde.children 推荐 不能算自己
查看老大
node.firstChild
查看老幺
node.lastChild
查看上一个哥哥/姐姐
node.previousSibling
查看下一个弟弟/妹妹
node.nextSibling
遍历一个div里面的所有元素
travel = (node,fn) => {
  fn(node)
  if(node.children){
    for(let i = 0; i< node.children.length;i++){
      travel(node.children[i],fn)
    }
  }
}
travel(div,(node) => console.log(node))

DOM操作是跨线程的

浏览器分为渲染引擎JS引擎

各线程各司其职

Js引擎不能操作页面,只能操作JS

渲染引擎不能操作JS,只能操作页面

document.body.appenChild(div1)

这句JS是如何改变页面的?

跨线程通信

当浏览器发现JS在body里面加了个div1对象

浏览器就会通知渲染引擎在页面里也新增一个div元素

新增的div元素所有属性都照抄div1对象

插入新标签的完整过程

在div1放入页面之前

你对duiv1所有的操作都属于JS线程内操作

在div1放入页面之时

浏览器会发现JS的意图

就会通知渲染线程在页面中渲染div1对应的元素

把div1放入页面之后

你对div1的操作都有可能会触发重新渲染

div1.id='newxsad' 可能会重新渲染,也可能不会,例如修改的里面有css啥的,还是要重新渲染

div1.title = 'asda' 可能会重发渲染,也可能不会,例如div1::hover 里面改内容,里面还是要改内容,还是要重新渲染

如果你连续对div1多次操作,浏览器可能会合并成一次操作,也可能不会

属性同步

标准属性

对div1的标准属性的更改,会被浏览器同步到页面中

比如id className title等

data- * 属性

同上

非标准属性

对非标准属性的更改,只会停留在JS线程中

不会同步到页面里

气势

如果你有自定义属性,又想被同步到页面中,请使用data- 作为前缀

Property vs  Attribute

property属性

Js线程中div1的所有属性,叫做div1的property

attribute也是属性

渲染引擎中div1对应标签的属性,叫做attribute

区别

大部分时候,同名的property和attribute值相等

但如果不是标准属性,那么它俩只会在一开始相等

但注意arribute只支持字符串

而property支持字符串、布尔等类型



目录
相关文章
N..
|
7月前
|
JavaScript 前端开发 UED
DOM编程中的form对象
DOM编程中的form对象
N..
44 0
N..
|
7月前
|
XML JavaScript 数据格式
DOM编程中的Document对象
DOM编程中的Document对象
N..
75 0
|
JavaScript 前端开发
DOM编程进阶(JS)
本篇是DOM编程基础(JS)的进阶版
|
XML 移动开发 JavaScript
DOM编程基础
DOM编程基础
75 0
|
JavaScript
DOM编程2-重要案例!!!
DOM编程2-重要案例!!!
|
JavaScript 前端开发 API
DOM编程:Document Object Model
DOM编程:Document Object Model
|
存储 JavaScript 前端开发
JavaScript函数和BOM及DOM编程(详细总结-无尿点)(一)
JavaScript函数和BOM及DOM编程(详细总结-无尿点)(一)
74 0
|
XML JavaScript 前端开发
JavaScript函数和BOM及DOM编程(详细总结-无尿点)(二)
JavaScript函数和BOM及DOM编程(详细总结-无尿点)(二)
48 0
|
7月前
|
XML JavaScript 前端开发
属性和方法向 XML DOM 定义了编程接口
XML DOM 提供编程接口,通过属性和方法操作XML结构。使用JavaScript等语言,可访问和修改节点。属性如nodeName、nodeValue揭示节点信息,方法如getElementsByTagName、appendChild、removeChild实现查找、添加和删除节点功能。节点对象x的应用示例贯穿其中。
|
6月前
|
XML JavaScript 前端开发
属性和方法向 XML DOM 定义了编程接口
XML DOM 是一个编程接口,它将XML表示为节点对象集合,可通过JavaScript等语言访问。接口通过属性和方法定义,属性如nodeName、nodeValue显示节点信息,方法如getElementsByTagName、appendChild、removeChild执行操作。例如,x.nodeName返回节点名称,x.appendChild(node)添加子节点。