【学习前端第三十一课】DOM基础

DOM基础

Document Object Model,文档对象模型,主要目的就是把网页里面的元素当成对象一样来操作

DOM技术的本质操作我们的HTML元素进行各种格样的操作

DOM技术里面分两个部分,一个是JavaScript与html的结合,一个是JavaScript与css的结合

在学习之前,我们先简单了说明一下

1、document是文档的意思,因为文档指向的是当前网页,所以DOM在操作里面的整个页面的时候就会形成一个document的对象

2、页面上面所有的元素,最终会被转换成JavaScript里面的对象(所以我们操作标签对象就可以像操作之前我们学过的对象一样)

3、如果是非IE浏览器,它会根据每个ID生成一个对象,方便我们直接获取

通过JavaScript获取页面元素

首先再强调一遍,当前的页面指向的是document整个对象

1、通过ID来获取元素

document.getElementById("元素id属性值");

通过这种方式获取,永远只能获取到1个或0个(null)元素,不具备数据特性,如果找不到就返回null

2、通过class来获取元素

document.getElementsByClassName("类名");

通过这种方式,获取到一个叫做 HTMLCollection 的集合(类数组),具备数组特性,但是不具备数组方法,这个集合里面存放的都是DOM对象,如果一个都没获取到,返回一个空数组

3、通过标签名来获取

document.getELementsByTagName("标签名");

通过这种方式,获取到一个叫做 HTMLCollection 的集合(类数组),具备数组特性,但是不具备数组方法,这个集合里面存放的都是DOM对象,如果一个都没获取到,返回一个空数组

4、通过name属性来获取

document.getElementsByName("name属性值");

通过这种方式获取的是一个叫做 NodeList 集合,它也是一个类数组,具备数组特性但不具备数组方法,这个集合里面也存放的DOM对象,如果一个都获取不到返回空数组

上面4种方式是我们最基础的4种获取元素的方式,这种方法兼容性比较好,可以在绝大数浏览器种使用

如果页面的结构比较复杂的情况,我们要怎么获取

<div id="div1">
    <div class="div2">
        我爱北京天安门
    </div>		
    <div class="div2">
        天安门上太阳升
    </div>
    <div class="div3">
        哈哈哈哈哈
    </div>
</div>
<div class="div2">我是第二个盒子</div>
<div class="div2">我是第二个盒子的副本</div>
<p>我是一个段落标签</p>
<input type="radio" name="sex"><input type="radio" name="sex">

在上面的网页结构种,如果我们想获取到id="div1"里面的class="div2"的元素怎么办?

//第一步,先获取div1这个元素
var div1 = document.getElementById("div1");
//第二步,在div1当中取div2元素,我们之前都在document当中去找,现在是在div1去找
var div2 = div1.getElementsByClassName("div2");

这是我们很早以前的解决方案,现在我们已经可以不使用这种方式,转而另寻新欢(强烈推荐)

新的方法主要是结合了HTML5和CSS3的东西,我们把CSS3当中9大选择器与之前的JavaScript做了结合

1、通过 querySelector() 来获取元素

document.querySelector("#div1");   //获取id为div1的元素
document.querySelector(".div2");   //获取类名为div2的元素

这种方法是通过选择器来选择元素,如果找到了元素就返回1个元素,找不到返回null,即使找到多个元素,也只返回1个元素

2、通过 querySelectorAll() 来获取元素s

document.querySelectorAll(".div2");   //找到所有类名为div2的元素,返回一个集合
document.querySelectorAll("#div1>.div2");  //返回id名为div1下一级的所有类名为div2的元素

这种方法也是通过指定的选择器来获取元素,它返回的是一个NodeList的类数组,里面包含了要查找的元素,如果找不到返回一个空数组

总结: getElementById与querySelector都是返回1个或者null,找到就只返回1个,找不到返回null

querySelectorAll和后面getElementsBy *** 都是返回一个集合

DOM的结构

DOM本身也是一个对象,我们以前也叫过对象都有自己的属性和方法

