一三四——一六七
一三四、JavaScript——_DOM简介
MDNq前端参考文档:DOM 概述 - Web API 接口参考 | MDN (mozilla.org)
一三五、JavaScript——HelloWorld
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><button id="btn">点我一下</button><script>/*要使用DOM来操作网页,我们需要浏览器至少先给我一个对象才能去完成各种操作所以浏览器已经为我们提供了一个document对象,它是一个全局变量可以直接使用document代表的是整个网页*/// 打印document 和在控制台中访问document.window效果是一样的console.log(document)// 获取btn对象,获取id为"btn"的元素const btn = document.getElementById("btn")//console.log(btn)// 修改btn中的文字,通过innerText修改即可btn.innerText = "Click ME"</script></body>
</html>
// 打印document 和在控制台中访问document.window效果是一样的console.log(document)
// 获取btn对象,获取id为"btn"的元素const btn = document.getElementById("btn")//console.log(btn)
// 修改btn中的文字,通过innerText修改即可btn.innerText = "Click ME"
一三六、JavaScript——文件节点
document的整个原型链:
MDN前端参考文档关于Document的部分:https://developer.mozilla.org/zh-CN/docs/Web/API/Document
document对象
- document对象表示的是整个网页
- document对象的原型链
本身 -> 父类 -> 父类的父类 -> 父类的父类的父类 -> 父类的父类的父类 ->父类的父类的父类的父类
HTMLDocument -> Document -> Node -> EnventTarget -> Object.prototype ->null
- 凡是在原型链上存在的对象的属性和方法都可以通过Document去调用
- 部分属性:
document.documentElement -- > html根元素
document.head -- > head元素
document.title -- > title元素
document.link -- > 获取页面中所有的超链接
...
一三七、JavaScript——获取元素节点
// 获取body标签以及body标签内的内容console.log(document.body)
<button id="btn">点我一下</button><script>// 通过id获取按钮const btn = document.getElementById("btn")console.log(btn)</script>
元素节点对象(element)
- 在网页中,每一个标签都是一个元素节点
- 如何获取元素节点对象
1. 通过document对象来获取元素节点
2. 通过document创建元素节点
- 通过document获取已有的元素节点对象
document.getElementById()
- 根据id获取一个元素节点对象(只能获取一个,因为id是不能重复的)
document.getElementsByClassName()
- 根据元素的class属性获取一组元素节点对象
document.getElementsByClassName()
- 根据元素的class属性值获取一组元素节点对象
- 返回的是一个类数组对象
- 该方法返回的结果是一个实时更新的集合
当网页中新添加元素时,集合也会实时的刷新
document.getElementsByTagName()
- 根据标签名获取元素节点对象
- 返回的结果是实时更新的集合
- document.getElementsByTagName("*"): 获取页面中的所有元素
document.querySelectorAll()
- 根据选择器去页面中查询元素
- 会返回一个数组(不会实时更新)
document.querySelector()
- 根据选择器去页面中查询第一个符合条件的元素
<body><button id="btn">点我一下</button><span class="s1">我是pan</span><span class="s1">我是span</span><span class="s1">我是span</span><span class="s1">我是span</span><span class="s1">我是span</span><div>我是div</div><div>我是div</div><div>我是div</div><div>我是div</div><div>我是div</div><form><input type="text" name="username"><input type="radio" name="gender" value="男"><input type="radio" name="gender" value="女"></form><script>/*元素节点对象(element)- 在网页中,每一个标签都是一个元素节点- 如何获取元素节点对象1. 通过document对象来获取元素节点2. 通过document创建元素节点- 通过document获取已有的元素节点对象document.getElementById()- 根据id获取一个元素节点对象(只能获取一个,因为id是不能重复的)document.getElementsByClassName()- 根据元素的class属性获取一组元素节点对象document.getElementsByClassName()- 根据元素的class属性值获取一组元素节点对象- 返回的是一个类数组对象- 该方法返回的结果是一个实时更新的集合当网页中新添加元素时,集合也会实时的刷新document.getElementsByTagName()- 根据标签名获取元素节点对象- 返回的结果是实时更新的集合- document.getElementsByTagName("*"): 获取页面中的所有元素document.querySelectorAll()- 根据选择器去页面中查询元素- 会返回一个数组(不会实时更新)document.querySelector()- 根据选择器去页面中查询第一个符合条件的元素*/// 获取body标签以及body标签内的内容console.log(document.body)// 通过id获取按钮const btn = document.getElementById("btn")console.log(btn)// 通过Class的id的name获取span的内容const spans = document.getElementsByClassName("s1")// 遍历span标签的内容for(let i=0; i<spans.length; i++){//将内容都改为“哈哈哈”spans[i].innerText = "哈哈哈"+ i}console.log(spans)// 根据标签名div获取元素节点对象const divs = document.getElementsByTagName("div")// 获取页面中的所有元素const tagName = document.getElementsByTagName("*")console.log(tagName)// 针对form表单中的inputconst genderInput = document.getElementsByName("gender")console.log(genderInput)// 获取所有标签元素为div的const divs2 = document.querySelectorAll("div")// 打印的是一个集合 NodeList(5) [div, div, div, div, div]console.log(divs2)// 获取标签元素为div的,取单个的,一般情况就取第一个const divs3 = document.querySelector("div")// 在控制台直接打印div,点击显示的是第一个div标签</script></body>
一三八、JavaScript——元素的属性和方法
通过元素节点对象获取其他的节点的方法
element.childNodes 获取当前元素的子节点(会包含空白的节点)
子节点包括:文本节点、标签节点等,
标签节点后还有空白节点,所以算两个节点,而文本节点后的空白节点是被文本节点一起包含的
element.children 获取当前元素的子元素
element.firstElementChild 获取当前元素第一个子元素
element.lastElementChild 获取当前元素第一个子元素
element.nextElementSibling 获取当前元素的下一个兄弟元素
element.previousElementSibling 获取当前元素的前一个兄弟元素
element.parentNode 获取当前元素的父节点
element.tagName 获取当前元素的标签名
<body><div id="box1">我是box1<span class="s1">我是s1</span><span class="s1">我是s1</span></div><span class="s1">我是s1</span><script>/*div元素的原型链HTMLDivElement -> HTMLElement -> Elemnet -> Node -> ---通过元素节点对象获取其他的节点的方法element.childNodes 获取当前元素的子节点(会包含空白的节点)子节点包括:文本节点、标签节点等,标签节点后还有空白节点,所以算两个节点,而文本节点后的空白节点是被文本节点一起包含的element.children 获取当前元素的子元素element.firstElementChild 获取当前元素第一个子元素element.lastElementChild 获取当前元素第一个子元素element.nextElementSibling 获取当前元素的下一个兄弟元素element.previousElementSibling 获取当前元素的前一个兄弟元素element.parentNode 获取当前元素的父节点element.tagName 获取当前元素的标签名*/// 获取id为box1的标签。通过documnet去调,则是通过整个网页范围内查找const box1 = document.getElementById("box1")//console.log(box1)// 通过box1去调,调用的范围只在box1的标签名内查找const spans = box1.getElementsByTagName("span")// 打印结果为2,name为box1的标签内的span标签数量为2console.log(spans)// 标签节点后还有空白节点,所以算两个节点,而文本节点后的空白节点是被文本节点一起包含的。算一个const cns = box1.childNodes// 结果为5,说明节点数为5// 文本节点一个 标签节点两个 标签节点后的空白节点两个 共5个console.log(cns)</script></body>
一三九、JavaScript——文本节点
<body><img src="" alt=""><!-- "我是div"在这里就是一个文本节点 --><div id="box1"><span>我是box1</span></div><script>/*在DOM中,网页中的所有文本内容都是文本对象可以通过元素来获取其中的文本节点对象,但是我们通常不会这么做我们可以直接通过元素去修改其中的文本修改文本的三个属性element.textContent 获取或修改元素中的文本内容- 获取的是标签中的内容,不会考虑css样式- 不考虑样式就是本来的文本是大写,但通过textContent拿到的就是小写element.innerText 获取或修改元素中的文本内容- innerText获取内容时,会考虑css样式- 考虑样式就是本来的文本是大写,但通过innerText拿到的就是大写,保留原有样式- 当字符串中有标签时,会自动对标签进行转义,并不是真正的字符element.innerHTML 获取或修改HTML中的代码- 可以直接向元素中添加HTML代码- innerHTML插入内容时,有被xss注入的风险*/// 先通过id获取到标签的内容const box1 = document.getElementById("box1")// 通过element.textContent修改文本内容// box1.textContent = "新的内容"</script></body>
一四零、JavaScript——属性节点
属性节点(Attr)
- 在DOM中也是一个对象,通常不需要获取对象而是直接通过元素即可完成对其的各种操作
- 如何操作属性节点:
方式一:
读取:元素.属性名(注意:class属性需要用className来读取)
读取一个布尔值时,会返回true或false
修改: 元素.属性名 = 属性值
方式二:
读取:元素.getAttribute(属性名)
修改:元素.setAttribute(属性名,属性值)
删除:元素.removeAttribute(属性名)
<body><input type="text" name="username" value="admin"><script>/*属性节点(Attr)- 在DOM中也是一个对象,通常不需要获取对象而是直接通过元素即可完成对其的各种操作- 如何操作属性节点:方式一: 读取:元素.属性名(注意:class属性需要用className来读取)读取一个布尔值时,会返回true或false修改: 元素.属性名 = 属性值方式二:读取:元素.getAttribute(属性名) 修改:元素.setAttribute(属性名,属性值)删除:元素.removeAttribute(属性名)*/// getElementsByName 因为获取的是Elements,要想获取一个需要加一个索引[0]const input = document.getElementsByName("username")[0]// 打印内容为:<input type="text" name="username" value="admin">console.log(input)const input1 = document.querySelector("[name=username]")console.log(input)// 修改:元素.setAttribute(属性名,属性值)input.setAttribute("value","孙悟空")</script></body>
一四一、JavaScript——事件
事件(event)
- 事件就是用户和页面之间发生的交互行为
比如:点击按钮、鼠标移动、双击按钮、敲击键盘、松开键盘...
- 可以通过为事件绑定响应函数(回调函数),来完成用户之间的交互
- 绑定响应函数的方式
1. 可以直接在元素的属性中设置
2. 可以通过为元素的指定属性设置回调函数的形式来绑定事件
3. 可以通过元素addEventListener()方法来绑定事件
<body><!-- ondblclick指双击按钮跳出弹框 --><!-- <button id="btn" ondblclick="alert('你点我干嘛')">点我一下</button> --><button id="btn">点我一下</button><script>/*事件(event)- 事件就是用户和页面之间发生的交互行为比如:点击按钮、鼠标移动、双击按钮、敲击键盘、松开键盘...- 可以通过为事件绑定响应函数(回调函数),来完成用户之间的交互- 绑定响应函数的方式1. 可以直接在元素的属性中设置2. 可以通过为元素的指定属性设置回调函数的形式来绑定事件3. 可以通过元素addEventListener()方法来绑定事件*/// 1.获取到按钮对象const btn = document.getElementById("btn")// 2.为按钮对象的事件属性设置响应函数,即点击了就会响应btn.onclick = function(){alert("点击按钮后调用的函数")}// 设置了新的绑定之后,新的绑定会将旧的绑定覆盖btn.onclick = function(){alert("设置新的绑定")}// 3. 通过元素addEventListener()方法来绑定事件btn.assEventListener("click", function(){alert("哈哈哈")})// 不会被覆盖,按顺序依次出现btn.assEventListener("click", function(){alert("嘻嘻嘻")})</script>
</body>
一四二、JavaScript——文档的加载
- 网页是自上而下加载的,如果将js代码编写到网页的上边(button按钮的上面
- js代码在执行时候,网页还没有加载完毕,这时候会出现无法获取到DOM对象的情况
window.onload 事件会在窗口中的内容加载完毕之后才触发
- 会等待所有文档都加载完成才会触发
document对象的DOMContentLoaded事件会在窗口中的内容加载完成之后才会触发
- 当前文档加载完成就触发
如何解决这个问题:
1. 将script标签写到body标签的最后的位置
2. 将代码编写到window.onload的回调函数中,因为window.onload的回调函数是最后执行的,所以此时script可以放在任意位置,只要放在里面就可以最后执行
3. 将代码编写到document对象的DOMContentLoaded的回调函数中(执行的时机早)
4. 将代码编写到外部的js文件中,然后以defer的形式引入(执行的时机更早,早于DOMContentLoaded)
开发过程中常用1,引外部文件时常用4
<body><button id="btn">点我一下</button><script>/*网页是自上而下加载的,如果将js代码编写到网页的上边(button按钮的上面)js代码在执行时候,网页还没有加载完毕,这时候会出现无法获取到DOM对象的情况window.onload 事件会在窗口中的内容加载完毕之后才触发- 会等待所有文档都加载完成才会触发document对象的DOMContentLoaded事件会在窗口中的内容加载完成之后才会触发- 当前文档加载完成就触发如何解决这个问题:1. 将script标签写到body标签的最后的位置2. 将代码编写到window.onload的回调函数中,因为window.onload的回调函数是最后执行的,所以此时script可以放在任意位置,只要放在里面就可以最后执行3. 将代码编写到document对象的DOMContentLoaded的回调函数中(执行的时机早)4. 将代码编写到外部的js文件中,然后以defer的形式引入(执行的时机更早,早于DOMContentLoaded)开发过程中常用1,引外部文件时常用4*/// 可以放在任意位置,因为window.onload的回调函数总在最后执行// window.onload() = function(){// const btn = document.getElementById("btn")// console.log(btn)// }// document对象的DOMContentLoaded的回调函数,只能通过 document.addEventListener调用document.addEventListener("load", function (){const btn = document.getElementById("btn")console.log(btn)})const btn = document.getElementById("btn")console.log(btn)</script><!-- 代码编写到外部的js文件中,然后以defer的形式引入 --><!-- <script defer src="链接"></script> -->
一四六、JavaScript——元素的修改
appendChild() 用于给节点添加一个子节点
insertAdjacentElement(添加的位置,要添加的元素) 可以向元素任意位置添加元素i
添加的位置:
beforeend:标签的最后
afterbegin:标签的开始
beforebeing:与标签处于同级,在标签的前边插入元素(兄弟元素)
afterend:与标签处于同级,在标签的后边插入元素(兄弟元素)
insertAdjacentHTML("插入的位置", "插入的标签")
replaceWith("参与替换掉的元素")
remove() 方法来删除元素
<body><button id="btn01">按钮01</button><button id="btn02">按钮02</button><hr><ul id="list"><li id="swk">孙悟空</li><li id="zbj">猪八戒</li><li id="shs">沙和尚</li></ul><script>/*点击按钮后,向ul中添加一个唐僧*/// 获取ulconst list = document.getElementById("list")// 获取按钮const btn01 = document.getElementById("btn01")const btn02 = document.getElementById("btn02")btn01.onclick = function() {// 创建一个liconst li = document.createElement("li")// 向li中添加文本li.textContent = "唐僧"// 给li添加id属性li.id = "ts"// // appendChild() 用于给节点添加一个子节点// list.appendChild(li)// console.log(list)// insertAdjacentElement(添加的位置,要添加的元素)可以向元素任意位置添加元素i// 两个参数:1.添加的位置 2.要添加的元素/*添加的位置:beforeend:标签的最后afterbegin:标签的开始beforebeing:与标签处于同级,在标签的前边插入元素(兄弟元素)afterend:与标签处于同级,在标签的后边插入元素(兄弟元素)*/list.insertAdjacentElement("afterbegin",li)// insertAdjacentHTML("插入的位置", "插入的标签")list.insertAdjacentHTML("", "<li id='bgj'>白骨精</li>")}btn02.onclick = function() {// 创建一个蜘蛛精替换孙悟空const li = document.createElement("li")li.textContent = "蜘蛛精"li.id = "zzj"// 获取孙悟空const swk = document.getElementById("swk")// replaceWith() 使用一个元素替换当前元素// replaceWith("参与替换掉的元素")swk.replaceWith(li)// remove() 方法来删除元素swk.remove()}</script>
</body>
一五零、JavaScript——节点的复制
涉及的方法
添加:list.appendChild(l1)
将l1添加到list中
复制:const newL1 = li.cloneNode(true)
复制l1和l1下的子节点,l1标签里的文本节点就属于l1的子节点
<body><button id="btn01">点我一下</button><ul id="list1"><li id="l1">孙悟空</li><li id="l2">猪八戒</li><li id="l3">孙悟空</li></ul><ul id="list2"><li >蜘蛛精</li></ul><script>/*涉及的方法添加:list.appendChild(l1)将l1添加到list中复制:const newL1 = li.cloneNode(true)复制l1和l1下的子节点,l1标签里的文本节点就属于l1的子节点*//*点击按钮后,将id为l1的元素添加到list2中*/// 先获取按钮const btn01 = document.getElementById("btn01")const list2 = document.getElementById("list2")const l1 = document.getElementById("l1")// 点击按钮触发的函数btn01.onclick = function() {/*使用 cloneNode()方法对节点进行复制时,它会复制节点的所有特点包括各种属性这个方法只会默认复制当前节点,即只复制标签节点,不会复制文本节点,可以传递一个true作为参数,这样该方法也会将元素的子节点一起复制*/const newL1 = li.cloneNode(true) // 用来对节点进行复制// 防止id完全重复,重新赋值一个id即可newL1.id = "newL1"// 利用appendChild,点击按钮后,将l1添加到list2中去list2.appendChild(l1)}</script></body>
一五一、JavaScript——修改css样式
在stylE标签中,
在样式的结尾在结尾加 !important
表示优先级最高,最先执行
background-color: #4ead56 !important;
修改样式的方式: 元素.style.样式名 = 样式值
如果样式名中含有"-",例如"background-color"则需要将样式表修改为驼峰命名法"backgroundColor"
"background-color" -> "backgroundColor"
<style>.box1 {width: 200px;height: 200px;background-color: #4ead56 !important;/* 在stylE标签中,在样式的结尾在结尾加 !important表示优先级最高,最先执行background-color: #4ead56 !important;*/}</style></head>
<body><button id="btn">点我一下</button><hr /><div class="box1"></div><script>/*点击按钮后,修改box1的宽度*/const btn = document.getElementById("btn")// querySelector方法:选中页面中出现的第一个标签const box1 = document.querySelector(".box1")// 点击按钮触发的函数btn.onclick = function() {// 修改.box1的样式// 修改样式的方式: 元素.style.样式名 = 样式值box1.style.width = "600px"box1.style.height = "600px"// 如果样式名中含有"-",例如"background-color"则需要将样式表修改为驼峰命名法"backgroundColor"// "background-color" -> "backgroundColor"box1.style.backgroundColor = "yellow"; }</script>
</body>
一五二、JavaScript——读取样式
getComputedStyle()
-它会返回一个对象,这个对象中包含了当前元素的所有生效的样式
- 获取具体的样式数值:对象.width 获取样式的宽度
- 伪元素获取样式信息:getComputedStyle(要获取的样式对象, "要获取的为元素")
宽度以及高度的计算:
- 一般通过: "对象.width" 读取样式宽度时,都是带宽度的
- 通过 parseInt(对象.width)将 200px 中的px消除
- 再通过 + "px" 的方式加上单位
返回值
- 返回的一个对象,对象中存储了当前元素的样式
注意
- 样式对象中返回的样式值,不一定能拿来直接计算,有可能是auto
所以使用时,一定要确保值偶是可以计算的才去计算
<style>.box1 {width: 200px;height: 200px;background-color: #4ead56 !important;/* 在stylE标签中,在样式的结尾在结尾加 !important表示优先级最高,最先执行background-color: #4ead56 !important;*/}/* 伪元素*/.box1::before {content: "hello";color:red;}</style></head>
<body><button id="btn">点我一下</button><hr /><div class="box1"></div><script>/*点击按钮后,读取css的样式*/const btn = document.getElementById("btn")// querySelector方法:选中页面中出现的第一个标签const box1 = document.querySelector(".box1")// 点击按钮触发的函数btn.onclick = function() {// 不会用这种方式来读取样式// console.log(box1.style.width)/*getComputedStyle()-它会返回一个对象,这个对象中包含了当前元素的所有生效的样式- 获取具体的样式数值:对象.width 获取样式的宽度- 伪元素获取样式信息:getComputedStyle(要获取的样式对象, "要获取的为元素")宽度以及高度的计算:- 一般通过: "对象.width" 读取样式宽度时,都是带宽度的- 通过 parseInt(对象.width)将 200px 中的px消除- 再通过 + "px" 的方式加上单位返回值- 返回的一个对象,对象中存储了当前元素的样式注意- 样式对象中返回的样式值,不一定能拿来直接计算,有可能是auto所以使用时,一定要确保值偶是可以计算的才去计算*/const styleObj = getComputedStyle(box1)// 获取为元素的样式信息const beforeObj = getComputedStyle(box1, "before")// 通过 parseInt(对象.width)将 200px 中的px消除 // 再通过 + "px" 的方式加上单位parseInt(styleObj.width) + 100 + "px"// 获取元素的样式console.log(styleObj.width)}</script>
</body>
一五三、JavaScript——通过属性读取样式
元素.clientHeight
元素.clientWidth
- 获取元素内部的宽度和高度(包括内容区和内边距,width和padding)
- 返回的结果就是纯数字,不带单位
元素.offsetHeight
元素.offsetWidth
- 获取元素的可见框的大小(包括内容区、内边距和边框)
- 返回的结果就是纯数字,不带单位
元素.scrollHeight
元素.scrollWidth
- 获取元素滚动区域的大小
元素.offsetParent
- 获取元素定位的父元素
- 定位父元素,离当前元素最近的开启了定位的祖先元素
如果所有的元素都没有开启定位则返回body
元素.offsetTop
元素.offsetLeft
- 获取元素相对于起定位父元素的偏移量
<style>#box1 {width: 200px;height: 200px;padding: 50px;margin: 50px;border: 10px red solid;background-color:aqua;/* 设置多余的部分溢出, */overflow: auto;}#box2 {width: 100px;height: 500px;background-color:chartreuse;}</style></head>
<body><button id="btn">点我一下</button><hr><div id="box1"><div id="box2"></div></div><script>const btn = document.getElementById("btn")const box1 = document.getElementById("box1")btn.onclick = function() {/*元素.clientHeight元素.clientWidth- 获取元素内部的宽度和高度(包括内容区和内边距,width和padding)- 返回的结果就是纯数字,不带单位元素.offsetHeight元素.offsetWidth- 获取元素的可见框的大小(包括内容区、内边距和边框)- 返回的结果就是纯数字,不带单位元素.scrollHeight元素.scrollWidth- 获取元素滚动区域的大小元素.offsetParent- 获取元素定位的父元素- 定位父元素,离当前元素最近的开启了定位的祖先元素如果所有的元素都没有开启定位则返回body元素.offsetTop元素.offsetLeft- 获取元素相对于起定位父元素的偏移量*/}console.log(box1.clientWidth)</script>
</body>
一五四、JavaScript——操作class
- 元素.classList.add(class名称,class名称) :向元素中添加一个或多个class
元素.classList.remove(class名称) :删除一个或多个class
元素.classList.toggle(class名称) :切换class
元素.classList.replace(class1, class2) :1去掉class1,替换成class2
box1.classList.contains("box1"): 判断是否含有某个class
<body><button id="btn">点我一下</button><hr /><div class="box1"></div><script>const btn = document.getElementById("btn")// querySelector取网页中第一次出现的标签const box1 = document.querySelector(".box1")btn.onclick = function() {/*除了直接修改样式外,也可以通过修改class属性来简介修改样式被替换的.className += " 具体替换的" 注意具体替换的前有空格box1.className += " box2"*/// box1.className += " box2"/*元素.classList.add(class名称,class名称) :向元素中添加一个或多个class元素.classList.remove(class名称) :删除一个或多个class元素.classList.toggle(class名称) :切换class元素.classList.replace(class1, class2) :1去掉class1,替换成class2box1.classList.contains("box1"): 判断是否含有某个class*/// 元素.classList 是一个对象,对象中提供了对当前元素的类的各种操作方法box1.classList.add(box2)box1.classList.remove(box2)box1.classList.toggle("box2")// 把1去掉替换成2box1.classList.replace("box1","box2")// 检查是否包含box1.classList.contains("box1")}</script>
</body>
一五五、JavaScript——事件对象简介
event 事件
- 事件对象
- 事件对象是由浏览器在事件触发时所创建的对象
这个对象中封装了事件相关的各种信息
- 通过事件对象可以获取到事件的详细信息
比如:鼠标的坐标,键盘的按键
- 浏览器在创建事件对象后,会将事件作为响应函数的参数传递
所以我们可以在事件的回调函数中定义一个形参来接收事件对象
<style>#box1 {width: 300px;height: 300px;border: 10px greenyellow solid;}</style>
</head>
<body><div id="box1"></div><script>/*event 事件- 事件对象- 事件对象是由浏览器在事件触发时所创建的对象这个对象中封装了事件相关的各种信息- 通过事件对象可以获取到事件的详细信息比如:鼠标的坐标,键盘的按键- 浏览器在创建事件对象后,会将事件作为响应函数的参数传递所以我们可以在事件的回调函数中定义一个形参来接收事件对象*/// onmousemove鼠标移动事件// box1.onmousemove = function() {// console.log("鼠标移动了")// }// 方式1:回调函数传入参数用来记录// box1.onmousemove = function(event) {// console.log(event)// }// 方式2:匿名函数传入形参命名为event// box1.onmousemove = event => {// console.log(event)// }const box1 = document.getElementById("box1")// addEventListener("事件", 函数)box1.addEventListener("mousemove", event => {// console.log(event)// 打印鼠标的坐标console.log(event.clientX, event.clientY)// 让鼠标坐标显示在网页中box1.textContent = event.clientX + "," +event.clientY})</script>
</body>
一五六、JavaScript——event对象
MDN前端参考文档:Event - Web APIs | MDN (mozilla.org)
在DOM中存在着多种不同类型的事件对象
- 多种事件对象有一个共同的祖先 Event
- event.target 触发事件的对象
- event,currentTarget 绑定事件的对象(问this)
- event.stopPropaggation() 停止事件的向上传导
- event.preventDefault() 取消默认行为
- 事件的冒泡(bubble)
- 事件的冒泡就是指事件的向上传导
- 当元素的某个事件被触发后,其祖先元素上的相同元素也会被触发
- 冒泡的存在大大简化了代码的编写,但在一些场景下我们并不希望冒泡存在
<style>#box1 {width: 300px;height: 300px;background-color: antiquewhite;}</style>
</head>
<body><div id="box1"></div><script>/*在DOM中存在着多种不同类型的事件对象- 多种事件对象有一个共同的祖先 Event- event.target 触发事件的对象- event,currentTarget 绑定事件的对象(问this)- event.stopPropaggation() 停止事件的向上传导- event.preventDefault() 取消默认行为- 事件的冒泡(bubble)- 事件的冒泡就是指事件的向上传导- 当元素的某个事件被触发后,其祖先元素上的相同元素也会被触发- 冒泡的存在大大简化了代码的编写,但在一些场景下我们并不希望冒泡存在*/// 获取box1const box1 = document.getElementById("box1")// addEventListener("事件", "函数")box1.addEventListener("click", event => {// alert(event)// console.log(event)/*在事件的响应函数中:event.target 表示的是触发事件的对象,由谁引发的事件就显示谁*/// 打印 <div id="box1"></div>;因为是由于box1触发的console.log(event.target)})</script>
</body>
一五七、JavaScript——事件的冒泡
<style>#box1{width: 100px;height: 100px;background-color: cornflowerblue;border-radius: 50%;position: absolute;}#box2{width: 500px;height: 500px;background-color: coral;}#box3{width: 200px;height: 200px;background-color: aqua;}#box4{width: 100px;height: 100px;background-color: brown;}</style>
</head>
<body><div id="box1"></div><!-- 创建一个box2 --><div id="box2"></div><div id="box3" onclick="alert(3)"><div id="box4" onclick="alert(4)"></div></div><script>/*使小绿球可以跟鼠标一起移动事件的冒泡和元素的样式无关,只和结构有关*/const box1 = document.getElementById("box1")const box2 = document.getElementById("box2")// 绑定鼠标移动事件,并传入形参event// 并且绑定在整个界面上,而不是box1上document.addEventListener("mousemove", (event) => {// console.log(111)// 图标跟随鼠标移动box1.style.left = event.x + "px"box1.style.top = event.y + "px"})// 取消box2的事件的冒泡box2.addEventListener("mousemove", (event) => {// 取消事件的冒泡,这样再box2的区域小球就不会随着鼠标移动event.stopPropagation()})</script></body>
一五八、JavaScript——事件的委派
<body><button id="btn">点我一下</button><hr><ul id="list"><li><a href="javascript:;">链接1</a></li><li><a href="javascript:;">链接2</a></li><li><a href="javascript:;">链接3</a></li><li><a href="javascript:;">链接4</a></li></ul><script>// 获取所有为ul标签中的a标签const links = document.querySelectorAll("ul a")// 获取list标签const list = document.getElementById("list")const btn = document.getElementById("btn")for(let i=0; i<links.length; i++) {links[i].addEventListener("click", event => {alert(event.target.textContent)})}// 点击按钮后,在ul中新增一个libtn.addEventListener("click", () => {// 通过insertAdjacentHTML("插入的位置", "插入的内容") 直接插入标签list.insertAdjacentHTML("beforeend", "<li><a href='javascript:;'>新超链接</a></li>")})/*上面虽然实现了点击按钮新增链接的功能,但还经历了遍历和点击添加的,我一个希望只绑定一次事件,即可以让所有的超链接,包括当下和未来的超链接都具有这些事情思路:可以将事件统一绑定给document,这样点击超链接时由于事件的冒泡会导致document上的点击事件被触发,这样只绑定依次,所有的超链接都会具有这些事件委派就是将本该绑定多个元素的的事件,统一绑定给一个共同事件*/// 获取list中的所有链接const linkes = list.getElementsByTagName("a")// 将点击事件扩大到整个网页,即对象是documentdocument.addEventListener("click", (event) => {// 在执行代码前,判断一下事件是由谁来触发// 检查event.target 是否在 links 中存在// 但link打印出来是 "HTMLCollection [a,a,a,a]" 我们需要的是数组// 调用静态方法 Arrary.form(linkes) 后,数组变为[a,a,a,a]// 或者直接用展开运算符展开[...linkes] 效果是一样的// 判断如果触发事件在linkes中出现了if([...links].includes(event.target)) {// 点击事件触发后显示触发的文本 alert(event.target.textContent)}}) </script></body>
一六零、JavaScript——事件的捕获
事件的传播机制:
- 在DOM中,事件的传播可以分为三个阶段:
1.捕获阶段 (由祖先元素向目标元素进行事件的捕获)(默认情况下,事件不会在捕获阶段触发)
2.目标阶段 (触发事件的对象)
3.冒泡阶段 (由目标元素向祖先元素的进行事件的冒泡)
- 事件的捕获,指事件从外向内的传导
捕获是从外向里捕获
冒泡是由里向外捕获
当我们当前元素的触发事件以后,会先从当前元素的最大祖先元素开始事件的捕获
- 如果希望在捕获阶段触发事件,可以将addEventListener的第三个参数设置为true
一般情况下我们不希望事件在捕获阶段触发,所以通常不需要设置addEventListener第三个参数为true
eventPhase 表示事件触发的阶段,结果是数字
1 表示捕获阶段 2 表示目标阶段 3 表示冒泡阶段
<style>#box1 {width: 300px;height: 300px;background-color: aquamarine;}#box2 {width: 200px;height: 200px;background-color:crimson}#box3 {width: 100px;height: 100px;background-color:darkblue;}</style>
</head>
<body><div id="box1"><div id="box2"><div id="box3"></div></div></div><script>/*事件的传播机制:- 在DOM中,事件的传播可以分为三个阶段:1.捕获阶段 (由祖先元素向目标元素进行事件的捕获)(默认情况下,事件不会在捕获阶段触发)2.目标阶段 (触发事件的对象)3.冒泡阶段 (由目标元素向祖先元素的进行事件的冒泡)- 事件的捕获,指事件从外向内的传导捕获是从外向里捕获冒泡是由里向外捕获当我们当前元素的触发事件以后,会先从当前元素的最大祖先元素开始事件的捕获- 如果希望在捕获阶段触发事件,可以将addEventListener的第三个参数设置为true一般情况下我们不希望事件在捕获阶段触发,所以通常不需要设置addEventListener第三个参数为trueeventPhase 表示事件触发的阶段,结果是数字1 表示捕获阶段 2 表示目标阶段 3 表示冒泡阶段*/const box1 = document.getElementById("box1")const box2 = document.getElementById("box2")const box3 = document.getElementById("box3")box1.addEventListener("click", event => {alert(event.eventPhase) //eventPhase 表示事件触发的阶段},true)box2.addEventListener("click", event => {alert(2)})box3.addEventListener("click", event => {alert(3)})</script></body>
一六一、JavaScript——BOM简介
BOM
- 浏览器对象模型
- BOM为我们提供了一组对象,通过这组对象可以完成对浏览器的各种操作
- BOM对象
- Window —— 代表浏览器窗口(全局对象)
- Navigator —— 浏览器的对象(可以用来识别浏览器)
- Location —— 浏览器的地址栏信息
- History —— 浏览器的历史记录(控制浏览器前进后退)
- Screen —— 屏幕的信息
- BOM对象是作为window对象的属性保存的,所以可以直接在JS中访问这些对象
一六二、JavaScript——Navigator
- BOM对象
- MDN前端参考文档:https://developer.mozilla.org/en-US/docs/Web/API/Navigator
- Navigator —— 浏览器的对象(可以用来识别浏览器)
userAgent 返回一个用来描述浏览器信息的字符串
<body><script>/*- BOM对象- MDN前端参考文档:https://developer.mozilla.org/en-US/docs/Web/API/Navigator- Navigator —— 浏览器的对象(可以用来识别浏览器)userAgent 返回一个用来描述浏览器信息的字符串*/// console.log(navigator.userAgent)function getBrowserName(userAgent) {// The order matters here, and this may report false positives for unlisted browsers.if (userAgent.includes("Firefox")) {// "Mozilla/5.0 (X11; Linux i686; rv:104.0) Gecko/20100101 Firefox/104.0"return "Mozilla Firefox";} else if (userAgent.includes("SamsungBrowser")) {// "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36"return "Samsung Internet";} else if (userAgent.includes("Opera") || userAgent.includes("OPR")) {// "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 OPR/90.0.4480.54"return "Opera";} else if (userAgent.includes("Edge")) {// "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"return "Microsoft Edge (Legacy)";} else if (userAgent.includes("Edg")) {// "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 Edg/104.0.1293.70"return "Microsoft Edge (Chromium)";} else if (userAgent.includes("Chrome")) {// "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"return "Google Chrome or Chromium";} else if (userAgent.includes("Safari")) {// "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1"return "Apple Safari";} else {return "unknown";}
}const browserName = getBrowserName(navigator.userAgent);
console.log(`You are using: ${browserName}`);</script>
</body>
一六三、JavaScript——Location
location表示的是网站的地址栏的信息
- 可以直接将location的值修改为一个新的地址,这样会使得网页发生跳转
- location.assign() 跳转到一个新的地址 (可以通过回退按钮回退到原来的地址)
- location.replac() 跳转到一个新的地址 (无法通过回退按钮回退到原来的地址)
- location.reload() 刷新页面,可以传递一个true来强制清缓存刷新
- location.replac() 跳转到一个新的地址 (无法通过回退按钮回退到原来的地址)
- location.href 获取当前地址
一六四、JavaScript——History
MDN前端文档:https://developer.mozilla.org/en-US/docs/Web/API/History
history.back() 浏览器回退
history.forward() 浏览器前进
history.go() 可以向前跳转也可以向后跳转,取决于括号中输入的数字,正数向前,负数向后
<body><button id="btn">点我一下</button><script>const btn = document.getElement("btn")btn.onclick = () => {/*history.back() 浏览器回退istory.forward() 浏览器前进history.go() 可以向前跳转也可以向后跳转,取决于括号中输入的数字,正数向前,负数向后*/// 后退history.back()// 前进history.forward()// history.go()}</script>
</body>
一六五、JavaScript——定时器
通过定时器,可以是代码再指定时间后执行
- 设置定时器打方式有两种:
setTimeout() (只执行一次)
- 参数
1. 回调函数(要执行的代码)
2. 间隔的时间(毫秒)
clearTimeout()
- 关闭定时器
setInterval() (每隔一段时间就会执行依次)
- 参数:
1. 回调函数(要执行的代码)
2. 间隔的时间(毫秒)
clearInterval()
- 关闭定时器
<body><h1 id="num"></h1><script>/*通过定时器,可以是代码再指定时间后执行- 设置定时器打方式有两种:setTimeout() (只执行一次)- 参数1. 回调函数(要执行的代码)2. 间隔的时间(毫秒)clearTimeout()- 关闭定时器setInterval() (每隔一段时间就会执行依次)、- 参数:1. 回调函数(要执行的代码)2. 间隔的时间(毫秒)clearInterval()- 关闭定时器*/const timer = setTimeout(() => {alert("我是定时器中的代码")},1000)// 关闭定时器clearTimeout(timer)const numH1 = document.getElementById("num")let num = 0// 构建一个定时器,在指定时间不断生成数字并显示在H1标签中const timeres = setInterval(() => {num++numH1.textContent = num// 判断如果定时器的数字到200,则关闭定时器if(num === 200) {clearInterval(timeres)}},500)</script>
</body>
一六六、JavaScript——调用栈
时间循环(event loop)
- 函数在每次执行时,都会产生一个执行环境
- 执行环境负责存储函数执行的一切数据
- 问题:函数的执行环境要存储到哪里
- 函数执行环境存储到了一个叫做调用栈的地方
- 栈,是一种数据结构,特点:后进先出
调用栈(call stack)
- 调用栈负责存储函数的执行环境
- 当一个函数被调用时,它的执行环境会作为一个栈帧
插入到调用栈的栈项,函数执行完毕其他栈会自动从栈中弹出
调用栈中放的都是正在执行的函数
<script>/*时间循环(event loop)- 函数在每次执行时,都会产生一个执行环境- 执行环境负责存储函数执行的一切数据- 问题:函数的执行环境要存储到哪里- 函数执行环境存储到了一个叫做调用栈的地方- 栈,是一种数据结构,特点:后进先出调用栈(call stack)- 调用栈负责存储函数的执行环境- 当一个函数被调用时,它的执行环境会作为一个栈帧插入到调用栈的栈项,函数执行完毕其他栈会自动从栈中弹出调用栈中放的都是正在执行的函数*/function fn(){let a = 10;let b = 20;}</script>
一六七、JavaScript——消息队列
消息队列
- 队列,是一种数据结构, 特点:先进先出
- 当我们触发一个事件时,其响应函数并不是直接就添加到调用栈中的
因为调用栈中又可能会存在一些还没有执行完的代码
- 事件触发后,JS引擎是将事件响应函数插入到消息队列中排队
<script>/*时间循环(event loop)- 函数在每次执行时,都会产生一个执行环境- 执行环境负责存储函数执行的一切数据- 问题:函数的执行环境要存储到哪里- 函数执行环境存储到了一个叫做调用栈的地方- 栈,是一种数据结构,特点:后进先出调用栈(call stack)- 调用栈负责存储函数的执行环境- 当一个函数被调用时,它的执行环境会作为一个栈帧插入到调用栈的栈项,函数执行完毕其他栈会自动从栈中弹出调用栈中放的都是正在执行的函数消息队列- 队列,是一种数据结构, 特点:先进先出- 当我们触发一个事件时,其响应函数并不是直接就添加到调用栈中的因为调用栈中又可能会存在一些还没有执行完的代码- 事件触发后,JS引擎是将事件响应函数插入到消息队列中排队*/function fn() {let a = 10let b = 20function fn2() {console.log("fn2")}fn2()console.log("fn!")}fn()console.log(1111)const btn = document.getElementById("btn")btn.onclick = function() {console.log("按钮被点击了")}</script>