前言:
JS 分为三大部分,之前已经学习了ES(基础语法部分),本篇来讨论第二部分:DOM API — 操作页面结构
DOM (Document Object Model),页面文档对象模型
W3C 标准给我们提供了一系列的函数,让我们可以操作:
DOM 树
一个页面的结构是一个树形结构,称为 DOM 树
相当于 html 树形结构,为一个多子树结构(一个节点下可以有多个);每个节点都可以抽象为一个页面文档的对象
DOM API
即:JS 提供的,操作界面元素(节点)的API
JS 及 DOM API,都和事件有关
JS 要构建动态页面,就需要感知到用户的行为;如:用户对于页面的一些操作(点击,选择,修改等) 操作都会在浏览器中产生一个个事件,被 JS 获取到,从而进行更复杂的交互操作
举例:
<input type="button" value="点我呀" onclick="alert('点就点');">
写 JS 代码,主要流程:
1.事件源: 学习如何选择页面元素 (DOM API 中,把这些页面元素也称为 DOM 元素)
2.调用 DOM 元素的 API 来做事情
做什么事情?
2.1 设置属性(比如style属性就是样式,on开头的属性就是事件属性)
2.2 设置标签内容
这部分工作类似于 CSS 选择器的功能
querySelector
之前的获取元素的方式都比较麻烦,而使用 querySelector 能够完全复用前面学过的 CSS 选择
器知识,可以更快更精准的获取到元素对象
querySelector 调用的节点元素下,去查找满足选择器条件的元素,最后 element 就是选择到的元素
var element = document.querySelector(selectors);
.
document: 页面顶级节点
selectors: 字符串内容,格式和 CSS 一样(CSS 选择器可以获取到哪些元素,querySelector 就可以获取到哪些元素)
总结:
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 更多
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 结构
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 来修改
例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;
}
}
分成两个步骤
可以直接在最后的元素后创建
<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树形结构中,作为最后一个子节点
}
仍以上述为例:
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 对象,其中包含属性:
<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);
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://xhuahua.blog.csdn.net/article/details/122580394
内容来源于网络,如有侵权,请联系作者删除!