1.1 什么是DOM
什么是window
window:是一个全局对象, 代表浏览器中一个打开的窗口, 每个窗口都是一个window对象。
什么是document
document是window的一个属性, 这个属性是一个对象。
document代表当前窗口中的整个网页,document对象保存了网页上所有的内容, 通过document对象就可以操作网页上的内容。
文档对象模型( DOM, Document Object Model )主要用于对 HTML 文档的内容进行操作。
DOM 把 HTML 文档表达成一个节点树,通过对节点进行操作,实现对文档内容的添加、删除、修改、查找等功能。
DOM 节点就是 HTML 上所有的内容 ,包括 :
- 文档节点
- 元素节点(标签)
- 元素属性节点
- 文本节点
- 注释节点
节点图示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>节点概念</title>
</head>
<body>
<div id="d1">hello HTML DOM</div>
</body>
<script>
function p(s){
document.write(s);
document.write("<br>");
}
let div1 = document.getElementById("d1");
p("文档节点"+document);
p("元素"+div1);
p("属性节点"+div1.attributes[0]);
p("内容节点"+div1.childNodes[0]);
</script>
</html>
执行结果
1.2 DOM相关操作
1.2.1 获取DOM元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>获取DOM元素</title>
</head>
<body>
<!--
1.在JavaScript中HTML标签也称之为DOM元素。
2.使用document的时候前面不用加window。
-->
<div class="father">
<form>
<input type="text" name="test">
<input type="password" name="test">
</form>
<div class="father" id="box">这是一个div</div>
<script type="text/javascript">
/*
1.通过id获取指定元素
由于id不可以重复, 所以找到了就会将找到的标签包装成一个对象返回给我们, 找不到就返回Null
注意点: DOM操作返回的是一个对象, 这个对象是宿主类型对象(浏览器提供的对象)
*/
console.log("====通过id获取指定元素====");
let div1 = document.getElementById("box");
// 输出结果
console.log(div1);
console.log(typeof div1); // obj类型
/*
2.通过class名称获取
由于class可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组
*/
console.log("====通过class名称获取====");
let div2 = document.getElementsByClassName("father");
console.log(div2);
/*
3.通过name名称获取
由于name可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组。
*/
console.log("++++通过name名称获取++++");
let div3 = document.getElementsByName("test");
console.log(div3);
/*
4.通过标签名称获取
由于标签名称可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组
*/
console.log("++++通过标签名称获取++++");
let div4 = document.getElementsByTagName("div");
console.log(div4);
/*
5.通过选择器获取
querySelector只会返回根据指定选择器找到的第一个元素
*/
console.log("====通过选择器获取====");
let div5 = document.querySelector("#box");
console.log(div5);
let div6 = document.querySelector(".father");
console.log(div6);
let div7 = document.querySelector("div>form");
console.log(div7);
/*
6.通过选择器获取
querySelectorAll会返回指定选择器找到的所有元素
*/
console.log("====返回指定选择器找到的所有元素====");
let elements = document.querySelectorAll(".father");
console.log(elements);
</script>
</div>
</body>
</html>
执行结果
1.2.2 获取节点
DOM对象(document)这个对象以树的形式保存了界面上所有的内容*,*HTML页面每一部分都是节点(标签(元素),文本,属性)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>获取DOM元素</title>
</head>
<body>
<div>
<h3>hello javaScript!!!</h3>
<h3>hello Vue.js!!!</h3>
<p class="special">Spring Boot!!!</p>
<p>html</p>
<span>CSS改变文本颜色.</span>
</div>
<script type="text/javascript">
// 1.获取指定元素所有的子元素
console.log("====获取指定元素所有的子元素====");
let elements = document.querySelector("div");
// 1.1 children属性获取到的是指定元素中所有的子元素
console.log(elements.children);
// 1.2 childNodes属性获取到的是指定元素中所有的节点
console.log("====获取到的是指定元素中所有的节点===")
console.log(elements.childNodes);
// 1.3 遍历节点
console.log("===遍历节点====")
for(let node of elements.childNodes){
// 条件判断
if(node.nodeType === Node.ELEMENT_NODE){
console.log(node);
}
}
// 2.获取指定节点中的第一个子节点
console.log("===获取指定节点第一个子节点==");
let div2 = document.querySelector("div");
console.log(div2.firstChild);
//3.获取指定元素中的第一个子元素
console.log("===获取指定元素的第一个子元素===");
console.log(div2.firstElementChild);
// 4.获取指定节点中最后一个子节点
console.log("===获取指定节点最后一个子节点===");
console.log(div2.lastChild);
// 5.获取指定元素中最后一个子元素
console.log("===获取指定元素中最后一个子元素===");
console.log(div2.lastElementChild);
// 6.通过子元素获取父元素/父节点
console.log("===通过子元素获取父元素/父节点===")
let div3 = document.querySelector(".special");
let parentEle = div3.parentElement || div3.parentNode;
// 输出结果
console.log(parentEle);
// 7.获取相邻上一个节点
console.log("====获取相邻上一个节点===");
console.log(div3.previousSibling);
// 8.获取相邻的上一个元素
console.log("====获取相邻的上一个元素===");
console.log(div3.previousElementSibling);
// 9.获取相邻的下一个节点
console.log("====获取相邻的下一个节点===");
console.log(div3.nextSibling);
console.log("===获取相邻下一个元素===");
console.log(div3.nextElementSibling);
</script>
</body>
</html>
执行结果
1.2.3 节点的增删改查
创建节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素增删改查</title>
</head>
<body>
<div>
<h3>javaScript DOM</h3>
<p>DOM元素增删改查</p>
</div>
<script type="text/javascript">
// 1.创建节点
console.log("===创建节点===");
let mySpan = document.createElement("span");
console.log(mySpan);
console.log(typeof mySpan);
</script>
</body>
</html>
执行结果
添加节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素增删改查</title>
</head>
<body>
<div>
<h3>javaScript DOM</h3>
<p>DOM元素增删改查</p>
</div>
<script type="text/javascript">
// 2.添加节点
// 注意点: appendChild方法会将指定的元素添加到最后
let mySpan = document.createElement("span");
let myDiv = document.querySelector("div");
myDiv.appendChild(mySpan);
let myA = document.createElement("a");
myDiv.appendChild(myA);
</script>
</body>
</html>
执行结果
插入节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素增删改查</title>
</head>
<body>
<div>
<h3>javaScript DOM</h3>
<p>DOM元素增删改查</p>
</div>
<script type="text/javascript">
// 3.插入节点
let mySpan = document.createElement("span");
let myDiv = document.querySelector("div");
let myH3 = document.querySelector("h3");
myDiv.insertBefore(mySpan, myH3);
let myP = document.querySelector("p");
myDiv.insertBefore(mySpan, myP);
</script>
</body>
</html>
执行结果
删除节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素增删改查</title>
</head>
<body>
<div>
<h3>javaScript DOM</h3>
<p>DOM元素增删改查</p>
</div>
<script type="text/javascript">
// 3.插入节点
let mySpan = document.createElement("span");
let myDiv = document.querySelector("div");
let myH3 = document.querySelector("h3");
myDiv.insertBefore(mySpan, myH3);
let myP = document.querySelector("p");
myDiv.insertBefore(mySpan, myP);
// 4.删除节点
// 注意:在js中如果想要删除某一个元素, 只能通过对应的父元素来删除.
mySpan.parentNode.removeChild(mySpan);
myDiv.parentNode.removeChild(myDiv);
</script>
</body>
</html>
执行结果
克隆节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素增删改查</title>
</head>
<body>
<div>
<h3>javaScript DOM</h3>
<p>DOM元素增删改查</p>
</div>
<script type="text/javascript">
// 5.克隆节点
let myDiv = document.querySelector("div");
let newDiv = myDiv.cloneNode(true);
console.log(newDiv);
</script>
</body>
</html>
执行结果
1.2.4 元素属性操作
通过对象.属性名称的方式无法获取到自定义属性的取值,通过getAttribute方法可以获取到自定义属性的取值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素属性操作</title>
</head>
<body>
<img src="images/timg.jpg" alt="歼20" title="第五代隐形战斗机" ts="123">
<script type="text/javascript">
// 1.获取元素属性
let myImg1 = document.querySelector("img");
// 输出结果
console.log("alt属性:" + myImg1.getAttribute("alt"));
// 自定义属性
console.log("TS属性:" + myImg1.getAttribute("TS"));
// 2.修改元素属性
let myImg2 = document.querySelector("img");
// 设置属性
myImg2.setAttribute("title", "帅气的五代机");
myImg2.setAttribute("ts", "牛逼!!!");
// 3.新增元素属性
let myImg3 = document.querySelector("img");
myImg3.setAttribute("nb", "隐形机");
myImg3.setAttribute("nt", "漂亮");
// 4.删除元素属性
let myImg4 = document.querySelector("img");
myImg4.removeAttribute("nb");
</script>
</body>
</html>
执行结果
1.2.5 元素内容操作
获取元素内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素内容操作</title>
</head>
<body>
<div>
金缕曲二首
<h3>我亦飘零久,十年来,深恩负尽,死生师友</h3>
<p>桃李春风一杯酒,江湖夜雨十年灯</p>
</div>
<script type="text/javascript">
// 1.获取元素内容
/*
1.innerHTML获取的内容包含标签, innerText/textContent获取的内容不包含标签
2.innerHTML/textContent获取的内容不会去除两端的空格, innerText获取的内容会去除两端的空格
*/
let myDiv1 = document.querySelector("div");
console.log(myDiv1.innerHTML);
console.log(myDiv1.innerText);
console.log(myDiv1.textContent);
</script>
</body>
</html>
执行结果
设置元素内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素内容操作</title>
</head>
<body>
<div>
金缕曲二首
<h3>我亦飘零久,十年来,深恩负尽,死生师友</h3>
<p>桃李春风一杯酒,江湖夜雨十年灯</p>
</div>
<script type="text/javascript">
// 2.设置元素内容
/*
特点:
无论通过innerHTML/innerText/textContent设置内容, 新的内容都会覆盖原有的内容。
区别:
如果通过innerHTML设置数据, 数据中包含标签, 会转换成标签之后再添加。
如果通过innerText/textContent设置数据, 数据中包含标签, 不会转换成标签, 会当做一个字符串直接设置。
*/
let myDiv2 = document.querySelector("div");
// myDiv2.innerHTML = "123";
// myDiv2.innerText = "456";
// myDiv2.textContent = "789";
// myDiv2.innerHTML = "<span>愿我如星君如月,夜夜流光相皎洁</span>";
// myDiv2.innerText = "<span>愿我如星君如月,夜夜流光相皎洁</span>";
// myDiv2.textContent = "<span>愿我如星君如月,夜夜流光相皎洁</span>";
setText(myDiv2, "愿我如星君如月,夜夜流光相皎洁");
function setText(obj, text) {
if("textContent" in obj){
obj.textContent = text;
}else{
obj.innerText = text;
}
}
</script>
</body>
</html>
执行结果
1.2.6 操作元素样式
设置元素样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>操作元素样式</title>
<style>
.box{
width: 200px;
height: 200px;
background-color: blueviolet;
}
</style>
</head>
<body>
<div class="box"></div>
<script type="text/javascript">
// 1.设置元素样式
let myDiv1 = document.querySelector("div");
// 方式一:由于class在JS中是一个关键字, 所以叫做className.
myDiv1.className = "box";
// 第二种方式
// 注意点: 通过JS添加的样式都是行内样式, 会覆盖掉同名的CSS样式.
myDiv1.style.width = "300px";
myDiv1.style.height = "300px";
myDiv1.style.backgroundColor = "blue";
</script>
</body>
</html>
执行结果
获取元素样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>操作元素样式</title>
<style>
.box{
width: 200px;
height: 200px;
background-color: blueviolet;
}
</style>
</head>
<body>
<div class="box"></div>
<script type="text/javascript">
// 2.获取元素样式
let myDiv2 = document.querySelector("div");
// 取到CSS设置的属性值,必须通过getComputedStyle方法来获取
let style = window.getComputedStyle(myDiv2);
console.log(style.width);
</script>
</body>
</html>
执行结果
1.3 DOM事件
1.3.1 事件基本定义
在网页中操作的时候,会激活各种事件,可以通过JS代码来对这些事件编程,当激活这些事件的时候,实现相应的功能。可以让网页"活"起来,与用户有交互的功能。
1.3.2 设置事件方式
命名函数
<input type="button" onclick="clickMe()" id="btn">
function clickMe() {
//事件处理函数
}
匿名函数
document.querySelector("btn").onclick = function() {
//事件处理函数
}
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件处理函数</title>
</head>
<body>
<input type="button" value="命名函数" id="b1" onclick="clickMe()">
<input type="button" value="匿名函数" id="b2">
<script type="text/javascript">
//命名函数
function clickMe() {
alert("命名函数");
}
//匿名函数要写在按钮元素的后面
document.getElementById("b2").onclick = function () {
alert("匿名函数");
}
</script>
</body>
</html>
执行结果
1.3.4 Event(事件)
- Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
- 事件通常与函数结合使用,函数不会在事件发生前被执行!
- 事件对象是和当前事件有关系。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Event对象事件</title>
<style type="text/css">
body,html{height: 100%;}
</style>
</head>
<body>
<span id='span'></span>
<script>
onclick = function(event){
console.log(event)
};
</script>
</body>
</html>
执行结果
1.3.5 事件流
**事件冒泡:**从内到外
**事件捕获:**从外到内
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡和事件捕获</title>
</head>
<body>
<div id="div1" style="background: red; width: 300px; height: 300px">
<div id="div2" style="background: blue;width: 200px;height: 200px"></div>
</div>
<script>
// 获取div元素
let div1 = document.getElementById("div1");
let div2 = document.getElementById("div2");
// 事件捕获
div1.onclick = function(){
alert(1);
}
// 事件冒泡
div2.onclick = function(){
alert(2);
}
</script>
</body>
</html>
执行结果
1.3.6 加载完成事件
当整个文档加载成功,或者一个图片加载成功,会触发加载事件 。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>加载完成事件</title>
<style type="text/css">
#myDiv{width: 100px;
height: 100px;
background: green;}
</style>
</head>
<body>
<div id=myDiv></div>
<script>
// 函数一开始是不执行的:整个浏览器窗口加载完毕以后才执行
window.onload = function(){
setTimeout(function(){
document.querySelector("#myDiv").style.height = '200px';
},1000);
};
</script>
</body>
</html>
执行结果
1.3.7 鼠标事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>鼠标事件</title>
</head>
<body>
<input type="button" onmousedown="down()" onmouseup="up()" value="按下和弹起" ><br/><br/>
<input type="button" onmousemove="move()" value="鼠标经过" ><br/><br/>
<input type="button" onmouseover="over()" value="鼠标进入"><br/><br/>
<input type="button" onmouseout="out()" value="鼠标退出" ><br/><br/>
<div id="message"></div>
<script type="text/javascript">
// 定义number变量
let num = 0;
/*鼠标按下调用函数*/
function down(){
document.querySelector("#message").innerHTML="按下了鼠标";
}
/*鼠标谈起调用函数*/
function up(){
document.querySelector("#message").innerHTML="弹起了鼠标";
}
/*鼠标经过次数调用函数*/
function move(){
document.querySelector("#message").innerHTML="鼠标经过次数:"+(++num);
}
/*鼠标进入次数调用函数*/
function over(){
document.querySelector("#message").innerHTML="鼠标进入次数:"+(++num);
}
/*鼠标退出调用函数*/
function out(){
document.querySelector("#message").innerHTML="鼠标退出";
num = 0;
}
</script>
</body>
</html>
执行结果
1.3.8 点击事件
- 点击事件,由单击,双击按两个事件组成。
- 当在组件上单击的时候,会触发onclick事件,当在组件上双击的时候,会触发ondblclick事件 。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点击事件</title>
</head>
<body>
userName:<input type="text" id="t1"> <br/><br/>
userName:<input type="text" id="t2"> <br/><br/>
<input type="button" value="单击复制/双击清除" id="btn">
<script type="text/javascript">
//单击事件
document.querySelector("#btn").onclick = function () {
document.querySelector("#t2").value = document.querySelector("#t1").value;
}
//双击事件
document.getElementById("btn").ondblclick = function () {
/*清空为0*/
document.getElementById("t1").value = "";
document.getElementById("t2").value = "";
}
</script>
</body>
</html>
执行结果
1.3.9 焦点事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>得到焦点和失去焦点</title>
</head>
<body>
<input type="text" id="txt">
</body>
<script>
// 获得文本对象
let txt = document.querySelector("#txt");
// 得到焦点
txt.onfocus = function(){
txt.style.background = "red";
}
// 失去焦点
txt.onblur = function(){
txt.style.background = "blue";
}
</script>
</html>
执行结果
1.3.10 改变事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>onchange事件</title>
</head>
<body>
<select name="" id="city">
<option value="">北京</option>
<option value="">天津</option>
<option value="">上海</option>
</select>
</body>
<script>
// 获得文本
let city = document.getElementById("city");
// 文本修改值
city.onchange = function(){
alert("改变值了");
}
// 4.oninput事件可以时时获取到用户修改之后的数据, 只要用户修改了数据就会调用(执行)
city.oninput = function (){
console.log(this.value);
}
</script>
</html>
执行结果
1.3.11 添加事件方式
- 通过onclick的方式来添加。
- 通过addEventListener方法添加。
- 整合attachEvent方法添加。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加事件方式</title>
</head>
<body>
<button id="btn">按钮button</button>
<script type="text/javascript">
let oBtn = document.getElementById("btn");
/*
注意点: 由于是给属性赋值, 所以后赋值的会覆盖先赋值.
*/
oBtn.onclick = function (){
console.log("onclick:" + 123);
}
oBtn.onclick = function (){
console.log("onclick:" + 234);
}
/*
事件名称不需要添加on,后添加的不会覆盖先添加的,只支持最新的浏览器。
*/
oBtn.addEventListener("click", function (){
console.log("addEventListener:" + 11);
});
oBtn.addEventListener("click", function (){
console.log("addEventListener:" + 21);
});
/*
事件名称必须加上on,后添加的不会覆盖先添加的,只支持低版本的浏览器。
*/
addEvent(oBtn, "click", function (){
console.log("整合方法:" + 333);
})
addEvent(oBtn, "click", function (){
console.log("整合方法:" + 77);
})
// 调用方法
function addEvent(ele, name, func){
if(ele.attachEvent){
ele.attachEvent("on" + name, func);
}else {
ele.addEventListener(name, func);
}
}
</script>
</body>
</html>
执行结果
1.3.12 事件对象
事件对象基本定义
事件对象就是一个系统自动创建的一个对象,当注册的事件被触发的时候, 系统就会自动创建事件对象。
当注册的事件被触发的时候, 系统就会自动创建事件对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件对象</title>
</head>
<body>
<a href="https://www.imooc.com/">慕课网</a>
<script type="text/javascript">
/*
事件对象的注意点:
在高级版本的浏览器中, 会自动将事件对象传递给回到函数
在低级版本的浏览器中, 不会自动将事件对象传递给回调函数
在低级版本的浏览器中, 需要通过window.event来获取事件对象
*/
let oA = document.querySelector("a");
oA.onclick = function (event){
// 兼容性实现
event = event || window.event;
// 打印
console.log(123);
// 阻止默认行为
return false;
}
</script>
</body>
</html>
执行结果
1.3.13 事件冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
width: 400px;
margin: 100px auto;
border: 1px solid #000;
}
.selected{
background: green;
}
</style>
</head>
<body>
<ul>
<li class="selected">我亦飘零久,十年来,深恩负尽,死生师友。</li>
<li>桃李春风一杯酒,江湖夜雨十年灯。</li>
<li>雨中黄叶树,灯下白头人。</li>
<li>绿蚁新醅酒,红泥小火炉。晚来天欲雪,能饮一杯无?</li>
<li>君埋泉下泥销骨,我寄人间雪满头。</li>
</ul>
<script type="text/javascript">
// 1.获取对象
let oUl = document.querySelector("ul");
let oLi = document.querySelector(".selected");
// 2.点击事件
oUl.onclick = function (event){
event = event || window.event;
oLi.className = "";
let item = event.target;
item.className = "selected";
oLi = item;
}
</script>
</body>
</html>
执行结果
1.3.14 阻止事件冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>阻止事件冒泡</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.div1{
width: 300px;
height: 300px;
background: green;
}
.div2{
width: 150px;
height: 150px;
background: blueviolet;
}
</style>
</head>
<body>
<div class="div1" id="S1">
<div class="div2" id="S2"></div>
</div>
<script type="text/javascript">
// 1.拿到需要操作的元素
let oS1 = document.getElementById("S1");
let oS2 = document.getElementById("S2");
// 2.注册事件监听
oS1.onclick = function (){
console.log("S1");
}
oS2.onclick = function (event){
event = event || window.event;
// stopPropagation方法只支持高级浏览器,cancelBubble支持低级浏览器
if(event.cancelBubble){
event.cancelBubble = true;
}else {
event.stopPropagation();
}
// 输出s2
console.log("S2");
}
</script>
</body>
</html>
代码示例
1.3.15 位置获取
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>位置获取</title>
<style>
*{
margin: 0;
padding: 0;
}
div{
width: 100px;
height: 100px;
background: red;
margin-left: 100px;
margin-top: 800px;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
// 获得id值
let oDiv = document.getElementById("box");
// 点击事件
oDiv.onclick = function (event){
// offsetX/offsetY: 事件触发相对于当前元素自身的位置
console.log("offsetX:", event.offsetX);
console.log("offsetY:", event.offsetY);
console.log("---------");
// clientX/clientY: 事件触发相对于浏览器可视区域的位置
console.log("clientX:", event.clientX);
console.log("clientY:", event.clientY);
console.log("---------");
// pageX/pageY:事件触发相对于整个网页的位置
console.log("pageX:", event.pageX);
console.log("pageY:", event.pageY);
// screenX/screenY: 事件触发相对于屏幕的位置
console.log("---------");
console.log("screenX:", event.screenX);
console.log("screenY:", event.screenY);
}
</script>
</body>
</html>
执行结果
1.4 定时器
重复执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>定时器</title>
</head>
<body>
<button id="start">开始执行</button>
<button id="close">结束操作</button>
<script type="text/javascript">
// 1.重复执行的定时器
let start1 = document.querySelector("#start");
let id = null;
// 1.1 点击事件
start1.onclick = function (){
id = setInterval(function (){
console.log("hello javaScript!!!");
}, 1000);
}
// 1.2 关闭点击事件
let close1 = document.querySelector("#close");
// 停止事件
close1.onclick = function (){
clearInterval(id);
}
</script>
</body>
</html>
执行结果
执行一次
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>定时器</title>
</head>
<body>
<button id="start">开始执行</button>
<button id="close">结束操作</button>
<script type="text/javascript">
// 2.执行一次的定时器
let start2 = document.querySelector("#start");
let id = null;
// 2.1 点击事件
start2.onclick = function (){
id = window.setTimeout(function (){
console.log("hello javaScript!!!");
}, 1000);
}
// 2.2 关闭点击事件
let close2 = document.querySelector("#close");
// 停止事件
close2.onclick = function (){
clearTimeout(id);
}
</script>
</body>
</html>
执行结果
延时调用
SetTimeout()方法
延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次。
ClearTimeout()方法
可取消由 setTimeout()方法设置的定时操作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>延时调用</title>
</head>
<body>
<script type="text/javascript">
var num = 1;
/*
* 延时调用:
* 延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次
* 延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次
* 延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择
*/
var timer = setTimeout(function(){
console.log(num++);
},3000);
//使用clearTimeout()来关闭一个延时调用
clearTimeout(timer);
</script>
</body>
</html>
1.5 JS 闭包
闭包基本定义
子函数使用父函数变量的行为叫做闭包。
生成闭包
当一个内部函数引用了外部函数的数据(变量/函数)时, 那么内部的函数就是闭包,所以只要满足是函数嵌套、内部函数引用外部函数数据。
闭包的特性
- 只要闭包还在使用外部函数的数据, 那么外部的数据就一直不会被释放,也就是说可以延长外部函数数据的生命周期。
- 在js中函数内部的局部变量只允许其子函数使用。
- 父函数没法使用子函数的局部变量,子函数可以使用父函数的局部变量。
闭包的注意点
当后续不需要使用闭包时候, 一定要手动将闭包设置为null, 否则会出现内存泄漏。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>闭包</title>
</head>
<body>
<script type="text/javascript">
function func1(){
//c 是局部变量 外面拿不到
var c = 10;
function func2(){
var f = 20;
console.log("c1的值" + c);
function func3(){
console.log("c2的值:" + c);
}
}
func2();
console.log("f的值:" + f);
}
func1();
</script>
</body>
</html>
执行结果