当前位置: 首页 > news >正文

前端学习(5)—— JavaScript(WebAPI)

目录

一,背景知识

1.1 关于JS

1.2 关于 DOM

1.3 获取元素

二,事件

2.1 点击事件

2.2 键盘事件 

三,操作元素

3.1 获取/修改元素内容

3.2 获取/修改元素属性

3.3 获取/修改表单元素属性

3.4 获取/修改样式属性

四,操作节点

4.1 新增节点

4.4.1 创建元素节点

4.4.2 插入节点到 DOM 树中

4.2 删除节点


一,背景知识

1.1 关于JS

JavaScript包含三个大部分:

  • ECMAScript:基础语法部分
  • DOM API:操作页面结构
  • BOM API:操作浏览器

我们前面学习的 JS 基础语法主要学的是第一部分,但只靠基础语法只能让我们的页面进行一些简单的操作,要实现一个更复杂高级的交互式页面,还需要有 WebAPI 的支持 

WebAPI 特指 DOM+BOM,可以参考文档: Web API | MDN

1.2 关于 DOM

DOM 全称 Document  Object Model,W3C 标准为我们提供一系列函数,让我们可以对网页内容、结构、样式进行操作

一个页面的结构是一个树形结构,称为 DOM 树,假设我们有一个页面,结构如下:

那么DOM 树结构用结构图来表示就是:

关于上面的图: 

  • 文档:一个页面就是一个文档,使用 document 表示,所以我们使用浏览器打开一个 .html 文件,页面标题默认显示为 document
  • 元素:页面中所有的标签都称为元素,使用element表示
  • 节点:网页中所有的内容都可以称为节点,使用 node 表示
  • 这些概念在 JS 的代码中就体现为一个一个的对象,所以上面的图又叫做“文档对象模型”

1.3 获取元素

这部分工作类似于 CSS 选择器的功能

①querySelector

 我们前面 CSS 的几种获取元素的方法比较麻烦,使用querySelector 能够完全复用我们 CSS 选择器的知识,并且能够更快更精准地获取到元素对象,使用地格式如下:

var element = document.querySelector(selectors);
  • selectors 包含一个或多个要匹配的选择器的 DOM字符串,该字符串必须是有效地CSS选择器字符串;如果不是,则引发 SYNTAX_ERR 异常;String - JavaScript | MDN
  • 表示文档中与指定的一组CSS选择器匹配的第一个元素的 html元素对象;Element - Web API | MDN
  • 如果您需要与指定选择器匹配的所有元素的列表,则应该使用 querySelectorAll();Document.querySelectorAll - Web API | MDN
  • 可以在任何元素上调用,不仅仅是 document。 调用这个方法的元素将作为本次查找的根元素

如下示例:

<div class="aaa">111</div>
<div id="bbb">222</div>
<h3><span><input type="text"></span></h3>
<script>var elem1 = document.querySelector('.aaa');console.log(elem1);var elem2 = document.querySelector('#bbb');console.log(elem2);var elem3 = document.querySelector('h3 span input');console.log(elem3);
</script>

②querySelectorAll

 querySelectorAll用法和上面类型:

<div class="aaa">111</div>
<div id="bbb">222</div>
<script>var elems = document.querySelectorAll('div');console.log(elems);
</script>

二,事件

2.1 点击事件

JS 要构建动态页面,首先要繁殖用户地行为,比如点击,选择,修改,提交等,这些操作都会在浏览器中产生一个个的事件,然后被 JS 捕获到,从而进行更复杂的交互操作

事件三要素:

  • 事件源: 哪个元素触发的
  • 事件类型: 是点击, 选中, 还是修改或者其它
  • 事件处理程序: 进一步如何处理. 往往是一个回调函数

该操作和操作系统中的信号处理很相似 

 下面来看一个简单示例:

<button id="btn">你好</button>
<script>var elem = document.getElementById('btn');elem.onclick = function(){alert("你好鸭");}
</script>

  • btn 按钮就是事件源,点击就是事件类型
  • function 这个匿名函数就是事件处理程序,其中 btn.onclick = function() 这个操作称为 注册事件/绑定事件
  • 这个匿名函数相当于一个回调函数,它不需要程序猿主动来调用,而是由浏览器在合适的时机(触发点击操作时)自动进行调用

2.2 键盘事件 

键盘事件我们主要介绍这三个:

主要涉及到三个函数,这三个函数事件发生顺序如下:

  • onkeydown:当用户按下某个键时发生
  • onkeypress:在用户按下某个键未松开时发生
  • onkeyup:用户释放键时发生

