JavaScript — DOM API
前言:
JS 分为三大部分,之前已经学习了ES(基础语法部分),本篇来讨论第二部分:DOM API — 操作页面结构
DOM API
- DOM 概念
- 事件
- 基本概念
- 时间三要素
- JS 代码主要流程
- 获取页面元素
- querySelector & querySelectorAll
- 操作元素
- 获取 / 修改元素内容
- innerText
- innerHTML
- 获取 / 修改元素属性
- 获取 / 修改样式属性
- 获取 / 修改表单元素属性
- 操作节点
- 新增节点
- 1.创建元素节点
- 2.插入节点到 DOM 树中
- 删除节点
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(){//获取当前点击的 classvar 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相关推荐
- 好程序员web前端教程分享JavaScript验证API
好程序员web前端教程分享JavaScript验证API,小编每天会分享一下干货给大家.那么今天说道的就是web前端培训课程中的章节. JavaScript验证API 约束验证DOM方法 Proper ...
- SAP UI5 应用开发教程之四十五 - 如何在 SAP UI5 应用里使用 jQuery 和原生的 DOM API
一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...
- JavaScript + Audio API自制简易音乐播放器(详细完整版、小白都能看懂)
JavaScript + Audio API自制简易音乐播放器(详细完整版) ** 音乐播放器的功能清单如下: ** 1.点击暂停按钮,歌曲暂停 2.点击播放按钮,歌曲播放 3.单曲循环与取消单曲循环 ...
- 初读JavaScript DOM编程艺术(一)
JavaScript DOM编程艺术--前三章概念总结 一. 概述 1.什么是JavaScript 2.什么是DOM 二. JavaScript 语法 1. 语句和注释 2. 变量和数组 三. DOM ...
- JavaScript DOM编程艺术第一章:JavaScript简史
本系列的博客是由本人在阅读<JavaScript DOM编程艺术>一书过程中做的总结.前面的偏理论部分都是书中原话,觉得有必要记录下来,方便自己翻阅,也希望能为读到本博客的人提供一些帮助, ...
- 前端开发学习笔记(二)JavaScript DOM编程技术(一、二)
陆陆续续看了将近2周的时间,其实书中的内容不难理解,只不过最近的事情较多,不能静下心来. 第一章 JavaScript简史 采用标准化的思路来建立网站,引入"WEB标准"技术.XH ...
- 使用 JavaScript 调用 API
使用 JavaScript 调用 API 前言 译者述 作者述 预备知识 本文目标 快速浏览 配置 连接 API 获得 API 端点 通过 HTTP 请求检索数据 处理 JSON 响应 展示数据 总结 ...
- 传智播客--JavaScript DOM加强(佟刚)
上了一天的课,很累,不过真的很充实.比自己学的效率要高很多,对技术的理解也提高了不少.对自己又充满了信心,感觉自己两个半月后一定能找到一个五千块 以上的工作.哈哈!今天是佟刚老师讲的 JavaScri ...
- 六、前端开发-JavaScript DOM
六.前端开发语言体系-JavaScript DOM 文章目录 六.前端开发语言体系-JavaScript DOM JavaScript DOM DOM简介 DOM方法 DOM事件 DOM事件监听器 D ...
- javascript DOM 遍历
javascript DOM 遍历 由 愚人码头 撰写 http://www.css88.com/archives/514 javascript DOM 遍历 以下一系列的辅助函数可以帮助您,他们能取 ...
最新文章
- APP启动原理,APPdelegate程序状态解析
- python2.7.13环境搭建
- angr学习笔记(11)(SimProcedure)
- error: invalid use of incomplete type 'XXXX' ;error: forward declaration of 'XXXX' 声明改为包含头文件
- python opencv 教程_OpenCV-Python系列教程介绍
- 《A Discussion on Solving Partial Differential Equations using Neural Networks》梳理
- 数据结构与算法 第二章习题课
- 利用shell脚本远程磁盘分区
- springboot 集成redis实现session共享
- 商学院计算机系篮球策划书,篮球训练营策划书.doc
- matlab output()函数,MATLAB - Data Output
- 在积分系统中可以设置哪些获取积分方式
- 【编程之外】当遮羞布被掀开,当人们开始接受一切
- SpringBoot启动报错:Parameter 0 of method hmset in com.qcby.rbac.util.RedisUtils required a bean of type
- 中国电影的网络付费点播发行:现状与展望
- php 合成图片,合成圆形图片
- Linux 系统如何查看文件是32位还是64位?
- linux用什么命令查看ip,Linux中ip命令的使用实例
- 软件外包项目如何承接
- 关系数据库-关系代数-数据库习题