前言:
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;}
}

操作节点

新增节点

分成两个步骤

  1. 创建元素节点
  2. 把元素节点插入到 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相关推荐

  1. 好程序员web前端教程分享JavaScript验证API

    好程序员web前端教程分享JavaScript验证API,小编每天会分享一下干货给大家.那么今天说道的就是web前端培训课程中的章节. JavaScript验证API 约束验证DOM方法 Proper ...

  2. SAP UI5 应用开发教程之四十五 - 如何在 SAP UI5 应用里使用 jQuery 和原生的 DOM API

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...

  3. JavaScript + Audio API自制简易音乐播放器(详细完整版、小白都能看懂)

    JavaScript + Audio API自制简易音乐播放器(详细完整版) ** 音乐播放器的功能清单如下: ** 1.点击暂停按钮,歌曲暂停 2.点击播放按钮,歌曲播放 3.单曲循环与取消单曲循环 ...

  4. 初读JavaScript DOM编程艺术(一)

    JavaScript DOM编程艺术--前三章概念总结 一. 概述 1.什么是JavaScript 2.什么是DOM 二. JavaScript 语法 1. 语句和注释 2. 变量和数组 三. DOM ...

  5. JavaScript DOM编程艺术第一章:JavaScript简史

    本系列的博客是由本人在阅读<JavaScript DOM编程艺术>一书过程中做的总结.前面的偏理论部分都是书中原话,觉得有必要记录下来,方便自己翻阅,也希望能为读到本博客的人提供一些帮助, ...

  6. 前端开发学习笔记(二)JavaScript DOM编程技术(一、二)

    陆陆续续看了将近2周的时间,其实书中的内容不难理解,只不过最近的事情较多,不能静下心来. 第一章 JavaScript简史 采用标准化的思路来建立网站,引入"WEB标准"技术.XH ...

  7. 使用 JavaScript 调用 API

    使用 JavaScript 调用 API 前言 译者述 作者述 预备知识 本文目标 快速浏览 配置 连接 API 获得 API 端点 通过 HTTP 请求检索数据 处理 JSON 响应 展示数据 总结 ...

  8. 传智播客--JavaScript DOM加强(佟刚)

    上了一天的课,很累,不过真的很充实.比自己学的效率要高很多,对技术的理解也提高了不少.对自己又充满了信心,感觉自己两个半月后一定能找到一个五千块 以上的工作.哈哈!今天是佟刚老师讲的 JavaScri ...

  9. 六、前端开发-JavaScript DOM

    六.前端开发语言体系-JavaScript DOM 文章目录 六.前端开发语言体系-JavaScript DOM JavaScript DOM DOM简介 DOM方法 DOM事件 DOM事件监听器 D ...

  10. javascript DOM 遍历

    javascript DOM 遍历 由 愚人码头 撰写 http://www.css88.com/archives/514 javascript DOM 遍历 以下一系列的辅助函数可以帮助您,他们能取 ...

最新文章

  1. APP启动原理,APPdelegate程序状态解析
  2. python2.7.13环境搭建
  3. angr学习笔记(11)(SimProcedure)
  4. error: invalid use of incomplete type 'XXXX' ;error: forward declaration of 'XXXX' 声明改为包含头文件
  5. python opencv 教程_OpenCV-Python系列教程介绍
  6. 《A Discussion on Solving Partial Differential Equations using Neural Networks》梳理
  7. 数据结构与算法 第二章习题课
  8. 利用shell脚本远程磁盘分区
  9. springboot 集成redis实现session共享
  10. 商学院计算机系篮球策划书,篮球训练营策划书.doc
  11. matlab output()函数,MATLAB - Data Output
  12. 在积分系统中可以设置哪些获取积分方式
  13. 【编程之外】当遮羞布被掀开,当人们开始接受一切
  14. SpringBoot启动报错:Parameter 0 of method hmset in com.qcby.rbac.util.RedisUtils required a bean of type
  15. 中国电影的网络付费点播发行:现状与展望
  16. php 合成图片,合成圆形图片
  17. Linux 系统如何查看文件是32位还是64位?
  18. linux用什么命令查看ip,Linux中ip命令的使用实例
  19. 软件外包项目如何承接
  20. 关系数据库-关系代数-数据库习题

热门文章

  1. ubutun 滑动 触控板_Ubuntu系统的笔记本触摸板怎么调节鼠标光标速度?
  2. C语言中整型变量四舍五入,怎样将整型变量按四舍五入转换成整数
  3. 《奈何BOSS要娶我》将播 制片人:做了很多反套路的改编
  4. 读后感:《走出软件作坊》51:幽幽一缕香
  5. dub怎么生成这么大的垃圾呢.
  6. JAVA版12306抢票工具
  7. SpringCloud Gateway堆外内存溢出排查
  8. 淘咖啡:阿里无人咖啡馆效果图
  9. 内存大计算机运行就快吗,内存一样大,为什么就电脑的运行速度最快?
  10. python 数据shape的理解