目录
(2) querySelector 和 querySelectorAll
一、DOM简介
DOM (Document Object Model) 译为文档对象模型,是 HTML 和 XML 文档的编程接口。
HTML DOM 定义了访问和操作 HTML 文档的标准方法。
DOM 以树结构表达 HTML 文档。
通过可编程的对象模型,JavaScript 获得了足够的能力来创建动态的 HTML:
- JavaScript 能够改变页面中的所有 HTML
- 元素 JavaScript 能够改变页面中的所有 HTML 属性
- JavaScript 能够改变页面中的所有 CSS 样式
- JavaScript 能够对页面中的所有事件做出反应
二、HTML DOM 树形结构:
- 文档:一个页面就是一个文档,DOM 中使用 document 表示
- 元素:页面中的所有标签都是元素,DOM 中使用 element 表示
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM 中使用 node 表示
三、DOM 节点
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
- 整个文档是一个文档节点
- 每个 HTML 元素是元素节点
- HTML 元素内的文本是文本节点
- 每个 HTML 属性是属性节点
- 注释是注释节点
节点类型
- 元素节点 nodeType 为 1
- 属性节点 nodeType 为 2
- 文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)
节点父、子和同胞
节点树中的节点彼此拥有层级关系。
我们常用父(parent)、子(child)和同胞(sibling)等术语来描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
- 在节点树中,顶端节点被称为根(root)。
- 每个节点都有父节点、除了根(它没有父节点)。
- 一个节点可拥有任意数量的子节点。
- 同胞是拥有相同父节点的节点。
下面的图片展示了节点树的一部分,以及节点之间的关系:
(1) 父级节点
node.parentNode
- parentNode 属性可返回某节点的父节点,注意是最近的一个父节点
- 如果指定的节点没有父节点则返回 null
(2)子节点childNodes
parentNode.childNodes(标准)
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
// 1. 子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等
console.log(ul.childNodes);
结果:
换行属于text节点
for(var i = 0; i < ul.childNodes.length;i++) {
if (ul.childNodes[i].nodeType == 1) {
// ul.childNodes[i] 是元素节点
console.log(ul.childNodes[i]);
} }
(3)子节点children
parentNode.children(非标准)
(4)子节点first和last
parentNode.firstChild
firstChild 返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。
parentNode.lastChild
parentNode.firstElementChild
firstElementChild 返回第一个子元素节点,找不到则返回null。
parentNode.lastElementChild
lastElementChild 返回最后一个子元素节点,找不到则返回null。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
<li>我是li5</li>
</ol>
<script>
var ol = document.querySelector('ol');
// 1. firstChild 第一个子节点 不管是文本节点还是元素节点
console.log(ol.firstChild);
console.log(ol.lastChild);
// 2. firstElementChild 返回第一个子元素节点 ie9才支持
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
// 3. 实际开发的写法 既没有兼容性问题又返回第一个子元素
console.log(ol.children[0]);
console.log(ol.children[ol.children.length - 1]);
</script>
</body>
</html>
结果:
(5)兄弟节点
同上一个,直接上代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div>我是div</div>
<span>我是span</span>
<script>
var div = document.querySelector('div');
// 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等
console.log(div.nextSibling);
console.log(div.previousSibling);
// 2. nextElementSibling 得到下一个兄弟元素节点
console.log(div.nextElementSibling);
console.log(div.previousElementSibling);
</script>
</body>
</html>
四、DOM对象
当浏览器载入 HTML 文档, 它就会成为 Document 对象
Document 对象是 HTML 文档的根节点
Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问
提示: Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问。
1、查找 HTML 元素常用方法
(1)get方法
方法 | 描述 |
---|---|
getElementById() | 返回带有指定 ID 的元素。 |
getElementsByTagName() | 返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)。 |
getElementsByClassName() | 返回包含带有指定类名的所有元素的节点列表。 |
// 返回ID为'test'的节点:
var test = document.getElementById('test');
// 先定位ID为'test-table'的节点,再返回其内部所有tr节点:
var trs = document.getElementById('test-table').getElementsByTagName('tr');
// 先定位ID为'test-div'的节点,再返回其内部所有class包含red的节点:
var reds = document.getElementById('test-div').getElementsByClassName('red');
(2) querySelector 和 querySelectorAll
注意:querySelector 和 querySelectorAll里面的选择器需要加符号,比如:
document.querySelector('#nav');
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="box">盒子1</div>
<div class="box">盒子2</div>
<div id="nav">
<ul>
<li>首页</li>
<li>产品</li>
</ul>
</div>
<script>
// 1. getElementsByClassName 根据类名获得某些元素集合
var boxs = document.getElementsByClassName('box');
console.log(boxs);
// 2. querySelector 返回指定选择器的第一个元素对象 切记 里面的选择器需要加符号 .box #nav
var firstBox = document.querySelector('.box');
console.log(firstBox);
var nav = document.querySelector('#nav');
console.log(nav);
var li = document.querySelector('li');
console.log(li);
// 3. querySelectorAll()返回指定选择器的所有元素对象集合
var allBox = document.querySelectorAll('.box');
console.log(allBox);
var lis = document.querySelectorAll('li');
console.log(lis);
</script>
</body>
</html>
(3)获取特殊元素(body,html)
2、事件基础
在学习DOM的增删改查之前,我们先了解一下什么是事件。
(1)事件概述
(2)事件三要素
- 事件源 (谁)
- 事件类型 (什么事件)
- 事件处理程序 (做啥)
例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button id="btn">唐伯虎</button>
<script>
// 点击一个按钮,弹出对话框
// 1. 事件是有三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素
//(1) 事件源 事件被触发的对象 谁 按钮
var btn = document.getElementById('btn');
//(2) 事件类型 如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下
//(3) 事件处理程序 通过一个函数赋值的方式 完成
btn.onclick = function() {
alert('点秋香');
}
</script>
</body>
</html>
(3) 事件汇总
下面总结一些常用的事件。
鼠标事件
属性 | 描述 |
---|---|
onclick | 当用户点击某个对象时调用的事件句柄。 |
oncontextmenu | 在用户点击鼠标右键打开上下文菜单时触发 |
ondblclick | 当用户双击某个对象时调用的事件句柄。 |
onmousedown | 鼠标按钮被按下。 |
onmouseenter | 当鼠标指针移动到元素上时触发。 |
onmouseleave | 当鼠标指针移出元素时触发 |
onmousemove | 鼠标被移动。 |
onmouseover | 鼠标移到某元素之上。 |
onmouseout | 鼠标从某元素移开。 |
onmouseup | 鼠标按键被松开。 |
键盘事件
属性 | 描述 |
---|---|
onkeydown | 某个键盘按键被按下。 |
onkeypress | 某个键盘按键被按下并松开。 |
onkeyup | 某个键盘按键被松开。 |
表单事件
属性 | 描述 |
---|---|
onblur | 元素失去焦点时触发 |
onchange | 该事件在表单元素的内容改变时触发( <input>, <keygen>, <select>, 和 <textarea>) |
onfocus | 元素获取焦点时触发 |
onfocusin | 元素即将获取焦点时触发 |
onfocusout | 元素即将失去焦点时触发 |
oninput | 元素获取用户输入时触发 |
onreset | 表单重置时触发 |
onsearch | 用户向搜索域输入文本时触发 ( <input="search">) |
onselect | 用户选取文本时触发 ( <input> 和 <textarea>) |
onsubmit | 表单提交时触发 |
剪贴板事件
属性 | 描述 |
---|---|
oncopy | 该事件在用户拷贝元素内容时触发 |
oncut | 该事件在用户剪切元素内容时触发 |
onpaste | 该事件在用户粘贴元素内容时触发 |
完整版事件见如下链接:https://www.runoob.com/jsref/dom-obj-event.html
3、改变元素内容
(1)innerText和innerHTML
element.innerText
从起始位置到终止位置的内容, 但它去除 html 标签, 同时空格和换行也会去掉
element.innerHTML
起始位置到终止位置的全部内容,包括 html 标签,同时保留空格和换行
(2)常用元素的属性操作
1. innerText、innerHTML 改变元素内容
2. src、href
3. id、alt、title
(3)样式属性操作
1. element.style 行内样式操作
2. element.className 类名样式操作
注意1:
(4)案例
见:
4、自定义属性
(1) 获取属性值
- element.属性
- element.getAttribute('属性')
- element.属性 获取内置属性值(元素本身自带的属性)
- element.getAttribute(‘属性’); 主要获得自定义的属性 (标准) 我们程序员自定义的属性
(2)设置属性值
- element.属性 = ‘值’
- element.setAttribute('属性', '值')
- element.属性 设置内置属性值
- element.setAttribute(‘属性’); 主要设置自定义的属性 (标准)
(3)移除属性
- element.removeAttribute('属性')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="demo" index="1" class="nav"></div>
<script>
var div = document.querySelector('div');
// 1. 获取元素的属性值
// (1) element.属性
console.log(div.id);
//(2) element.getAttribute('属性') get得到获取 attribute 属性的意思 我们程序员自己添加的属性我们称为自定义属性 index
console.log(div.getAttribute('id'));
console.log(div.getAttribute('index'));
// 2. 设置元素属性值
// (1) element.属性= '值'
div.id = 'test';
div.className = 'navs';
// (2) element.setAttribute('属性', '值'); 主要针对于自定义属性
div.setAttribute('index', 2);
div.setAttribute('class', 'footer'); // class 特殊 这里面写的就是class 不是className
// 3 移除属性 removeAttribute(属性)
div.removeAttribute('index');
</script>
</body>
</html>
(4)H5自定义属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div getTime="20" data-index="2" data-list-name="andy"></div>
<script>
var div = document.querySelector('div');
console.log(div.getTime);
console.log(div.getAttribute('getTime'));
div.setAttribute('data-time', 20);
console.log(div.getAttribute('data-index'));
console.log(div.getAttribute('data-list-name'));
// h5新增的获取自定义属性的方法 它只能获取data-开头的
// dataset 是一个集合里面存放了所有以data开头的自定义属性
console.log(div.dataset);
console.log(div.dataset.index);
console.log(div.dataset['index']);
// 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
</script>
</body>
</html>
5、创建、添加、删除、复制节点
(1)创建节点
(2)添加节点
(3)删除节点
(4)复制节点(克隆节点)
(5)三种动态创建元素区别
- document.write()
- element.innerHTML
- document.createElement()
- document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
- innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
- innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
- createElement() 创建多个元素效率稍低一点点,但是结构更清晰