①onkeydown 

<input type="text">
<script>var input = document.querySelector('input');input.onkeydown = function(event) //event是一个全局事件{var a = event.keyCode;var b = String.fromCharCode(a); //直接打印a是打印ASCII码值的,这个函数是转换console.log(b + "键被按下了");}
</script>

 

可以看到我们的 onkeydown 是不区分大小写的,为了解决这个问题我们就需要用到我们的 onkeypress

②onkeypress

 我们直接把上面代码的 onkeydown 替换成 onkeypress:

③onkeyup

这个事件就是我们按下某个键后松开的一瞬间触发的一个事件,和前面的用法基本一致,下面我们把三个事件集合一下,如下代码:

<div><input type="text" class="hello1">不区分大小写</div>
<div><input type="text" class="hello2">区分大小写</div>
<script>let input1 = document.querySelector('.hello1');let input2 = document.querySelector('.hello2');let input3 = document.querySelector('.hello1');let input4 = document.querySelector('.hello2');input1.onkeydown = function (event) {if(event.shiftKey) alert("shift被按下");if(event.altKey) alert("alt被按下");if(event.ctrlKey) alert("Ctrl键被按下");5console.log("你好," + String.fromCharCode(event.keyCode) + "键正在按下");}input2.onkeypress = function (event) {console.log("你好," + String.fromCharCode(event.keyCode) + "键正在按下");}input3.onkeyup = function (event) {console.log(String.fromCharCode(event.keyCode) + "键松开了");}input4.onkeyup = function (event) {console.log(String.fromCharCode(event.keyCode) + "键松开了");}
</script>

解释一下:

  • 为两个点击事件各自设置了输入框,其中给第一个输入框附加了Shift,Alt等非字母键的事件,因为不是所有键(例如 ALT、CTRL、SHIFT、ESC)都会在所有浏览器中触发 onkeypress 事件。如需只检测用户是否按下了某个键,就改用 onkeydown 事件,因为它适用于所有键。 
  • 部分键的单独事件列表如下:

其它更多的事件可以查阅手册:HTML DOM 事件 

三,操作元素

3.1 获取/修改元素内容

①innerText 

Element.innerText 属性表示一个节点及其后代的“渲染”文本内容,如下示例:

<div><span>hello</span><span>world</span>
</div>
<script>var div = document.querySelector('div');console.log(div.innerText); //获取 div 内部内容div.innerText = '你好<span>你好鸭</span>'
</script>

  • 可以看到,innerText 无法获取到 div 内部其它的 html 标签,只能得到文本内容
  • 修改页面时会把其它的标签当初 文本进行设置 

②innerHTML

Element.innerHTML 属性设置或获取 HTML语法表示的元素的后代,先看下面示例:

<div><span>hello</span><span>world</span>
</div>
<script>var div = document.querySelector('div');console.log(div.innerHTML); //获取 div 内部内容div.innerHTML = '你好<span>你好鸭</span>'
</script>

  • 可以看到 innerHTML 不光能获取到页面的 html 结构,还能对替换后的内容进行重新渲染,而不是像 innerText那样纯文本替换

3.2 获取/修改元素属性

可以通过 Element 对象的属性来直接修改,就能影响到页面的显示效果:

<img src="./TestImg.png" alt="这是一个图标" title="刷新">
<script>var img = document.querySelector('img');console.dir(img);
</script>

我们也可以直接在代码中获取对应属性的值:

<img src="./TestImg.png" alt="这是一个图标" title="刷新">
<script>var img = document.querySelector('img');console.dir(img.src);console.dir(img.title);console.dir(img.alt);
</script>

还可以直接修改属性:

<img src="./TestImg.png" alt="这是一个图标" title="刷新">
<script>var img = document.querySelector('img');img.onclick = function(){if(img.src.lastIndexOf('TestImg.png') !== -1){img.src = './female.png';}else{img.src = './TestImg.png'}}
</script>

 这个代码就是实现一下点击图片就达到切换图片的功能,如下 gif :

3.3 获取/修改表单元素属性

表单(主要是指 imput 标签)的一下属性都可以同 DOM 来修改:

  • value:input的值
  • disabled:禁用
  • checked:复选框使用
  • selected:下拉框使用
  • type:input的类型

①示例1:切换按钮的文本

 假设有一个播放按钮,可以在“播放中” 和 “已暂停” 之间切换,如下代码:

