Day 10
DOM文档对象模型
之前经常用document.write,也可以看出这是一个文档对象。不过直接在控制台输出document的话,看到的是一个和element一样的HTML格式的内容,要想看到真正document对象的内容,要放到数组[document]来看。
document是最大的文档对象,HTML、head、body都是文档对象的内容
节点Node
构成HTML网页的最基本单元,每一个部分都可以是一个节点,例如HTML标签、属性甚至整个文档都是节点
但这些节点是不同类型的,常见的类型有:
- 文档节点(文档):整个 HTML 文档。整个 HTML 文档就是一个文档节点。
- 元素节点(标签):HTML标签。
- 属性节点(属性):元素的属性。
- 文本节点(文本):HTML标签中的文本内容(包括标签之间的空格、换行)。
不过一般找节点都是找文档节点和元素节点
DOM树
实际上就是Html结构(包含div之类的)
DOM的作用
- 找对象(元素节点)
- 设置/修改元素的属性值
- 设置/修改元素的样式
- 动态创建和删除元素
- 事件的触发响应:事件源、事件、事件的驱动程序
DOM找元素/节点的方法
总的来说,都是通过document对象的方法来获取的,以下是常用的三种方式
一、通过标签名称获取多个元素
//获取h1元素(可以获取多个
var h1s = document.getElementByTagName('h1')
console.log(h1s)
二、通过ID获取元素
//获取特定ID的元素(只能获取一个
var qwer = document.getElementById("qwer")
console.log(qwer)
三、通过class获取元素
//获取h1元素(可以获取多个
var classss = document.getElementByClassName('calssss')
console.log(classss)
四、document.querySelector一个方法找所有元素(最好用也最常用)
可以获取多个并不是什么好事,假如我只想要某标签或者某calss的某一个元素呢?可以像CSS那样单独选择吗,当然可以。
上面三种方法是ES5就能用的,ES6就有了更好的方法:
document.querySelector
<h1>helloworld1</h1>
<h1>helloworld2</h1>
<h1 id="abc">helloworld3</h1>
<h1 class="cba">helloworld4</h1>
<h1 class="cba">helloworld5</h1>
<div id="d1">
<h1 class="cc">helloworld6</h1>
</div>
<script type="text/javascript">
//完全是css选择器的方式,比如选择第4个子元素(详见后面一节)
var zzz = document.querySelector('.cba:nth-child(4)')
console.log(zzz);
console.log("————————————————————————");
//document.querySelector返回最先匹配到的第一个对象
var cba = document.querySelector('.cba') //如果有多个的话只返回第一个
console.log(cba)
var abc = document.querySelector("#abc") //和CSS选择器一样的获取id
console.log(abc)
var abc1 = document.getElementById("abc")
//通过document.querySelector和document.getElementById获取到的对象是同样的
console.log(abc===abc1)
var a6 = document.querySelector('#d1>.cc') //选择id下的class,也和CSS选择器一样
console.log(a6)
//只能返回第一个的话,要是就像要多个的话怎么办?用querySelectorAll
//document.querySelectorAll获取所有匹配到的元素对象
var cbas = document.querySelectorAll('.cba')
console.log(cbas)
//让所有cbas元素都设置背景色为skyblue
cbas.forEach(function(item,i,arr){
item.style.background = "skyblue"
})
</script>
DOM找父子关系节点
如何用document来找某元素的父元素或者子元素嗯
注意获取节点和获取元素的区别
<div class="d1">
helloworld1
<h3>child1</h3>
<h3>child2</h3>
<h3>child3</h3>
</div>
<div class="d2">helloworld2</div>
<div class="d3">helloworld3</div>
<script type="text/javascript">
var d1 = document.querySelector('.d1')
console.log([d1])
console.log("——————————————分割线————————————");
//获取父节点parentNode / parentElement(这两个方法都可以)
var hhh = d1.parentElement //d1的父节点就是body
console.log(hhh);
//获取子元素 children(元素)/childNodes(节点)
var first = d1.children[0]
//d1.firstElementChild,获取第一个元素
var last = d1.children[d1.children.length-1]
//d1.lastElementChild,获取最后1个元素
console.log(first)
console.log(last)
console.log("——————————再次的分割线————————");
//获取d1的子节点
var zzz = d1.childNodes
console.log(zzz); //可以在控制台看节点有哪些(共7个
//获取d1下的h3的第2个子元素
var child2 = document.querySelector('.d1 h3:nth-child(2)')
console.log([child2])
//获取兄弟元素的下一个元素,nextElementSibling
//获取兄弟元素的上一个元素,previousElementSibling
//一般都是找元素,如果找节点的话,很容易找到的是text
//以上都可以通过console控制台点开来看
</script>
DOM节点的操作
操作都是函数(方法),所以有括号,要传参数
创建/添加和删除节点
在某元素后面添加:添加子元素的父元素.appendChild(创建的元素)
在某元素之前添加:插入元素的父元素.insertBefore(img,d3)
删除某元素:要删除元素的父元素.removeChild(要删除的元素)
<div class="d1">hello1</div>
<div class="d2">hello2</div>
<div class="d3">hello3</div>
<div class="d4">hello4</div>
<div class="d5">hello5</div>
<script type="text/javascript">
//1创建元素
var h1 = document.createElement("h1") //这里的参数是标签名
console.log([h1])
console.log(typeof h1) //查看类型
//2设置元素的内容
h1.innerHTML = "中午吃啥?"
//3插入元素,首页要找到被插入的元素(要把创建的元素放在哪
var d1 = document.querySelector(".d1");
//4追加子元素(放在后面
d1.appendChild(h1)
//可以在什么前面插入元素吗(放在前面
//创建img元素
var img = document.createElement('img') //这里创建img标签
//设置img的src属性
img.src = "img/cxk.jpg"
console.log(img)
//找到被插入的父元素,<body>
var body = document.querySelector('body')
//在body的d3前插入内容.insertBefore
var d3 = document.querySelector('.d3')
body.insertBefore(img,d3) //第二个参数表示插入到哪个元素前面
//d3.parentElement.insertBefore(img,d3)
//如果想在d5的位置再插入一张图的话,用这个方法可行吗
//不可行,因为设置var d5 = document.querySelector('.d5')的话,内存地址就给到其他对象了,所以就只剩下一张图片了
//如果重新创建的话,又要再写属性?如果多张图的话岂不是得累死
//就可以用img.cloneNode()方法了
var img2 = img.cloneNode() //不带参数的话,只复制节点本身不复制子节点;带参数true则也复制子节点
//将图追加到d5
var d5 = document.querySelector('.d5')
d5.appendChild(img2)
//删除元素.removeChild,顾名思义,不仅要找到元素本身还要找到其父元素
//1找到被删除的父元素
var body = document.querySelector('body')
//2找到要删除的元素
var d2 = document.querySelector('.d2')
//3删除,父元素.removeChild(子元素)
body.removeChild(d2)
//可以发现,以上方法都要找父元素,都要多写一行,比较麻烦
//d2.parentElement.removeChild(d2),这样可以少写一个找到父元素的步骤1
</script>
获取和设置/修改以及删除元素的属性
<body>
<div id="d1">
helloworld
</div>
<img id="img1">
<script type="text/javascript">
var d1 = document.querySelector("#d1");
console.log([d1])
//获取属性值的三种方法
console.log(d1.id)
console.log(d1['id'])
console.log(d1.getAttribute('id'))
//设置属性值的三种方法(对应获取方法
d1.id = "d2"
d1['id'] = "d3"
//setAttribute("属性名称","属性值")
d1.setAttribute("id","d4") //需要两个参数
//以上一节的内容为例,修改img元素的src属性
var img = document.querySelector('#img1')
img.setAttribute("src","img/cxk.jpg")
//这两种方式有什么区别吗
//d1.abc = "789";//默认元素中如果不存在此属性,那么此属性只会创建在对象中,不会显示在元素的html上
//例如img的src是默认存在的属性
///默认元素中如果没有此属性,那么此属性不会创建在对象的属性中,会显示在html的属性中.
d1.setAttribute("abc","789") //html结构中是真的有abc的
console.log(d1)
console.log([d1])
//删除属性
d1.removeAttribute("abc")
</script>
</body>