一、基本知识
1.1 API和Web API
API(Application Programming Interface,应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码或理解内部工作机制的细节。
简单理解:API是给程序员提供的一种工具,以便能更轻松的实现想要完成的功能。
Web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM),主要针对于浏览器做交互效果。Web API一般都有输入和输出(函数的传参和返回值),Web API很多都是方法(函数)。
1.2 DOM和DOM树
文档对象模型(Documet Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式。
DOM树
- 文档:一个页面就是一个文档,DOM中使用document表示
- 元素:页面中的所有标签都是元素,DOM中使用element表示
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
DOM把以上元素都看作是对象,在开发中主要是用来操作元素。
二、获取元素
获取页面中元素的方式
- 根据ID获取
- 根据标签名获取
- 通过HTML5新增的方法获取
- 特殊元素获取(body, html)
2.1 根据ID获取
使用getElementById()方法可以获取带有ID的元素对象
参数id是大小写敏感的字符串
返回的是一个元素对象
// 用法
document.getElementsByTagName('标签名');
// 假设HTML中已经有了 id 为 time的div
let time = document.getElementById('time');
console.log(time); // 输出结果:<div id="time"></div>
2.2 根据标签名获取
使用getElementByTagName()方法可以返回带有指定标签名的对象的集合
// 假设HTML中已经有了两个div
let divs = document.getElementsByTagName('div');
console.log(divs); // 输出结果如图所示
我们可以看到,得到的是一个对象(动态的)的集合,所以要想操作里面的元素就需要遍历。
// 可以通过一个for循环对此遍历
for (let i = 0; i < divs.length; i++) {
console.log(divs[i]);
}
输出结果:
还可以获取某个元素(父元素)内部所有指定标签名的子元素
// 部分HTML代码
<ul id="ul">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
// 用法: element.getElementsByTagName('标签名');
// 案例代码
let ul = document.getElementById('ul')
let lis = ul.getElementsByTagName('li')
for (let i = 0; i < lis.length; i++) {
console.log(lis[i])
}
输出结果:
注意:父元素必须是单个对象(必须指明是哪一个元素对象,不能用比如getElementsByTagName这样的Element带复数的方法获取,因为返回的是一个伪数组,不是单个对象),获取的结果不包括父元素自己。
2.3 通过HTML5新增的方法获取
既然是HTML5的用法,那么在使用这些方法时要注意浏览器兼容性问题。
document.getElementsByClassName('类名') ; // 根据类名返回元素对象集合
document.querySelector('选择器'); // 根据指定选择器返回第一个元素对象
document.querySelectorAll('选择器'); // 根据指定选择器返回
以下是各个用法的案例代码与输出结果:
// 根据类名返回元素对象集合
let ul = document.getElementsByClassName('ul');
console.log(ul);
输出结果:
// 根据指定选择器返回第一个元素对象
// 使用注意:获取类名的元素用.类名,获取id的元素用#id名,获取标签直接用标签名
// 以下以类名为例
let ul = document.querySelector('.ul');
console.log(ul)
输出结果:
// 根据指定选择器返回
let lis = document.querySelectorAll('li');
console.log(lis)
输出结果:
2.4 获取特殊元素(body, html)
获取body元素
document.body // 返回body元素对象
let body = document.body;
console.log(body);
输出结果:
获取html元素
document.documentElement // 返回html元素对象
let html = document.documentElement;
console.log(html);
输出结果:
三、对元素节点的操作
原HTML结构:
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
页面效果:
3.1 创建节点
let li = document.createElement('li')
3.2 添加节点
let ul = document。querySelector('ul')
// 第一种方式
// node.appendChild(child)方法将一个节点添加到指定父节点的子节点列表【末尾】,类似于css里面的after伪元素
let li1 = document.createElement('li')
li1.innerHTML = 'end'
ul.appendChild(li1)
// 第二种方式
// node.insertBefore(child, 指定元素)方法将一个节点添加到指定父节点的子节点【前面】 类似于css里面的before伪元素
let li2 = document.createElement('li')
li2.innerHTML = 'front'
ul.insertBefore(li2, ul.children[0])
页面效果:
3.3 删除节点
// node.removeChild(child) 从DOM中删除一个子节点,返回删除的节点
// 删除第一个子节点
let remove = ul.removeChild(ul.children[0]) // remove 用来接受被删除的子节点
console.log(remove) // 打印子节点
页面效果:
输出结果:
3.4 复制节点(克隆节点)
// node.cloneNode() 返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点
注意:
- 如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
- 如果括号参数为true,则是深度拷贝,会复制节点本身以及里面所有的子节点
// 克隆最后一个节点并将其添加到最后(浅拷贝)
let same = ul.lastChild.cloneNode()
ul.appendChild(same)
页面效果;
// 克隆最后一个节点并将其添加到最后(深度拷贝)
let same = ul.lastChild.cloneNode(true)
ul.appendChild(same)
页面效果:
四、补充
三种动态创建元素的区别
- document.write()
- element.innerHTML
- document.createElement()
区别:
- document.write() 也可以创建元素,是直接将内容写入页面的内容流,但是果页面文档流加载完毕,再调用此API会导致页面重绘。
- innerHTML 是将内容写入某个DOM节点,不是导致页面全部重绘
- innerHTML创建多个元素效率更高(不要拼接字符串,采用数组形式拼接),结构稍微复杂。
- createElement()创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML效率要比createElement()高(前提是不拼接字符串)。
五、学习总结
本文主要总结了原生js中常用的操作DOM的API接口,主要为了复习基础知识。平时开发用多了类库,对基础知识的了解可能就渐渐地遗忘,但这些基础知识才是我们立足的根本,只有掌握原生的js,才能真正做好js的开发。