<input type="button" value="播放中">
<script>var btn = document.querySelector('input');btn.onclick = function() {if(btn.value == "播放中"){btn.value = "已暂停";}else{btn.value = "播放中";}}
</script>

②示例2:点击计数

 使用一个输入框输入初始值,之后每次点击依次按钮,值 + 1,如下代码:

<input type="text" id="text" value="0">
<input type="button" id="btn" value='点我++'>
<script>var text = document.querySelector('#text');btn.onclick = function () {text.value++;}
</script>

  • input 有一个非常重要的属性就是 value,决定了表单的内容
  • 如果是输入框,value 表示输入框的内容,同时也会随着输入框内容的变化而变化
  • 按钮的 value 则表示按钮里的内容 

③示例3:全选/取消全部按钮 

点击全选按钮则直接选中所有选项,只要有一个选项取消,自动取消全选按钮的选中状态:如下代码:

<input type="checkbox" id="all">我全都要 <br>
<input type="checkbox" class="offer">腾讯offer <br>
<input type="checkbox" class="offer">字节offer <br>
<input type="checkbox" class="offer">大疆offer <br>
<input type="checkbox" class="offer">小米offer <br>
<script>// 1. 获取元素var all = document.querySelector('#all');var offer = document.querySelectorAll('.offer');// 2. 给 all 注册点击事件, 选中/取消所有选项all.onclick = function () {for (var i = 0; i < offer.length; i++) {offer[i].checked = all.checked;}}// 3. 给其它按钮注册点击事件for (var i = 0; i < offer.length; i++) {offer[i].onclick = function () {// 检测当前是不是所有的按钮都被选中了. all.checked = checkOffer(offer);}}// 4. 实现 checkOfferfunction checkOffer(offer) {for (var i = 0; i < offer.length; i++) {if (!offer[i].checked) {// 只要一个没被选中, 返回false,把全选按钮取消return false;}}// 所有按钮都选中了,结果就是全选中,把全选按钮选上return true;}
</script>

 解释下上面的代码:

  • 五个选项,其中第一个选项表示全选,剩下四个都是多选项
  • 首先对于全选项,如果勾选全选项,则通过循环把后面4各按钮全选上
  • 然后对于4个选项,有选中取消两种行为,如果选中一个,判断其余三个是否选中,如果其余三个全选中,则把全选按钮选上,否则什么也不做
  • 如果四个按钮有任意一个取消了,则直接把全选按钮取消

 

3.4 获取/修改样式属性

①行内样式操作

CSS 中指定给元素的属性,也都可以通过 JS 来修改

行内样式操作如下:

element.style.[属性名] = [属性值];
element.style.cssText = [属性名+属性值]

行内样式通过 style 直接在标签上指定样式,会覆盖之前的的样式,优先级很高,适用于改少量样式的情况,如下示例:

实现一个页面,要求点击文字则方法字体

<div style="font-size: 20px; font-weight: 700;">你好
</div>
<script>var div = document.querySelector('div');div.onclick = function () {var curFontSize = parseInt(this.style.fontSize);curFontSize += 10;this.style.fontSize = curFontSize + "px";}
</script>

 

  • style 中的属性都是“驼峰命名” 的方式和 CSS 属性对应的,例如上面的 font-size => fontSize,background-color => backgroundColor 
  • 这种方式只影响特定样式,其它内联样式不变

②类名样式操作

element.className = [CSS类名]

这种是直接修改元素的 CSS 类名,适用于大量修改样式的情况,如下示例:

实现一个页面,点击页面背景变成黑色,再次点击变成白色,达到夜间白天模式切换的效果

