js Web APIs
DOM
获取元素
获取页面元素的方法:1、根据ID获取
2、根据标签名获取
3、通过HTML5新增的方法获取
4、特殊元素获取
根据ID获取
使用getElementByld()方法可以获取带有ID的元素对象,返回值为一个元素对象
document.getElementById('id名');
使用getElementsByTagName获取某些元素,返回的是获取过来的元素对象的集合
// 返回的是 获取过来元素对象的集合 以伪数组的形式储存
var lis = document.getElementsByTagName('li');
console.log(lis);
// 返回的是 获取过来元素对象的集合 以伪数组的形式储存
var lis = document.getElementsByTagName('li');
console.log(lis);
// 依次打印元素对象可以采用遍历的方式
for(var i = 0; i < lis.length; i++)
{
console.log(lis[i]);
}
根据标签名获取
可以获取某个元素(父元素)内部所有指定标签名的子元素
element.getElementsByTagName('标签名');
注意:父元素必须是单个对象(必须指明是哪一个元素对象)。获取的时候不包括父元素自己
// element.getElementsByTagName('ol');
var ol = document.getElementsByTagName('ol');
console.log(ol[0].getElementsByTagName('li'));
// 第二种方法
var ol = document.getElementById('ol');
console.log(ol.getElementsByTagName('li'));
通过HTML5新增的方法获取
document.getElementsByClassName('类名');//根据类名返回元素对象集合
<body>
<div class="box">盒子</div>
<div class="box">盒子</div>
<div class="nav">
<ul>
<li>首页</li>
<li>产品</li>
</ul>
</div>
<script>
// 1、getElementsByClassName 根据类名获得某些元素
var boxs = document.getElementsByClassName('box');
console.log(boxs);
</script>
</body>
document.querySelector('选择器');//根据指定选择器返回第一个元素对象 切记里面的选择器需要加符号 类加. id加#
// 2、querySelector 返回指定选择器的第一个对象
var firstBox = document.querySelector('.box');
console.log(firstBox);
document.querySelectorAll('选择器');//根据指定选择器返回 返回指定选择器的所有元素对象集合
获取特殊元素(body,html)
获取body元素
var bodyEle = document.body;//返回body对象
获取html元素
var htmlEle = document.documentElement;//返回Html对象
事件基础
事件由三部分组成:事件源 事件类型 事件处理程序
<!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>
// 点击一个按钮,弹出对话框
// 1、事件源 事件被触发的对象
var btn = document.getElementById('btn');
// 2、事件类型 如何触发 什么事件 比如鼠标点击(onclick)还是鼠标经过 还是键盘按下
// 3、事件处理程序 通过一个函数赋值的方式完成
btn.onclick = function(){
alert('点秋香');
}
</script>
</body>
</html>
执行事件的步骤:1、获取事件源
2、注册事件(绑定事件)
3、添加事件处理程序(采取函数赋值形式)
常见的鼠标事件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1u0zkBh-1650767316133)(js Web APIs.assets/CLRGBVN8V2NI%T5N_N1L.png)]
操作元素
改变元素内容
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JXhyVx7b-1650767316136)(js Web APIs.assets/QQ图片20220414125650.png)]
innerText
<!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>
<style>
div,p{
background-color: pink;
}
</style>
</head>
<body>
<button>显示当前系统时间</button>
<div>某个时间</div>
<P>123</P>
<script>
// 当我们点击了按钮 div里面的文字会发生变化
// 1、获取元素
var btn = document.querySelector('button');
var div = document.querySelector('div');
// 2、注册事件
btn.onclick = function(){
div.innerText = getDate();
}
function getDate(){
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() +1;
var dates = date.getDay();
var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
var day = date.getDay();
return '今天是:'+ year+'年'+ month + '月' + dates + '日' + arr[day];
}
// 元素可以不用添加事件
var p = document.querySelector('p');
p.innerText = getDate();
</script>
</body>
</html>
区别
<!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>
<div></div>
<script>
// innerText和innerHTML的区别
// 1、innerText不识别HTML标签 非标准 去除空格和换行
var div = document.querySelector('div');
div.innerText = '<strong>今天是:</strong> 2019';
// 2、innerHTML W3C标准 识别html标签 保留空格和换行
div.innerHTML = '<strong>今天是:</strong> 2019';
// 这两个属性是可读写的 可以获取元素里面的内容
var p = document.querySelector('p');
</script>
</body>
</html>
常用元素的属性操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3szSyBm4-1650767316138)(js Web APIs.assets/QQ图片20220414133652.png)]
表单元素的操作属性
利用DOM可以操作如下表单元素的属性:
type, value, checked, selected, disabled
获得焦点:onfocus 失去焦点:onblur
<!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>按钮</button>
<input type="text" value="输入内容">
<script>
// 1、获取元素
var btn = document.querySelector('button');
var input = document.querySelector('input');
// 2、注册事件处理程序
btn.onclick = function(){
// 表单里面的值通过value来进行修改
input.value = '被点击了'
// 如果想要某个表单被禁用 不能再点击 disabled 我们想要这个按钮 button 禁用
// btn.disabled = true;
this.disabled = true;
// this指向的是事件函数的调用者
}
</script>
</body>
</html>
样式属性操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BJc6W3tC-1650767316139)(js Web APIs.assets/WS]N_`C7{AIA6Z5L56Q{XTG.png)]
注意:1、JS里面的样式采取驼峰命名法
2、JS修改style样式操作,产生的是行内样式,css权重比较高
3、className 会直接更改元素的类名,会覆盖原先的类名,如果想要保留原先的类名 使用多类名选择器
<!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>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
// 1、获取元素
var div = document.querySelector('div');
// 注册事件 处理程序
div.onclick = function(){
// 里面的属性采用驼峰命名法
this.style.backgroundColor = 'purple';
this.style.width = '250px';
}
</script>
</body>
</html>
className修改元素类名更改样式
<!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>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
.change {
width: 250px;
height: 250px;
background-color: skyblue;
color: #fff;
}
</style>
</head>
<body>
<div>文字</div>
<script>
var test = document.querySelector('div');
test.onclick = function(){
this.className = 'change';
// 如果想要保留原先的类名
this.className = 'first change';
}
</script>
</body>
</html>
排他思想
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WBfXo3F1-1650767316140)(js Web APIs.assets/2B[KZXNJBJ_NEXX{{GPB%A4.png)]
自定义属性的操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aex4C3pv-1650767316142)(js Web APIs.assets/QQ图片20220414164548.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KIrrCA4G-1650767316143)(js Web APIs.assets/%]T19$M50KAX41CP9EF9@C.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DHHYyJYX-1650767316145)(js Web APIs.assets/QQ图片20220414165353.png)]
H5自定义属性
自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据中
自定义属性获取是通过getAttribute(‘属性’)获取
但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tDfnGGht-1650767316146)(js Web APIs.assets/`ZTXBH%V4%NC90FS[SER.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w9IXNEs9-1650767316147)(js Web APIs.assets/D86UCI_J@0JB}8Q93TY7L2.png)]
如果自定义属性里面有多个 - 链接的单词,我们在获取的时候采取 驼峰命名法
H5新增的获取方法只能获取以data开头的自定义属性 并且ie11才开始支持,之前版本不兼容
节点操作
节点概述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ae9kD98-1650767316148)(js Web APIs.assets/KR[Z1G$UZ_FD@7RD_13MS{M.png)]
节点层级
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZB1cp9r3-1650767316149)(js Web APIs.assets/[YH%TT7L]VD2M3FR1A{NDAF.png)]
父级节点
node.parentNode
**注意:**1、node.parentNode返回的是离元素最近的父节点
2、如果父节点不存在则返回为空
操作代码:
<!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>
<div class="box">
<span class="erweima">x</span>
</div>
<script>
// 1、父节点 parentNode
var erweima = document.querySelector('.erweima');
// 得到的是离元素最近的父级节点,如果找不到父节点就返回为空
var box = erweima.parentNode;
</script>
</body>
</html>
子节点
node.chidNodes
//得到所有的节点包括元素节点 文本节点等
//判断得到的是什么节点
console.log(ul.childNodes[0].nodeType);
console.log(ul.childNodes[1].nodeType);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zEFprlKm-1650767316150)(js Web APIs.assets/QQ图片20220414200405.png)]
只获取元素节点
parentNode.children
parentNode.children是一个只读属性,返回所有子元素节点。它只返回子元素节点,其余节点不反悔(重点掌握)
支持各种浏览器使用
获取第几个子节点
返回第一个子节点,找不到则返回null。也是返回所有节点
parentNode.firstChild;
返回第一个子节点,只返回元素节点
parentNode.firstElementChild
返回最后一个节点,找不到则返回null,也是返回所有节点
parentNode.lastChild
返回最后一行子元素节点
parentNode.lastElementChild
parentNode.fistElementChild和parentNode.lastElementNode有兼容性问题 IE9以上才支持
实际开发中 既没有兼容性问题又返回第一个子元素
解决方案:1、如果想要第一个子元素节点,可以使用parentNode.children[0];
2、如果想要最后一个子元素节点,可以使用parentNode.children[ol.length - 1]
兄弟节点
返回当前元素的下一个兄弟节点,包含所有的节点
node.nextSibling
返回上一个兄弟节点,包含所有节点
node.previousSibling
返回当前元素下一个兄弟元素节点有兼容性问题IE9以上支持
node.nextElementSibling
返回上一个兄弟元素节点有兼容性问题IE9以上支持
node.previousElementSibling
如何解决兼容性问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B3uOsYkG-1650767316152)(js Web APIs.assets/QQ图片20220415134033.png)]
创建节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OnLNmZmA-1650767316153)(js Web APIs.assets/H$@8NPZRTI7KK`FEGVUSNA.png)]
添加节点
node.appendchild()方法将一个节点添加到指定父节点的子节点列表末尾。类似于CSS里面的after伪元素 后面追加元素
node.appendchild(child)
node.insertBefore()方法将一个节点添加到父节点的指定子节点前面。类似于css里面的before伪元素
node.insertBefore(child,指定元素)
<!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>
<ul></ul>
<script>
// 1、创建节点元素节点
var li = document.createElement('li');
// 2、添加节点 node.appendChild(child)
var ul = document.querySelector('ul');
ul.appendChild(li);
// 3、添加节点,在指定元素之前添加
var lili = document.createElement('li');
ul.insertBefore(lili,ul.children[0]);
</script>
</body>
</html>
注意:想要页面中添加一个新元素:1、创造元素 2、添加元素
简单留言发布案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JiDdAAoI-1650767316154)(js Web APIs.assets/VZNL@7R%INWRWLQOZ]KX6B.png)]
<!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>
<textarea name="" id=""></textarea>
<button>发布</button>
<ul>
</ul>
<script>
// 1、获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2、注册事件
btn.onclick = function(){
if(text.value == ''){
alert('您没有输入内容');
return false;
}else{
console.log(text.value);
// 1、创建元素
var li = document.createElement('li');
// 先有li才能赋值
li.innerHTML = text.value;
// 2、添加元素
// ul.appendChild(li);
ul.insertBefore(li,ul.childeren[0]);
}
}
</script>
</body>
</html>
删除节点
删除node节点中的子节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRgQL8zS-1650767316155)(js Web APIs.assets/QQ图片20220415144722.png)]
<!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>删除</button>
<ul>
<li>熊大</li>
<li>熊二</li>
<li>光头强</li>
</ul>
<script>
// 1、获取元素
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
//2、删除元素
// ul.removeChild(ul.children[0]);
// 3、点击按钮以此删除里面的孩子
btn.onclick = function(){
if(ul.children.length == 0)
{
this.disabled = true;
}else{
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
</html>
删除留言案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kb6LXmfj-1650767316156)(js Web APIs.assets/QQ图片20220415150111.png)]
复制节点(克隆节点)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-prKeybme-1650767316158)(js Web APIs.assets/QQ图片20220415150309.png)]
**注意:**1、如果括号参数为空或者为false,则是浅拷贝,即只克隆赋值节点本身,不克隆里面的子节点
2、node.cloneNode(true);括号里面为true 深拷贝 复制标签并复制里面的内容
<!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>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
// 1、node.cloenNode();
var lili = ul.children[0].cloneNode(true);
ul.appendChild(lili);
</script>
</body>
</html>
动态生成表格
案例:1、准备数据
2、创建行
3、获取对象数据并将其给创建的单元格
<!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>
<style>
</style>
</head>
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1、先准备好学生数据
var datas = [
{
name:'liu',
subject:'javascript',
score:100
},{
name:'li',
subject:'javascript',
score:99
},
{
name:'lu',
subject:'javascript',
score:98
}
];
// 2、往tbody里面创建行:有几个人(通过数组长度)就创建几行
var tbody = document.querySelector('tbody');
for(var i = 0; i < datas.length; i++)
{
// 创建 tr行
var tr = document.createElement('tr');
tbody.appendChild(tr);
// 行里面创建单元格 td 单元格数量取决于每个对象里面的属性个数
for(var k in datas[i])
{
var td = document.createElement('td');
// 把对象里面的数据给td
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
// 3、创建有删除两字的单元格
var td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除</a>';
tr.appendChild(td);
}
// 4、删除操作
var as = document.querySelectorAll('a');
for(var i = 0; i < as.length; i++)
{
as[i].onclick = function(){
// 点击a删除 当前a所在的行(链接的爸爸的爸爸)node.removeChild(child)
tbody.removeChild(this.parentNode.parentNode);
}
}
</script>
</body>
</html>
三种动态创建元素的区别
document.write()
element.innerHTML
document.createElement()
区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ri99virG-1650767316159)(js Web APIs.assets/QQ图片20220415213225.png)]
//innerHTML数组形式拼接
var arr = [];
for (var i = 0; i <= 100; i++)
{
arr.push('<a href="#">百度</a>');
}
inner.innerHTML = arr.join('');
DOM重点核心
主要有创建、增、删、改、查、属性操作、事件操作
创建:1、document.write
2、innerHTML
3、createElement
增:1、appendChild 在后面加
2、insertBefore 在前面加
删:1、removeChild
改:主要修改dom的元素属性,dom元素的内容、属性,表单的值等
1、修改元素属性:src、href、title等
2、修改普通元素内容:innerHTML、innerText
3、修改表单元素:value、type、disable等
4、修改元素样式:style、className
查:主要获取查询dom的元素
1、DOM提供的API方法:getElementById、getElementsByTagName 古老用法不太推荐
2、H5提供的新方法:querySelector、querySelectorAll 提倡
3、利用节点操作获取元素:父(parentNode)、子(childNode)、兄(previousElementSibling、nextElementSibling)提倡
属性操作:主要针对于自定义属性
1、setAttribute: 设置dom的属性值
2、getAttribute:得到dom的属性值
3、removeAttribute移除属性
事件操作:给元素注册事件,采取事件源.事件类型=事件处理程序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vQKuw3L8-1650767316161)(js Web APIs.assets/QQ图片20220415214936.png)]
高级事件
注册事件
给元素添加事件,称为注册事件或者绑定事件
注册事件有两种方式:传统方式和方法监听注册方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CqOCKycO-1650767316162)(js Web APIs.assets/QQ图片20220416132422.png)]
唯一性:同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-teWPHOm1-1650767316163)(js Web APIs.assets/QQ图片20220416132906.png)]
addEventListener事件监听方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mlAloX93-1650767316164)(js Web APIs.assets/QQ图片20220416133056.png)]
<!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>传统注册方式</button>
<button>事件监听方式</button>
<script>
var btns = document.querySelectorAll('button');
// 2、事件侦听注册方式 里面的事件类型是字符串,需要加引号,不带on
btns[1].addEventListener('click',function(){
alert(22);
})
btns[1].addEventListener('click',function(){
alert(33);
})
</script>
</body>
</html>
attachEven事件监听方式(了解)

注册事件兼容性解决方案(了解)

删除事件
删除事件的方式
1、传统注册方式
eventTarget.onclick = null;
2、方法监听注册方式
eventTarget.removeEvenListener(type, listener[,useCapture]);
eventTarget.detachEvent(eventNameWithOn, callback);
<!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>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
var divs = document.querySelectorAll('div');
divs[0].onclick = function(){
alert(11);
// 1、传统方式删除事件
divs[0].onclick = null;
}
divs[1].addEventListener('click', fn);//里面的fn不需要调用加小括号
function fn(){
alert(22);
divs[1].removeEventListener('click', fn);
}
</script>
</body>
</html>
删除事件兼容性解决方案(了解)

DOM事件流
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B0vSC7pA-1650767316165)(js Web APIs.assets/QQ图片20220416135655.png)]
DOM事件流分为3个阶段:1、捕获阶段
2、当前目标阶段
3、冒泡阶段
冒泡阶段:事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程
事件捕获:由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wb7y7CN9-1650767316166)(js Web APIs.assets/CF33JLOA%Y}C}I7`0V4ZX3.png)]
4、实际开发中很少使用事件捕获,更关注事件冒泡
5、有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave
6、事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件。
事件对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ApZnHO0v-1650767316167)(js Web APIs.assets/DIN32TU@XDP@H7`A[T%F@YM.png)]
event是个形参,系统帮我们设定为事件对象,不需要传递实参过去
当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n6dhz063-1650767316168)(js Web APIs.assets/QQ图片20220416141951.png)]
事件对象的常见属性和方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DqV2N5eZ-1650767316169)(js Web APIs.assets/QQ图片20220416152612.png)]
阻止事件冒泡
事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点
事件冒泡本身的特性,会带来的坏处,也会带来好处,需要灵活掌握
方式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6B8P42kR-1650767316170)(js Web APIs.assets/BV4{}PM3JWX8LL4NSZ0W7M.png)]
阻止事件冒泡的兼容性解决方案
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yVscUMIV-1650767316171)(js Web APIs.assets/QQ图片20220416154214.png)]
事件委托(代理、委派)
事件委托也成为时间代理,在jQuery里面称为事件委派
原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oHiudkEq-1650767316171)(js Web APIs.assets/LHTS0J_HXF%5@FODU1R]HJB.png)]
<!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>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
// 事件委托的核心原理:给父节点添加侦听器,利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e){
// e.target可以得到当前点击的对象
e.target.style.backgroundColor = 'pink';
})
</script>
</body>
</html>
常用的鼠标事件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tDxoSf1o-1650767316172)(js Web APIs.assets/CLRGBVN8V2NI%T5N_N1L.png)]
禁止鼠标右键菜单
contexmenu禁止右键菜单
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ugzJHI9T-1650767316173)(js Web APIs.assets/NQ5PA$[A4}SJOVWFD9TC8Y.png)]
禁止鼠标选中(selectstart 开始选中)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2D48jXM-1650767316175)(js Web APIs.assets/QQ图片20220416155931.png)]
鼠标事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象
MouseEvent和键盘事件对象KeyboardEvent
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qxysxrx9-1650767316176)(js Web APIs.assets/SUSONQP]SR7KLSLAM}]N0X.png)]
案例:跟随鼠标的天使
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Js6jsHtH-1650767316177)(js Web APIs.assets/QQ图片20220416161843.png)]
<!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>
<style>
img {
position: absolute;
}
</style>
</head>
<body>
<img src="../images/4b84d997422c4f2381d1fb398d136a86.png" alt="">
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove', function(e){
// 1、只要鼠标移动1px 就会触发这个事件
// 2、核心原理:每次鼠标移动,都会获得最新的鼠标坐标,把这个x和y坐标作为图片的top和left值就可以移动图片
var x = e.pageX;
var y = e.pageY;
// 需要加上px单位
pic.style.left = x - 50 + 'px';
pic.style.top = y - 40 + 'px';
})
</script>
</body>
</html>
常用的键盘事件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aEilS1dR-1650767316179)(js Web APIs.assets/QQ图片20220416165116.png)]
注意1、如果使用addElementListener不需要加on
2、onkeypress和前面2个的区别是,它不识别功能键,比如左右箭头,shift等
3、三个事件的执行顺序是:keydown – keypress – keyup
键盘事件对象
键盘事件对象属性 | 说明 |
---|---|
keyCode | 返回该键的ASCII值 |
**注意:**onkeydown和onkeyup不区分字母大小写 onkeypress区分字母大小写
在实际开发中,更多使用keydown和keyup,能识别所有的键(包括功能键)
keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值
模拟京东按键输入内容案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kZx0Q3JT-1650767316180)(js Web APIs.assets/QQ图片20220416171303.png)]
<!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>
<input type="text">
<script>
var search = document.querySelector('input');
document.addEventListener('keyup',function(e){
// console.log(e.keyCode);
if (e.keyCode === 83){
search.focus();
}
})
</script>
</body>
</html>
模拟京东快递单号查询案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-350euf4F-1650767316181)(js Web APIs.assets/2ZI1[G_(HIR0[`)]RN@%G8X.png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ve5zTtTh-1650767316182)(js Web APIs.assets/73IS_M`8K4Q{0$UJ8AH[B4.png)]
keyup事件触发的时候,文字已经落入文本框里面了
BOM
BOM即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。
window对象是浏览器的顶级对象,具有双重角色
1、它是JS访问浏览器窗口的一个接口
2、它是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法。它在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如aler()、prompt()等
注意:window下的一个特殊属性window.name
window常见事件
窗口加载事件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T6JvcExh-1650767316183)(js Web APIs.assets/QQ图片20220417135317.png)]
注意1、有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面内容全部加载完毕再去执行处理函数。
2、window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准
3、如果使用addEventListener则没有限制
提倡用addEventListener方式写
windou.addEventListener('load', function(){
//内容
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JhHwskTF-1650767316184)(js Web APIs.assets/QQ图片20220417140239.png)]
load等页面内容全部加载完毕,包含页面dom元素 图片 flash css等
DOMContentLoaded是DOM加载完毕,不包含图片 flash css等就可以执行 加载速度比load更快一些
调整窗口大小事件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wOrpzomc-1650767316184)(js Web APIs.assets/QQ图片20220417141554.png)]
定时器
setTimeout()定时器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mRKG5exF-1650767316185)(js Web APIs.assets/QQ图片20220417142301.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnsZCekB-1650767316186)(js Web APIs.assets/QQ图片20220417142500.png)]
5秒后自动关闭广告案例
案例分析:1、5秒之后,就把这个广告隐藏起来
2、用定时器setTimeout
<!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>
<img src="../images/QQ图片20220415101649.jpg" alt="" class="ad">
<script>
var ad = document.querySelector('.ad');
setTimeout(function(){
ad.style.display = 'none';
},5000)
</script>
</body>
</html>
停止setTimeout()定时器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFzgeydB-1650767316186)(js Web APIs.assets/7HO}D0}@O}@E}{OIB1Q65X.png)]
setInterval()定时器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dBR0Dszu-1650767316187)(js Web APIs.assets/QQ图片20220417145114.png)]
<!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>
<script>
setInterval(function(){
console.log('继续输出');
}, 1000)
</script>
</body>
</html>
倒计时案例
案例分析:1、这个倒计时是不断变化的,因此需要使用定时器来自动变化(setInterval)
2、三个黑色盒子里面分别存放时分秒
3、三个黑色盒子利用innerHTML放入计算的小时分钟秒数
4、第一次执行也是间隔毫秒数,因此刚刷新页面会有空白
5、最好采取封装函数的方式,这样可以先调用一次这个函数,防止刚开始刷新页面有空白问题
<!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>
<style>
div span{
display: inline-block;
width: 40px;
height: 40px;
color: #fff;
text-align: center;
line-height: 40px;
background-color: #333;
}
</style>
</head>
<body>
<div>
<span class="hour">1</span>
<span class="minute">2</span>
<span class="second">3</span>
</div>
<script>
// 1、获取元素
var hour = document.querySelector('.hour');
var minute = document.querySelector('.minute');
var second = document.querySelector('.second');
var inputTime = +new Date('2022-4-17 18:00:00');
// 开启定时器
countDown();
setInterval(countDown, 1000);
function countDown(){
var nowTime = +new Date();
var times = (inputTime - nowTime) / 1000;
var h = parseInt(times / 60 / 60 % 24);
h = h < 10 ? '0' + h : h;
hour.innerHTML = h;
var m = parseInt(times / 60 % 60);
m = m < 10 ? '0' + m : m;
minute.innerHTML = m;
var s = parseInt(times % 60);
s = s < 10 ? '0' + s : s;
second.innerHTML = s;
}
</script>
</body>
</html>
停止setInterval()定时器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Lyhbov9-1650767316188)(js Web APIs.assets/QQ图片20220417152000.png)]
<!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 class="begin">开启定时器</button>
<button class="stop">停止定时器</button>
<script>
var begin = document.querySelector('.begin');
var stop = document.querySelector('.stop');
var timer = null;
begin.addEventListener('click', function(){
// timer设置为全局变量
timer = setInterval(function(){
console.log('你好');
}, 1000);
})
stop.addEventListener('click', function(){
clearInterval(timer)
})
</script>
</body>
</html>
发送短信案例
点击按钮后,该按钮60秒之内不能再次点击,防止重复发送短信
案例分析:1、按钮点击之后,会禁用disabled为true
2、同时按钮里面的内容会变化,注意button里面的内容通过innerHTML修改
3、里面的描述是有变化的,因此需要用到定时器
4、定义一个变量,在定时器里面不断递减
5、如果变量为0说明到了时间,我们需要停止定时器,并且复原按钮初始状态
<!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>
手机号码:<input type="number"> <button>发送</button>
<script>
var btn = document.querySelector('button');
var time = 10;//剩下的描述
btn.addEventListener('click', function(){
btn.disabled = true;
var timer = setInterval(function(){
if(time == 0)
{
clearInterval(timer);
btn.disabled = false;
btn.innerHTML = '发送';
time = 10;
}else{
btn.innerHTML = '还剩下'+time+'秒';
time--;
}
}, 1000)
})
</script>
</body>
</html>
this指向问题
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象。
1、全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)
2、方法中this指向调用方法的对象
3、构造函数中this指向构造函数的实例。
JS执行机制
JS是单线程语言
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5UR1gvP-1650767316189)(js Web APIs.assets/QQ图片20220417164231.png)]
同步和异步
为了解决单线程造成的问题H5提出Web Worker标准,允许JS脚本创建多个线程。于是JS中出现了同步和异步
同步
前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。
异步
在做一件事情时,因为这件事情会花费很多时间,在做这件事的同时,可以处理其他事情。
本质区别:一条流水线上各个流程的执行顺序不同
同步任务
同步任务都是在主线程上执行,形成一个执行线
异步任务
JS的异步是通过回调函数实现的
一般而言,异步任务有以下三种类型:1、普通事件,如click、resize等
2、资源加载,如load、error等
3、定时器,包括setInterval、setTimeout等
异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)
执行机制
1、先执行执行栈中的同步任务
2、异步任务(回调函数)放到任务队列中
3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jG7L3ac5-1650767316191)(js Web APIs.assets/QQ图片20220417170719.png)]
location对象
window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。
URL
统一资源定位符是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EBR4ZDtd-1650767316192)(js Web APIs.assets/QQ图片20220418163354.png)]
location对象的属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EhKiw2al-1650767316193)(file:///C:\Users\sulli\Documents\Tencent Files\2524967263\Image\C2C\KD3}3{UJLWVKL}$]2VX`0Y0.png)]
href属性(常用)
<!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>点击</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
location.href = 'http://www.itcast.cn';//跳转页面
})
</script>
</body>
</html>
5秒之后跳转页面案例
案例分析:1、利用定时器做倒计时效果
2、时间到了,就跳转页面。使用location.href
<!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>
<div></div>
<script>
var div = document.querySelector('div');
var timer = 5;
function tiaozhuan(){
if(timer == 0){
location.href = 'http://www.itcast.cn';
}else{
div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页';
timer--;
}
}
tiaozhuan();
setInterval(tiaozhuan, 1000);
</script>
</body>
</html>
获取URL参数:不同页面参数传递案例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jiXD3EeX-1650767316194)(js Web APIs.assets/QQ图片20220418172827.png)]
登录页面代码:
<!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>
<form action="index.html">
用户名:<input type="text" name="uname">
<input type="submit" value="登录">
</form>
</body>
</html>
跳转页面代码:
<!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>
<div></div>
<script>
// console.log(location.search);
// ?uname=andy
// 1、先去掉? substr('起始的位置',截取几个字符)
var params = location.search.substr(1);
console.log(params);
// 2、利用+把字符串分割为数组 split('=')
var arr = params.split('=');
console.log(arr);
var div = document.querySelector('div');
// 3、把数据写入div中
div.innerHTML = arr[1] + '欢迎您';
</script>
</body>
</html>
location对象的方法
location对象方法 | 返回值 |
---|---|
location.assign() | 跟href一样,可以跳转页面(也称为重定向页面)记录浏览历史可以实现后退功能 |
location.replace() | 替换当前页面,因为不记录历史,所以不能后退页面 |
location.reload() | 重新加载页面,相当于刷新按钮或者f5 如果参数为true 强制刷新 ctrl+f5 |
navigator对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vzcjZr2x-1650767316196)(js Web APIs.assets/QQ图片20220418180119.png)]
history对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t9K01rfa-1650767316197)(js Web APIs.assets/QQ图片20220418180838.png)]
PC端网页特效
元素偏移量offset系列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcJcy4cf-1650767316198)(js Web APIs.assets/@A7E2NA1TTPOW84]{{0VW2P.png)]
offset与style的区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZdXn87Nk-1650767316200)(js Web APIs.assets/QQ图片20220418182220.png)]
案例:获取鼠标在盒子内的坐标
案例分析:1、在盒子内点击,想要得到鼠标距离盒子左右的距离
2、首先得到鼠标在页面中的坐标(e.pageX, e.pageY)
3、其次得到盒子在页面中的距离(box.offsetLeft, box.offsetTop)
4、用鼠标距离页面的坐标减去盒子在页面中的距离, 得到鼠标在盒子内的坐标。
5、如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动事件mousemove
<!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>
<style>
.box {
width: 200px;
height: 200px;
background-color: pink;
margin-top: 30px;
margin-left: 65px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var box = document.querySelector('.box');
box.addEventListener('mousemove', function(e){
var y = e.pageY - box.offsetTop;
var x = e.pageX - box.offsetLeft;
box.innerHTML = 'x坐标是' + x + 'y坐标是' + y;
})
</script>
</body>
</html>
案例:模态框拖拽
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PLeflKrC-1650767316201)(js Web APIs.assets/QQ图片20220419132200.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3xXrIyGq-1650767316202)(js Web APIs.assets/7{_VZS$IZ22Q]VH]`CR3EL.png)]
案例:仿京东放大镜
案例分析:1、整个案例可以分为三个功能模块
2、鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开隐藏2个盒子功能
3、黄色的遮挡层跟随鼠标功能
①、把鼠标坐标给遮挡层不合适。因为遮挡层坐标以父盒子为准
②、首先是获得鼠标在盒子的坐标
③、之后把数值给遮挡层作为left和top值
④、此时用到鼠标移动事件,但是还是在小图片盒子内移动
· ⑤、发现,遮挡层位置不对,需要再减去盒子自身高度和宽度的一半
⑥、遮挡层不能超出小图片盒子范围
⑦、如果小于0,就把坐标设置为0
⑧、如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离
⑨、遮挡层的最大移动距离:小图片盒子宽度减去遮挡层盒子宽度
4、移动黄色遮挡层,大图片跟随移动功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RRAcN9n1-1650767316203)(js Web APIs.assets/QQ图片20220419204757.png)]
元素可视区client系列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QyvyDhdp-1650767316205)(js Web APIs.assets/Y@`WDD55RA]OE@E}8FQ8GO3.png)]
立即执行函数
立即执行函数 (function() {})() 或者 (function() {}())
主要作用:创建一个独立的作用域,避免了命名冲突问题。不需要调用,自己立马执行函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QBlkxxU3-1650767316206)(js Web APIs.assets/COL0IEF5TMIPO7LQDV3}DDW.png)]
元素滚动scroll系列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xmkHuVJY-1650767316207)(js Web APIs.assets/QQ图片20220419213657.png)]
3.2页面被卷去的头部
如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时。页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发onscroll事件。
案例:仿淘宝固定侧边栏
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6IYx4xZY-1650767316208)(js Web APIs.assets/QQ图片20220419214711.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OATjfOu7-1650767316209)(js Web APIs.assets/QQ图片20220419220855.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZxM9z513-1650767316210)(js Web APIs.assets/QQ图片20220420142830.png)]
<!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>
<style>
.w{
width: 1200px;
margin: 10px auto;
}
.header{
height: 150px;
background-color: green;
}
.banner{
height: 300px;
background-color: blue;
}
.main{
height: 3000px;
background-color: purple;
}
.slider-bar{
position: absolute;
left: 50%;
top: 300px;
margin-left: 600px;
width: 45px;
height: 130px;
background-color: pink;
}
span{
position: absolute;
bottom: 0;
display: none;
}
</style>
</head>
<body>
<div class="slider-bar">
<span class="goBack">返回顶部</span>
</div>
<div class="header w">头部区域</div>
<div class="banner w">banner区域</div>
<div class="main w">主体部分</div>
<script>
// 1、获取元素
var sliderbar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');
var bannerTop = banner.offsetTop;//一定要写到滚动的外面
var sliderbarTop = sliderbar.offsetTop - bannerTop;
var main = document.querySelector('.main');
var goBack = document.querySelector('.goBack');
var mainTop = main.offsetTop;
// 2、页面滚动事件scroll
document.addEventListener('scroll', function(){
console.log(window.pageYOffset);
// 3、当页面被卷去头部大于等于 300 此时侧边栏改为固定定位
if(window.pageYOffset >= bannerTop){
sliderbar.style.position = 'fixed';
sliderbar.style.top = sliderbarTop + 'px';
}else{
sliderbar.style.position = 'absolute';
sliderbar.style.top = '300px';
}
if(window.pageYOffset >= mainTop){
goBack.style.display = 'block';
}else{
goBack.style.display = 'none';
}
})
</script>
</body>
</html>
三大系列总结
三大系列大小对比 | 作用 |
---|---|
element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回数值不带单位 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jbL5JOIk-1650767316211)(js Web APIs.assets/QQ图片20220420143717.png)]
主要用法:1、offset系列经常用于获得元素位置 offsetLeft offsetTop
2、client经常用于获取元素大小 clientWidth clientHeight
3、scroll经常用于获取滚动距离 scrollTop scrollLeft
mouseenter 和 mouseover的区别
mouseenter鼠标事件
1、当鼠标移动到元素上时就会触发mouseenter事件
2、类似mouseover,它们两者之间的差别是:mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter只会经过自身盒子触发。
3、之所以这样,是因为mouseenter不会冒泡
4、mouseenter搭配离开mouseleave同样不会冒泡
动画函数封装
动画实现原理
核心原理:通过定时器setInterval()不断移动盒子位置
实现步骤:1、获得盒子当前位置
2、让盒子在当前位置加1个移动距离
3、利用定时器不断重复这个操作
4、加一个结束定时器的条件
5、注意此元素需要添加定位,才能使用element.style.left
<!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>
<style>
div {
position: absolute;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
// 动画原理
var div = document.querySelector('div');
var timer = setInterval(function(){
if(div.offsetLeft >= 400){
// 停止动画
clearInterval(timer);
}else{
div.style.left = div.offsetLeft + 1 + 'px';
}
},30);
</script>
</body>
</html>
动画函数简单封装
注意函数需要传递2个参数,动画对象和移动到的距离
<!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>
<style>
div {
position: absolute;
width: 100px;
height: 100px;
background-color: pink;
}
span{
position: absolute;
left: 0;
top: 200px;
display: block;
width: 150px;
height: 150px;
background-color: purple;
}
</style>
</head>
<body>
<div></div>
<span></span>
<script>
// 简单动画函数封装obj目标对象 target 目标位置
function animate(obj, target){
var timer = setInterval(function(){
if(obj.offsetLeft >= target){
// 停止动画
clearInterval(timer);
}else{
obj.style.left = obj.offsetLeft + 1 + 'px';
}
},30);
}
// 动画原理
var div = document.querySelector('div');
var span = document.querySelector('span');
// 调用函数
animate(div,300);
animate(span,200);
</script>
</body>
</html>
动画函数给不同元素记录不同定时器
如果多个元素都使用这个动画函数,每次都要var声明定时器。我们可以给不同的元素使用不同的定时器(自己专门用自己的定时器)
核心原理:利用Js是一门动态语言,可以很方便的给当前对象添加属性
// 简单动画函数封装obj目标对象 target 目标位置
//给不同的元素指定了不同的定时器
//当不断点击按钮,启动动画时,元素的速度会越来越快,因为开启了太多的定时器
//解决方案就是 让元素只有一个定时器执行
function animate(obj, target){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
if(obj.offsetLeft >= target){
// 停止动画
clearInterval(obj.timer);
}else{
obj.style.left = obj.offsetLeft + 1 + 'px';
}
},30);
}
// 动画原理
var div = document.querySelector('div');
var span = document.querySelector('span');
// 调用函数
animate(div,300);
animate(span,200);
缓动动画效果原理
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
思路:1、让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
2、核心算法:(目标值-现在的位置)/ 10 作为每次移动的距离步长
3、停止的条件:让当前盒子位置等于目标位置就停止定时器
<!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>
<style>
div {
position: absolute;
width: 100px;
height: 100px;
background-color: pink;
}
span{
position: absolute;
left: 0;
top: 200px;
display: block;
width: 150px;
height: 150px;
background-color: purple;
}
</style>
</head>
<body>
<div></div>
<span></span>
<button>点击按钮动画移动</button>
<script>
// 简单动画函数封装obj目标对象 target 目标位置
function animate(obj, target){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
// 步长值写到定时器的里面
// 把步长值改为整数 不要出现小数的问题
var step =Math.ceil(( target - obj.offsetLeft) / 10);
if(obj.offsetLeft >= target){
// 停止动画
clearInterval(obj.timer);
}else{
// 缓动动画:把步长1 改为一个慢慢变小的值
obj.style.left = obj.offsetLeft + step + 'px';
}
},30);
}
// 动画原理
var div = document.querySelector('div');
var span = document.querySelector('span');
var btn = document.querySelector('button');
// 调用函数
animate(div,800);
btn.addEventListener('click', function(){
// 调用函数
animate(span,500);
})
</script>
</body>
</html>
区别:1、匀速动画就是盒子当前的位置 + 固定的值
2、缓动动画就是盒子当前的位置 + 变化的值((目标值-现在的值)/ 10)
动画函数多个目标值之间移动
可以让动画函数从800移动到500
当我们点击按钮时,判断步长是正值还是负值
1、如果是正值,则步长往大了取整
2、如果是负值,则步长往小了取整
动画函数添加回调函数
回调函数原理:函数可以作为一个参数。将这个函数作为参数传递到另一个函数里面,当那个函数执行完之后,再执行传进去的函数,这个过程叫做回调。
回调函数写的位置:定时器结束的位置
<!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>
<style>
div {
position: absolute;
width: 100px;
height: 100px;
background-color: pink;
}
span{
position: absolute;
left: 0;
top: 200px;
display: block;
width: 150px;
height: 150px;
background-color: purple;
}
</style>
</head>
<body>
<div></div>
<span></span>
<button class="btn500">点击按钮动画移动500</button>
<button class="btn800">800</button>
<script>
// 简单动画函数封装obj目标对象 target 目标位置
function animate(obj, target, callback){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
// 步长值写到定时器的里面
// 把步长值改为整数 不要出现小数的问题
// var step =Math.ceil(( target - obj.offsetLeft) / 10);
var step =( target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == target){
// 停止动画
clearInterval(obj.timer);
if(callback)
{
callback();
}
}
// 缓动动画:把步长1 改为一个慢慢变小的值
obj.style.left = obj.offsetLeft + step + 'px';
},15);
}
// 动画原理
var div = document.querySelector('div');
var span = document.querySelector('span');
var btn500 = document.querySelector('.btn500');
var btn800 = document.querySelector('.btn800');
// 调用函数
animate(div,800);
btn500.addEventListener('click', function(){
// 调用函数
animate(span,500);
})
btn800.addEventListener('click', function(){
// 调用函数
animate(span,800, function(){
span.style.backgroundColor = 'red';
console.log('nihao');
});
})
</script>
</body>
</html>
动画函数封装到单独JS文件里面
因为以后经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可
1、单独新建一个JS文件
案例:轮播图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDOJn47B-1650767316212)(js Web APIs.assets/QQ图片20220421181834.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GePYn5vw-1650767316213)(js Web APIs.assets/QQ图片20220422143800.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HrgG1bcu-1650767316213)(js Web APIs.assets/QQ图片20220422143930.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-smyO3Nnw-1650767316214)(js Web APIs.assets/QQ图片20220422145412.png)]
节流阀
防止轮播图按钮连续点击造成播放过快
节流阀目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发
核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。
150px;
height: 150px;
background-color: purple;
}
动画函数封装到单独JS文件里面
因为以后经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可
1、单独新建一个JS文件
案例:轮播图
[外链图片转存中…(img-pDOJn47B-1650767316212)]
[外链图片转存中…(img-GePYn5vw-1650767316213)]
[外链图片转存中…(img-HrgG1bcu-1650767316213)]
[外链图片转存中…(img-smyO3Nnw-1650767316214)]
节流阀
防止轮播图按钮连续点击造成播放过快
节流阀目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发
核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。