DOM
- 什么是DOM?
- 认识DOM Tree
- DOM的整体结构
- 节点、元素导航
- 获取元素的方法
- 元素的属性(property)
- 元素属性操作
- 元素的classNamehe和classList
- 创建元素和插入元素
- 元素的大小、滚动
- window的大小、滚动
什么是DOM?
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言的标准编程接口。
可以将页面所有内容表示为可以修改的对象
浏览器会对我们编写的HTML、CSS进行渲染,同时它又要考虑我们可能会通过JavaScript来对其进行操作;
于是浏览器讲文明编写在HTML中的每个元素(Element)都抽象成了一个个对象
所有这些对都可以通过JavaScript来对其进行访问,那么我们就可以通过JavaScript来操作页面
所以,我们将这个抽象过程称之为文档对象模型(Document Object Model)
整个文档被抽象到document对象中:
document.documentElement对应的是html元素document.body对应的是body元素document.head对应的是head元素
操作DOM就是相当于操作文档
认识DOM Tree
DOM Tree的理解
一个页面不只是有html、head、body元素,也包括很多的子元素
在html结构中,最终会形成一个树结构
在抽象DOM对象的时候,它们也会形成一个树结构,我们称之为DOM Tree
DOM的整体结构
Document节点表示的整个载入的网页,它的实例是全局的document对象
对DOM的所有材质都是从document对象开始的
它是DOM的入口点,可以从document开始去访问如何节点元素
对于最顶层的html、head、body元素,我们可以直接在document对象中获取到
html元素: = document.documentElement
body元素: = document.body
head元素: = document.head
文档声明: = document.doctype
console.log(document.documentElement) console.log(document.body) console.log(document.head) console.log(document.doctype)
1
2
3
4
节点、元素导航
DOM将网页表示为一颗树,该树的节点类型有多种。
https://img2.baidu.com/it/u=3378651381,3616439034&fm=253&fmt=auto&app=138&f=PNG?w=646&h=396
元素节点——html标签
文本节点——文本
属性节点——属性总是被包含在标签里,所以属性节点总是被包含在元素节点当中。(元素节点(属性节点,文本节点))
通常可以通过开发者工具(如firebug)查看dom结构,但是要说明一点,开发者工具中的DOM并不完整,因为有些元素存在于DOM中,但是不会被开发者工具显示。比如回车会被当做一个文本节点。
nodeType节点类型
元素节点,nodeType为1
属性节点,nodeType为2
文本节点,nodeType为3
文档节点,nodeType为9
<body><pid="p">段落</p><scripttype="text/javascript">varelement=document.getElementById("p"); vartext=document.getElementById("p").firstChild; varproperty=document.getElementById("p").getAttributeNode("id"); console.log("元素节点nodeType返回值"+element.nodeType); console.log("文本节点nodeType返回值"+text.nodeType); console.log("属性节点nodeType返回值"+property.nodeType); console.log("文档节点nodeType返回值"+document.nodeType); </script></body>
nodeName节点的名字
对于元素节点,nodeName就是标签名。元素节点也可以通过tagName获取标签名
对于文本节点,nodeName永远是#text
对于属性节点,nodeName是属性名称
对于文档节点,nodeName永远是#document
注意:
nodeName是一个只读属性,不能进行设置。
nodeName所包含的XML元素的标签名称永远是大写的。
获取元素的方法
getElementById()获取属性id。
getElementsByTagName()使用指定标签名返回所有元素,这些元素是调用该方法的元素的后代。
getElementsByClassName()返回带有指定类名的所有元素的节点列表。
getElementsByName()根据元素的name属性返回所有元素的节点列表。
元素的属性(property)
<body><!--这里的属性叫做attribute--><divclass="box"id=""title=" "style="">helloworld</div><script>constobj= { // 这里的属性叫做propertyname:'why' } //在Javascript中对象的属性可以通过点的形式获取obj.name</script></body>
attribute属性分为自定义属性和原生属性(标准属性)
在Javascript中对象的属性可以通过点的形式获取
所以元素的属性attribute也可以通过点的形式获取,
但是前提是attribute必须是原生属性(标准属性),自定义获取的是undefined
<body><divid=""class="box"age="30">helloworld</div><script>constbox=document.querySelector('.box') // 原生的属性可以通过对象一样点的形式box.id='content'// 自定义属性attribute不能通过点的形式console.log(box.age) </script></body>
元素属性操作
elem.hasAttribute(“name”)属性是否存在
elem.getAttribute(“name”)获取属性
elem.setAttribute(“name”,“value”)设置属性
elem.removeAttribute(“name”)移除属性
<body><divclass="box">helloworld</div><script>constbox=document.querySelector('.box') console.log(box.hasAttribute('class')) console.log(box.getAttribute('class')) box.setAttribute('title','你好') box.removeAttribute("class") </script></body>
*HTML5自定义属性data- **
获取自定义属性dataset
<body><!--设置自定义属性--><divclass="box"data-i="1"></div><script>constbox=document.querySelector('.box') // 获取自定义属性console.log(box.dataset) console.log(box.dataset.i) </script></body>
元素的classNamehe和classList
元素的class attribute ,对应的property并非叫做class,而是className
这是因为JavaScript早期是不允许使用class这个关键字来作为对象的属性,所以DOM规范中使用了className
虽然现在JavaScript已经没有这样的限制了,但是并不推荐,并且依然在使用className这个名称
我们可以对className进行赋值,它会替换整个类中的字符串
let boxEl = document.querySelector(".box")
boxEl.className = 'box box1 box2'
1
2
如果我们需要添加或者移除单个的class,那么可以使用classList属性
elem.classList是一个特殊的对象:
elem.classList.add(class):添加一个类
elem.classList.remove(class):移除一个类
elem.classListtoggle(class):如果类不存在就添加,存在就移除
elem.claaList.contains(class):是否存在类,返回true/false
元素的style属性
如果需要单独修改某一个CSS属性,那么可以通过style来操作;
对于多个单词组成的属性,必须使用驼峰式camelCase
boxEl.style.width = '100px'
boxEl.style.height = '100px'
boxEl.style.backgroundColor = 'red'
1
2
3
如果我们将值设置为空空字符串,那么会使用CSS的默认样式
boxEl.style.display = " "
1
多个样式的写法,我们须要使用cssText属性:
boxEl.style.cssText = `
width:100px;
height:100px;
background-color:red;
`
元素style的读取-getComputedStyle
如果我们需要读取样式
我们可以通过getComputedStyle的全局函数来实现
console.log(getComputedStyle(box).width)
1
创建元素和插入元素
创建元素步骤:
步骤一:创建一个元素
步骤二:插入元素到DOM的某一个位置;
创建元素
语法:
document.createElement(tag) varboxEl=document.querySelector(".box") //创建一个h2元素varh2El=document.createElement("h2") //向创建好的元素插入内容h2El.innerHTML='我是标题'//将创建好的元素插入到页面中boxEl.append(h2El)
插入元素
方式如下:
node.append(…nodes or strings) 在node里面末尾插入节点或字符串
node.perpend(…nodes or strings) 在node里面开头插入节点或字符串
node.before(…nodes or strings) 在node外面的前面插入节点或字符串
node.after(…nodes or strings) 在node外面的后面插入节点或字符串
node.replaceWith(…nodes or strings) 将node替换为给定的节点或字符串
<body><divclass="box"></div><script>constbox=document.querySelector('.box') consth2Create=document.createElement('h2') h2Create.textContent='我是h2标题'// 将创建的h2插入到box里面的后面box.append(h2Create) consth4El=document.createElement('h4') h4El.textContent='我是h4标题'h4El.className='title'// 将创建的h4插入到box里面的前面box.prepend(h4El) constp=document.createElement('p') p.textContent='你好世界'// 将创建的p元素插入到box外面的前面box.before(p) constdiv=document.createElement('div') div.textContent='helloworld'// 将创建的div元素插入到box外面的后面box.after(div) </script></body>
移除和克隆元素
移除元素我们可以调用元素本身的remove方法
<body><buttonclass="btn">移除box</button><divclass="box"><span>我是span</span></div><script>constbox=document.querySelector('.box') constbtns=document.querySelector('.btn') btns.addEventListener('click',() =>{ box.remove() }) </script></body>
克隆我们想要复制一个现有的元素,可以通过cloneNode方法:
可以传入一个Blooean类型的值,来决定是否是深度克隆;
深度克隆会对克隆元素的子元素也克隆,否则不会
<body><buttonclass="cloneBtn">复制</button><divclass="box"><span>我是span</span></div><script>constbox=document.querySelector('.box') constcloneBtn=document.querySelector('.cloneBtn') cloneBtn.onclick=function () { //克隆出来constcloneEl=box.cloneNode(true) // 插入到页面中box.after(cloneEl) } </script></body>
旧的元素操作方法
parentElem.appendChild(node):
在parentElem的父元素最后面位置添加一个子元素
parentElem.insertBefore(node,nextSibling);
在parentElem的nextSibling前面插入一个子元素
parentElem.replaceChild(node,oldchild)
在parentElem中,新元素替换之前的oldChild元素
parentElem.removeChild(node)
在parentElem中,移除一个元素
元素的大小、滚动
clientWidth:内容 + padding(不包含滚动条)
clientHeight:内容 + padding(不包含滚动条)
clientTop:border-top的宽度
clientLeft:border-left的宽度
offsetWidth:元素的完整宽度
offsetHeight:元素的完整高度
offsetLeft:距离父元素的x
offsetHeight:距离父元素的y
scrollHeight:整个可滚动的区域高度
scrollTop:滚动部分的高度
window的大小、滚动
window的width和height
innerWidth、innerHeight:获取window窗口的宽度和高度(包含滚动条)
outerWidth、outerHeight:获取window窗口的整个宽度和高度(包括调试工具、工具栏)
documentElement.clientHeight、documeElement.clientWidth:获取html的宽度和高度(不包含滚动条)
window的滚动位置:
scrollX:x轴的滚动位置(别名pageXOffset)
scrollY:Y轴滚动位置(别名pageYOffset)
也有提供对应的滚动方法:
方法scrollBy(x,y):将页面滚动至相对于当前位置的(x,y)位置
方法scrollTo(pageX,pageY)将页面滚动至绝对坐标