我们来分析一下DOM对象

标签名第一级第二级第三级第四级第五级
divHTMLDivElementHTMLElementElementNodeEventTarget
pHTMLParagraphElementHTMLElementElementNodeEventTarget

通过上面的两种标签对象的对比分析,我们可以看到所有的元素最终都继承自Node对象(EventTarget对象暂时先不管),我们可以把Node当成所有页面元素对象的父级,这个时候如果我们弄清除了Node对象,我们其实也就搞清除上面的元素对象

Element与Node区别
<div id="div1">
	 我在前面插入了一段文字
	 <div class="div2">第一行</div>
	 <div class="div2">第二行</div>
	 <!-- 我是一个注释 -->
</div>

1、网页当中的所有标签都可以是一个元素(element),同时也可以是一个节点node

2、但并不是所有的节点Node都是一个元素Element(节点是包含了元素,文字,注释,回车)

在上面的网页结构种,div1里面的所有就仅仅只有div2这两个,但是它的节点就很多了

Element常用属性

Element指的是页面上面的标签所形成的元素,我们学习属性和方法就是为了去操作HTML元素的

1、children属性,获取当前元素下面的子元素,它会返回一个HTMLCollection的集合

到目前为止,我们有三种可以获得子元素的方式

//第一种方式
var ul1 = document.getElementById("ul1");
var li1 =ul1.getElementsByTagName("li");

//第二种方式
var lis =document.querySelectorAll("#ul1>li");

//第三种方式
var ul1 = document.querySelector("#ul1");
ul1.children;

上面三种方式,各自有各自的好处不好一概而论,前面两种都有一个问题就是不能找到父级,只能找同级或者子级

,而第三种方式,为我们提供了一个思路,既然能children这个属性,那么是否可以有其他的属性去找全家,第三种在JavaScript中提供了一整套获取元素的体系

2、parentElement ,获取当前元素的父级元素

3、nextElementSibling ,获取当前元素的下一个兄弟元素

4、previousElementSibling 获取当前元素的上一个兄弟元素

前面4个属性就是以当前元素为中心去获取父级,子级,前一个,后一个元素

5、className 属性,获取或设置当前元素的class属性(类名)

<div id="div1">
    <div class="div2">
        我爱北京天安门
    </div>		
    <div class="div2">
        天安门上太阳升
    </div>
    <div class="div3">
        哈哈哈哈哈
    </div>
</div>
<div class="div2">我是第二个盒子</div>
<div class="div2">我是第二个盒子的副本</div>
<p>我是一个段落标签</p>
<input type="radio" name="sex"><input type="radio" name="sex"><script type="text/javascript">
    var div1 = document.querySelector("#div1");
    div1.children[0].className = "box";
</script>

通过上面的例子我们现在就已经可以操作元素的样式了,但是工作中实际中我们不这么干,因为会有问题

6、classList 属性 ,返回当前元素的class类名的集合,它返回的是一个叫做DOMTokenList对象(类数组),

这个集合里面包含了所有的class类名

  • add() 方法,在当前元素的classList里面添加一个class

  • div1.classList.add("p3");
    
  • remove() 方法,跟当前的classList里面删除一个class

  • div1.classList.remove("p1");
    
  • toggle() 方法,如果classList当前有这个类名就删除,如果过没有就添加

  • div1.classList.toggle("p1");
    
  • contains() 方法,判断当前的classList中是否有这个类名,如果有则返回true,没有返回false

7、firstElementChild 属性,获取当前元素下的第一个子元素,相当于 children[0]

8、lastElementChild 属性,获取当前元素下的最后一个子元素

9、innerText 属性,获取或设置当前元素的文本内容,如果赋值的时候是HTML标签,那么依然会以文本的形式进行赋值,不会进行html转义

<div class="box">我是一个盒子</div>
<script type="text/javascript">
    var box = document.querySelector(".box");
    box.innerText = "<h1>我是爸爸</h1>";  //h1标签会被直接输出到页面内容上面
</script>