<div class="container light">你好 <br>你好鸭 <br>你也好 <br>你也好呀 <br>
</div>
<style>* { margin: 0;padding: 0;}html, body {width: 100%;height: 100%;}.container {width: 100%;height: 100%;}.light {background-color: #f3f3f3;color: #333;}.dark {background-color: #333;color: #f3f3f3;}
</style>
<script>var div = document.querySelector('div');div.onclick = function () {console.log(div.className);if (div.className.indexOf('light') != -1) {div.className = 'container dark';}else {div.className = 'container light';}}
</script>

四,操作节点

4.1 新增节点

4.4.1 创建元素节点

创建节点语法如下:

var element = document.createElement(tagName[, options]); //options参数暂不关注

示例如下:

<div class="container"></div>
<script>var div = document.createElement('div');div.id = 'hello';div.className = 'hi';div.innerHTML = 'hei!';console.log(div);
</script>

可以看到,虽然创建出了新的 div,console.log 也能打印日志,但是没有在页面上显示出来,这是因为新创建的节点还没有加入到DOM树中

除了createElement外,还有:

  • createTextNode 创建文本节点
  • createComment 创建注释节点
  • createAttribute 创建属性节点

4.4.2 插入节点到 DOM 树中

①使用appendChild 将节点插入到指定节点的最后一个孩子之后

element.appendChild(aChild)
<div class="container"></div>
<script>var div = document.createElement('div');div.id = 'hello';div.className = 'hi';div.innerHTML = 'hei!';var container = document.querySelector('.container');container.appendChild(div);
</script>

②使用 insertBefore 将节点插入到指定节点之前 

var insertedNode = parentNode.insertBefore(newNode, referenceNode);
  • insertedNode:被插入节点,要将 newNode 插入
  • parentNode:新插入节点的父节点
  • newNode:用于插入的节点
  • referenceNode:newNode 将要插在这个节点之前
  • 如果 referenceNode 为 null,则将 newNode 插入到子节点的末尾
<div class="container"><div>111</div><div>222</div><div>333</div><div>444</div>
</div>
<script>var newdiv1 = document.createElement('div');var newdiv2 = document.createElement('div');newdiv1.innerHTML = '你好';newdiv2.innerHTML = '你好鸭';var container = document.querySelector('.container');console.log(container.children);container.insertBefore(newdiv1, container.children[0]);container.insertBefore(newdiv2, container.children[3]);
</script>

  • 如果针对一个节点插入两次,则只会生效一次(相当于把元素移动了) 
  • 一旦一个节点插入完毕,再对相同的节点对象插入,就能同步影响 DOM 树中的内容
  • 比如上面示例中,我们先在 111 前面插入 “你好”,这样再在下标为3的地方擦汗如,就不是在 444 前面插入了,而是在 333 前面插入

4.2 删除节点

oldChild = element.removeChild(child);

 就以上面的示例为例,把“你好” 和 “你好鸭” 删除了 

<div class="container"><div>111</div><div>222</div><div>333</div><div>444</div>
</div>
<script>var newdiv1 = document.createElement('div');var newdiv2 = document.createElement('div');newdiv1.innerHTML = '你好';newdiv2.innerHTML = '你好鸭';var container = document.querySelector('.container');console.log(container.children);container.insertBefore(newdiv1, container.children[0]);container.insertBefore(newdiv2, container.children[3]);container.removeChild(container.children[3]);container.removeChild(container.children[0]);
</script>
  • 被删除的节点只是 从 DOM 树被移除了,但是在内存中依然存在,随时可以再次加入到 DOM 树的其它位置
  • 如果要被删除的 child 节点不存在,则会抛出异常

相关文章:

  • 文件上传功能uploadify.js报updateSettings is not a function
  • EasyRTC嵌入式音视频通信SDK一对一音视频通信,打造远程办公/医疗/教育等场景解决方案
  • 【RabbitMQ】记录 InvalidDefinitionException: Java 8 date/time type
  • 超低延迟音视频直播技术的未来发展与创新
  • 数据库健康监测器(BHM)实战:如何通过 HTML 报告识别潜在问题
  • 深入理解万维网:URL、HTTP与HTML
  • 第16天-使用Python Pillow库常见图像处理场景
  • 如何使用Antv X6使用拖拽布局?
  • anaconda创建环境出错HTTPS
  • 每日Prompt:实物与手绘涂鸦创意广告
  • 【HTML-4】HTML段落标签:构建内容结构的基础
  • MySQL备份恢复:数据安全的终极指南
  • RPC 协议详解、案例分析与应用场景
  • 将VMware上的虚拟机和当前电脑上的Wifi网卡处在同一个局域网下,实现同一个局域网下实现共享
  • Neo4j实现向量检索
  • 【专题】机器学习期末复习资料
  • 【机器学习】支持向量机(SVM)
  • 华为鸿蒙电脑发布,折叠屏怎么选?
  • ToDesk云电脑、并行智算云与顺网云AI支持能力深度实测报告
  • 深度解析 Java 中介者模式:重构复杂交互场景的优雅方案
  • 运营网站/广州seo黑帽培训
  • 外贸建站 台州/企业整站推广
  • 做网站旅游销售/公司网站建设哪个好
  • 网站被主流搜索引擎收录的网页数量是多少/网店运营
  • 网站建设社会效益/镇江百度公司
  • 日本a片女人和狗做的网站/seo搜索引擎推广