JavaScript — DOM API
Posted 一朵花花
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript — DOM API相关的知识,希望对你有一定的参考价值。
前言:
JS 分为三大部分,之前已经学习了ES(基础语法部分),本篇来讨论第二部分:DOM API — 操作页面结构
DOM API
DOM 概念
DOM (Document Object Model),页面文档对象模型
W3C 标准给我们提供了一系列的函数,让我们可以操作:
- 网页内容
- 网页结构
- 网页样式
DOM 树
一个页面的结构是一个树形结构,称为 DOM 树
相当于 html 树形结构,为一个多子树结构(一个节点下可以有多个);每个节点都可以抽象为一个页面文档的对象
DOM API
即:JS 提供的,操作界面元素(节点)的API
事件
基本概念
JS 及 DOM API,都和事件有关
JS 要构建动态页面,就需要感知到用户的行为;如:用户对于页面的一些操作(点击,选择,修改等) 操作都会在浏览器中产生一个个事件,被 JS 获取到,从而进行更复杂的交互操作
时间三要素
- 事件源: 由哪个元素触发的;如:用户点了一个按钮,这个按钮就是事件源
- 事件类型: 用户操作的类型,如:点击,选中,修改…
- 事件处理程序: 事件发生之后,需要做什么?即: 进一步如何处理,往往是一个回调函数(回调函数,事件发生后,由浏览器自动执行里边的代码)
举例:
<input type="button" value="点我呀" onclick="alert('点就点');">
JS 代码主要流程
写 JS 代码,主要流程:
1.事件源: 学习如何选择页面元素 (DOM API 中,把这些页面元素也称为 DOM 元素)
2.调用 DOM 元素的 API 来做事情
做什么事情?
2.1 设置属性(比如style属性就是样式,on开头的属性就是事件属性)
2.2 设置标签内容
获取页面元素
这部分工作类似于 CSS 选择器的功能
querySelector & querySelectorAll
querySelector
之前的获取元素的方式都比较麻烦,而使用 querySelector 能够完全复用前面学过的 CSS 选择
器知识,可以更快更精准的获取到元素对象
querySelector 调用的节点元素下,去查找满足选择器条件的元素,最后 element 就是选择到的元素
var element = document.querySelector(selectors);
.
document: 页面顶级节点
selectors: 字符串内容,格式和 CSS 一样(CSS 选择器可以获取到哪些元素,querySelector 就可以获取到哪些元素)
总结:
- selectors 包含一个或多个要匹配的选择器的 DOM字符串 DOMString,该字符串必须是有效的
CSS选择器字符串;如果不是,则引发 SYNTAX_ERR 异常 - 表示文档中与指定的一组CSS选择器匹配的第一个元素的 html元素 Element 对象.
- 如果您需要与指定选择器匹配的所有元素的列表,则应该使用 querySelectorAll()
- 可以在任何元素上调用,不仅仅是 document;调用这个方法的元素将作为本次查找的根元素
如:
querySelectorAll
用法和 querySelector 类似
举例:
若选择器返回多个元素,需要使用querySelectorAll,返回的是一个数组,其中包含多个元素
<body>
<p>p1</p>
<p>p2</p>
<p>p3</p>
</body>
<script>
// 如果选择器返回多个元素,需要使用querySelectorAll,返回的是一个数组,其中包含多个元素
var arr = document.querySelectorAll("p");
// 遍历数组
for(let i=0; i<arr.length; i++)
console.log(arr[i]);
</script>
操作元素
获取 / 修改元素内容
innerHTML 用的场景比 innerText 更多
innerText
Element.innerText 属性表示一个节点及其后代的"渲染"文本内容
读操作 —— var renderedText = HTMLElement.innerText;
写操作 —— HTMLElement.innerText = string;
举例:
<body>
<div></div>
</body>
<script>
// 给div 添加内容
var div = document.querySelector("div");
div.innerText = "innerText设置内容";
</script>
缺点: 若是修改内容时,带一些 html 的标签作为字符串,此时不会把标签渲染成 html 的元素 (不识别 html 标签)
<script>
var div = document.querySelector("div");
div.innerText = "<span>innerText设置内容</span>";
</script>
由上述例子可以看到,通过 innerText 无法获取到 div 内部的 html 结构,只能得到文本内容; 修改页面的时候也会把 span 标签当成文本进行设置,不会渲染为 html 结构
innerHTML
Element.innerHTML 属性设置或获取HTML语法表示的元素的后代
读操作 —— var content = element.innerHTML;
写操作 —— element.innerHTML = htmlString;
<script>
var div = document.querySelector("div");
div.innerHTML = "<span>innerHTML设置内容</span>";
</script>
通过 innerHTML 获取到的字符串, 不光能获取到页面的 html 结构,同时也能修改结构;并且获取到的内容保留空格和换行
获取 / 修改元素属性
可以通过 Element 对象的属性来直接修改,就能影响到页面显示效果
举例:
console.dir() 表示,将一个对象中的属性、方法打印出来
<body>
<img src="xiawen2.jpg" alt="加载失败" title="哈温呐">
</body>
<script>
var img = document.querySelector("img");
console.dir(img);
</script>
修改 img 的 src 属性:
<body>
<img src="xiawen2.jpg" alt="加载失败" title="哈温呐">
</body>
<script>
var img = document.querySelector("img");
console.dir(img);
img.src = "xiawen.jpg";
</script>
打开网页的时候,最开始是 xiawen2.jpg,还没有等我们反应过来时,就已经变成了 xiawen.jpg,因为执行的速度非常快
点击图片,切换为另一张图片:
<script>
var img = document.querySelector("img");
img.onclick = function ()
if (img.src.lastIndexOf('xiawen2.jpg') !== -1)
img.src = './xiawen.jpg';
else
img.src = './xiawen2.jpg';
</script>
获取 / 修改样式属性
CSS 中指定给元素的属性,都可以通过 JS 来修改
行内样式操作
element.style.[属性名] = [属性值];
element.style.cssText = [属性名+属性值];
“行内样式”,通过 style 直接在标签上指定的样式,优先级很高;适用于改的样式少的情况
举例:
<div style="font-size: 20px; font-weight: 700;">一朵花花</div>
点击修改颜色:
// 点击后修改颜色
var div = document.querySelector('div');
div.onclick = function ()
// 获取 div 标签文本颜色
var curColor = div.style.color;
if(curColor == '' || curColor == 'black')
div.style.color = "red";
else
div.style.color = "black";
类名样式操作
element.className = [CSS 类名];
修改元素的 CSS 类名,适用于要修改的样式很多的情况
夜间模式切换
<style>
/* 白天模式: 白底黑字 */
.day
background-color: white;
color: black;
/* 黑夜模式: 黑底白字 */
.night
background-color: black;
color: white;
</style>
<body>
<span class="day">花花呀</span>
</body>
<script>
var span = document.querySelector("span");
span.onclick = function()
//获取当前点击的 class
var cls = span.className;
if(cls == 'day')
span.className = "night";
else
span.className = "day";
</script>
由于 class 是 JS 的保留字,所以名字叫做 className
获取 / 修改表单元素属性
表单 (主要是指 input 标签) 的以下属性都可以通过 DOM 来修改
- value: input 的值
- disabled:禁用
- checked:复选框会使用
- selected:下拉框会使用
- type:input 的类型(文本,密码,按钮,文件等)
例1 — 切换按钮的文本
<input type="button" id="bf" value="播放">
// 选择按钮元素,绑定点击事件,切换显示的文版内容
var btn = document.querySelector("#bf");
btn.onclick = function()
var content = btn.value;
if(content == '播放')
btn.value = '暂停';
else
btn.value = '播放';
例2 — 点击按钮,文本值+1
<input type="text" id="sum" value="0">
<input type="button" id="sum_btn" value="点我+1">
var sum = document.querySelector("#sum");
var sumBtn = document.querySelector("#sum_btn");
sumBtn.onclick = function()
var count = +sum.value; //返回字符串
console.log(count); // 转换成数值
sum.value = count + 1;
例3 — 全选 / 取消全选按钮
在 HTML 中,属性值设为 “checked” 为选中;而在 JS 中,需要设置为 true / false
<input type="checkbox" id="all">全部选中
<input type="checkbox" class="item">艾希
<input type="checkbox" class="item">凯特琳
<input type="checkbox" class="item">VN
// 全部选择 / 取消
var all = document.querySelector("#all");
all.onclick = function()
//子复选框
var items = document.querySelectorAll(".item");
if(all.checked)
for(item of items)
item.checked = true;
else
for(item of items)
item.checked = false;
优化用户体验:
var all = document.querySelector("#all");
var items = document.querySelectorAll(".item");
all.onclick = function()
console.log(all.checked);
for(item of items)
item.checked = all.checked;
for(item of items)
item.onclick = function()
// all 复选框是否被选中
let allChecked = true;
// 所有子复选框是否被选中
for(it of items)
if(!it.checked)
allChecked = false;
all.checked = allChecked;
操作节点
新增节点
分成两个步骤
- 创建元素节点
- 把元素节点插入到 DOM 树中
1.创建元素节点
可以直接在最后的元素后创建
<input type="text" id="content">
<input type="button" id="add" value="内容">
<div id="container">
<h3>内容</h3>
</div>
var add = document.querySelector("#add");
var content = document.querySelector("#content");
var container = document.querySelector("#container");
add.onclick = function()
// 点击,获取文本框内容
var text = content.value;
// innerHTML ,先获取 container 中的所有元素,在最后添加元素
var html = container.innerHTML;
html += "<p>";
html += text;
html += "</p>";
container.innerHTML = html;
但以上修改 container 中的所有内容,效率比较差,已有的标签已经渲染了,重新设置又会再次渲染
可以使用 createElement 方法来创建一个元素
var element = document.createElement(tagName[, options]);
var add = document.querySelector("#add");
var content = document.querySelector("#content");
var container = document.querySelector("#container");
add.onclick = function()
var text = content.value;
// 方式2
// 创建一个dom元素(<p>),然后添加到 container 中,作为最后一个子节点
var p = document.createElement("p"); // 创建一个元素
p.innerHTML = text;
container.appendChild(p); //添加到dom树形结构中,作为最后一个子节点
2.插入节点到 DOM 树中
- 使用 appendChild 将节点插入到指定节点的最后一个孩子之后
element.appendChild(aChild)
.
DOM 包含的子节点不动,在最后添加 element 节点,效率比较高
仍以上述为例:
container.appendChild(p); —— 添加到dom树形结构中,作为最后一个子节点
- 使用 insertBefore 将节点插入到指定节点之前
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
.
含义: 在 parentNode 节点中,有一个 insertedNode 的子节点,在这个子节点前,插入一个 newNode 节点
- insertedNode 被插入节点(newNode)
- parentNode 新插入节点的父节点
- newNode 用于插入的节点
- referenceNode newNode 将要插在这个节点之前
如果 referenceNode 为 null 则 newNode 将被插入到子节点的末尾
注意: referenceNode 引用节点不是可选参数
补充:
DOM 对象,其中包含属性:
- dom.children — 返回 DOM 对象下一级左右的子节点数组
- dom.parentNode — 返回该 DOM 对象上一级的父节点
<div id="insertBeforeDiv">
<p>11111</p>
<p>22222</p>
<p>33333</p>
<p>44444</p>
</div>
// insertBefore 学习
var insertBeforeDiv = document.querySelector("#insertBeforeDiv");
// 准备要插入的节点
var insertNode = document.createElement("p");
insertNode.innerHTML = "新插入节点";
insertBeforeDiv.insertBefore(insertNode, insertBeforeDiv.children[0]);
如果节点是页面已存在的,就做移动操作
<p id="beInsert">原P标签</p>
<ul>
<li>
<p>p111</p>
</li>
<li>
<p>p222</p>
</li>
</ul>
var beInsert = document.querySelector("#beInsert");
var ul = document.querySelector("ul");
// 构造一个 li 标签
var li = document.createElement("li");
li.appendChild(beInsert); // <li><p>beInsert</p></li>
ul.insertBefore(li,ul.children[0]);
删除节点
使用 removeChild 删除子节点
oldChild = element.removeChild(child);
.
含义: element 作为父节点,删除里边的 child 子节点,返回值 oldChild,作为已经删除的节点,还可以继续使用.
.
① child 为待删除节点
② element 为 child 的父节点
③ 返回值为该被删除节点
④ 被删除节点只是从 dom 树被删除了,但是仍然在内存中,可以随时加入到 dom 树的其他位
置.
⑤ 若 child节点 不是 element 节点的子节点,则该方法会抛出异常
举例: 删除 ul 中的最后一个 li
var last = ul.children[ul.children.length - 1]; // 取最后一个 li 节点
ul.removeChild(last);
以上是关于JavaScript — DOM API的主要内容,如果未能解决你的问题,请参考以下文章