10、innerHTML 属性,获取或设置当前元素的HTML内容 ,如果过赋值的时候是HTML你标签,那么会对标签的部分进行转义

<div class="box">我是一个盒子</div>
<script type="text/javascript">
    var box = document.querySelector(".box");
    box.innerHTML = "<h1>我是爸爸</h1>";  //h1标签会被当前标签渲染出来
</script>

11、tagName 属性,返回当前元素的标签名(返回的是大写标签名)

12、value 属性,它是表单标签才会有的属性,可以对这个属性取值赋值

13、childElementCount 获取当前元素子元素的个数

Element常用方法

1、createElement() 方法,根据标签名创建一个标签元素

var div1 = document.createElement("div");
var p1 = document.createElement("p");

2、appendChild() 方法,向当前元素里面的最后去追加一个新的元素

div1.appendChild(p1);  //将p1追加到div1标签的内部的最后
document.body.appendChild(div1);  //再将div1追加到网页的body标签里面

3、remove() 方法,删除当前的元素(里面的子元素也会一并被删除)

4、removeChild() 方法,删除指定的子元素,返回这个删除的子元素

ul1.children[1].remove();
ul1.removeChild(ul1.children[1]);

5、cloneNode() 克隆一个相同的元素出来,它接收一个参数,是布尔类型,默认是false,如果传一个true,则代表要克隆子元素

var ul2 = ul1.cloneNode();   //只克隆当前元素
var ul3 = ul1.cloneNode(true);  //克隆当前的元素和所有的子元素

6、insertAdjacentElement() 方法,在指定位置插入元素

var ul3 = ul1.cloneNode(true);			ul1.insertAdjacentElement("beforeEnd",ul3);
参数值解释
beforeBegin开始标签之前
afterBegin开始标签之后
beforeEnd结束标签之前
afterEnd结束标签之后

除了有 insertAdjacentElement 方法插入元素以外,还有其他与它类似的方法

insertAdjacentHTML() 插入网页标签

insertAdjacentText() 插入文本

var p1 = "<p>我是一个p标签</p>";
ul1.insertAdjacentHTML("beforeBegin",p1);   //与innerHTML类似
ul1.insertAdjacentText("beforeBegin",p1);   //与innerText类似

HTMLCollection与NodeList的区别

我们之前讲过元素的获取,我们通过 document.getElementsByTagName 获取到是元素的一个 HTMLCollection 的集合,而通过 document.getElementsByName/document.querySelectorAll 获取的集合是一个 NodeList的集合,那么这两种集合有什么区别?

<ul class="ul1">
	<li>1</li>
	<li>2</li>
	<li>3</li>
	<li>4</li>
	<li>5</li>
	<li>6</li>
</ul>
<script>
// 要求删除掉ul1内部的所有li元素
</script>

现在有上面的代码,我们如果要删除这里ul1内部所有的li,首先就应该先获取到里面的所有li,然后去调用 remove() 方法去删除

第一种方式获取li

var ul1 = document.querySelector(".ul1");
var list1 = ul1.children;   //这个时候list1就是一个HTMLCollection集合
for(var i = 0;i < list1.length ;i++){
	list1[i].remove();
}

这个时候我们会还想,并没有完全删掉里面的li,因为它是一个动态的集合,它的索引会发现变化,长度也会发生变化,这种现象我们叫沙漏效应,对应这种情况,我们可以采取倒序的方式去删除

for(var i = list1.length - 1; i >= 0; i--){
	list1[i].remove();
}

第二种方式获取li

var ul1 = document.querySelectorAll(".ul1>li");   //这个时候ul1就是一个NodeList集合
for(var i = 0;i < ul1.length ;i++){
	ul1[i].remove();
}

这个时候我们就发现li都被删除完了,说明 NodeList 并没有形成一个沙漏效应

HTMLCollection 是一个动态集合,而 NodeList 是一个静态集合

通过上面的演示元素的删除,其实就可以看作是HTMLCollection与NodeList的区别,包括在添加的时候也是一样的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值