js组成
JavaScript的组成
-
ECMAScript:
-
规定了js基础语法核心知识。
-
比如:变量、分支语句、循环语句、对象等等
-
-
Web APIs :
-
DOM 文档对象模型, 定义了一套操作HTML文档的API
-
BOM 浏览器对象模型,定义了一套操作浏览器窗口的API
-
什么是API
API: 应用程序接口(Application Programming Interface)
接口:无需关心内部如何实现,程序员只需要调用就可以很方便实现某些功能
web APIs 作用: JavaScript 去操作页面文档和浏览器
DOM简介
DOM(Document Object Model——文档对象模型)。
作用:DOM用来 操作网页文档,开发网页特效和实现用户交互
DOM的核心思想就是把网页内容当做对象来处理,通过对象的属性和方法对网页内容操作
document对象
是 DOM 里提供的一个对象,是DOM顶级对象作为网页内容的入口,所以它提供的属性和方都是用来访问和操作网页内容的。例:document.write()
获取DOM对象
利用css选择器来获取DOM元素
描述 | 属性/方法 | 效果 |
---|---|---|
获取DOM对象 | document.querySelector() | 获取指定的第一个元素 |
document.querySelectorAll() | 获取指定的所有元素 | |
操作元素内容 | 元素.innerText | 操作元素内容,不解析标签 |
元素.innerHTML | 操作元素内容,解析标签 | |
操作元素样式 | 元素.style.width | 通过style操作样式 |
元素.className | 通过类名操作样式 | |
元素.classList.add() | 增加类名 | |
元素.classList.remove() | 删除类名 | |
元素.classList.toggle() | 切换类名 | |
间隔函数 | setInterval(function() {}, 1000) | 定时器,每隔指定时间重复执行 |
语法 | 实例 | 描述 |
---|---|---|
getElementById | document.getElementById('box') | 根据id获取元素,单个元素 |
getElementsByTagName | document.getElementsByTagName('li') | 根据标签名获取元素,伪数组 |
getElementsByClassName | document.getElementsByClassName('one') | 根据类名获取元素,伪数组 |
getElementsByName | document.getElementsByName('sex') | 根据name属性值获取元素,伪数组 |
// 1. getElementById 根据id获取
const box = document.getElementById('box')
console.log(box)
// 2. getElementsByClassName 根据类名获取 返回伪数组
const items = document.getElementsByClassName('item')
console.log(items)
// 3. getElementsByTagName 根据标签名获取 返回伪数组
const ps = document.getElementsByTagName('p')
console.log(ps)
// 4. getElementsByName 根据name属性获取 返回伪数组
const inputs = document.getElementsByName('username')
console.log(inputs)
参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/querySelector
常用语法:
//document.querySelector('css选择器'),选择指定css选择器的第一个元素
const box=document.querySelector('div')
参数:包含一个或多个有效的CSS选择器 字符串
返回值: CSS选择器匹配的第一个元素对象 ,如果没有匹配到,则返回 null。
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box {
background-color: pink;
}
</style>
</head>
<body>
<!--
dom是用来操作也能元素(标签)
dom是将标签解析成dom对象--对象就有属性和方法--操作标签的
dom顶级的对象是document对象
-->
<div class="box">我是盒子</div>
<ul>
<li>5646</li>
<li>5646</li>
<li>5</li>
</ul>
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
</ol>
<script>
// 1.3 如果获取不到则返回 null
const p = document.querySelector('p')
console.log(p) // null
//通过css选择器获取元素,document.querySelector('css选择器')
//获取单个元素,匹配到的第一个元素
const box = document.querySelector(".box");
console.log(box); //只能单独输出内容
console.dir(box); //用来输出对象格式数据
//案例
const ul = document.querySelector("ul li:nth-child(3)");
console.dir(ul);// 只选择满足条件的第3个元素li
//获取多个元素 document.querySelectorALL('css选择器')
//All 方法获取到的是一个伪数组,具备数组的长度和索引
//获取的都是数组形式
//所以可以通过循环遍历的方式拿到每一个,但是不能使用数组的方法例如push()
const lis = document.querySelectorAll("ol li");
console.log(lis);// 只选择满足条件的第一个元素li
for (let i = 0; i < lis.length; i++) {
console.log(lis[i]);
}
</script>
</body>
</html>
选择指定css选择器的所有元素
语法:const lis = document.querySelectorAll('.nav li')
参数:包含一个或多个有效的CSS选择器 字符串
返回值:CSS选择器匹配的NodeList 伪数组
// 2. document.querySelectorAll() 选择指定css选择器的所有元素
// 2.1 参数还是字符串的css选择器
const lis = document.querySelectorAll('.nav li')
// 2.2 返回值是一个伪数组里面包含了所有的dom对象 li
console.log(lis)
// 2.3 伪数组
// (1) 有长度和索引号
// (2) 没有数组的一些常用方法 比如 push pop splice等方法
// lis.push(1)
// console.log(lis) // 因为lis是伪数组无法使用push方法所以报错
// 2.4 利用循环遍历伪数组得到里面的每一个元素对象
for (let i = 0; i < lis.length; i++) {
console.log(lis[i]) // 里面的每一个元素对象
}
// 2.5 即使只有1个元素,我们querySelectorAll 获得的也是一个伪数组,里面只有1个元素而已
const boxs = document.querySelectorAll('.box')
console.log(boxs)
操作元素内容
DOM对象可以操作页面标签,所以本质上就是操作DOM对象(增删改查)
如果想要操作标签元素的内容,则可以使用如下2种方式:
- 对象.innerText 属性
- 对象.innerHTML 属性
innerText
innerText
将文本内容添加/更新到任意标签位置,但是文本中包含的标签不会被解析。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>sdfi</div>
<script>
//操作元素内容属性
const box = document.querySelector("div");
//1。innerText
//获取内容 只会获取嵌套文本
//查
console.log(box.innerText);
//修改内容
box.innerText = "新值";
// 1.3 增
const box1 = document.querySelector('.box1')
console.log(box1)
box1.innerText='hdsfas'
// 1.4 删 给空字符串可以删除内容
box.innerText = ''
box1.innerText = ''
//不解析标签(不认识),原样输出
box.innerText = "<b>加粗</b>";
</script>
</body>
</html>
innerHTML
innerHTML
将文本内容添加/更新到任意标签位置,文本中包含的标签会被解析。
<script>
// 2. 对象.innerHTML 会解析标签,获取嵌套里面的所有内容
box.innerHTML = '<strong>hxm</strong>'
</script>
总结:如果文本内容中包含 html
标签时推荐使用 innerHTML
,否则建议使用 innerText
属性。
常用属性修改
可以通过DOM操作元素属性,比如通过 src 更换 图片地址,最常见的属性比如:href
、title
、src
等等
1,直接能过属性名修改,最简洁的语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>
<img src="" alt="" />
</div>
<script>
const arr = [
"./images/1.png",
"./images/2.png",
"./images/3.png",
"./images/4.png",
];
//设置常用属性 对象.属性=值
const img = document.querySelector("img");
//获取属性值
//查
console.log(img.src);
//设置属性值
//生成一个随机数
//改
const ran = Math.floor(Math.random() * arr.length);
img.src = arr[ran];
//增
img.title = "你好";
//删
img.src = "";
</script>
</body>
</html>
操作样式属性
2,DOM对象修改标签元素的样式属性
- 比如通过 轮播图小圆点自动更换颜色 样式
- 点击按钮可以滚动图片,这是移动的的位置 translateX 等等
三种操作方式
1,通过 style 属性操作元素样式
语法:
<script>
// 通过style操作元素样式
// 1. 先要获取这个box元素对象
const box = document.querySelector('.box')
// 2. 通过style来从操作样式
box.style.width = '300px'
box.style.marginTop = '50px'
box.style.backgroundColor = 'orange'
// 3. 注意事项
// 3.1 给样式赋值的时候,千万不要忘了加单位比如 300px
// 3.2 如果有-的样式,我们采取的是小驼峰命名法比如 marginTop
// 3.3 一定不要忘了加 style 属性
</script>
2,操作类名(className) 操作CSS
如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。就是把多个样式放到css一个类中,然后把这个类添加到这个元素身上。
<script>
// 通过类名操作元素样式
// 1. 获取box盒子
const box = document.querySelector('.box')
// 2. 利用类名操作元素样式
// box.className = 'hxm'
box.className = 'box hxm'
// 3. 利用类名操作样式添加的新的类名会覆盖掉原先的类名
</script>
注意:
1.由于class是关键字, 所以使用className去代替
2.className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类
3,通过 classList 操作类控制CSS
为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名。
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
/* .box {
width: 200px;
height: 200px;
color: #8df;
border: 1px solid red;
} */
.nav {
width: 300px;
height: 300px;
background-color: #8df;
color: red;
}
.box {
font-size: 30px;
text-align: center;
line-height: 300px;
border: 10px solid pink;
}
</style>
</head>
<body>
<!-- <div>文字</div>
<script>
//通过类名操作元素样式
//通过className属性的形式设置样式
const box = document.querySelector("div");
box.className = "box";
//问题:用新值换旧值
//场景:获取类名,但是用的不多
console.log(box.className);
</script> -->
<div class="nav">文字描述</div>
<script>
//需求:利用classList追加 删除 切换类名
const ds = document.querySelector("div");
//1,追加类名 在原类名的基础上,追加新类名
ds.classList.add("box");
//2,删除类名
ds.classList.remove("nav");
//3,切换类名 有则删除,没有则添加
ds.classList.toggle("nav");
//判断是否存在某个类名,存在返回true,否则false
console.log(ds.classList.contains("zcb"));
console.log(ds.classList.contains("nav"));
</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>轮播图点击切换</title>
<style>
* {
box-sizing: border-box;
}
.slider {
width: 560px;
height: 400px;
overflow: hidden;
}
.slider-wrapper {
width: 100%;
height: 320px;
}
.slider-wrapper img {
width: 100%;
height: 100%;
display: block;
}
.slider-footer {
height: 80px;
background-color: rgb(100, 67, 68);
padding: 12px 12px 0 12px;
position: relative;
}
.slider-footer .toggle {
position: absolute;
right: 0;
top: 12px;
display: flex;
}
.slider-footer .toggle button {
margin-right: 12px;
width: 28px;
height: 28px;
appearance: none;
border: none;
background: rgba(255, 255, 255, 0.1);
color: #fff;
border-radius: 4px;
cursor: pointer;
}
.slider-footer .toggle button:hover {
background: rgba(255, 255, 255, 0.2);
}
.slider-footer p {
margin: 0;
color: #fff;
font-size: 18px;
margin-bottom: 10px;
}
.slider-indicator {
margin: 0;
padding: 0;
list-style: none;
display: flex;
align-items: center;
}
.slider-indicator li {
width: 8px;
height: 8px;
margin: 4px;
border-radius: 50%;
background: #fff;
opacity: 0.4;
cursor: pointer;
}
.slider-indicator li.active {
width: 12px;
height: 12px;
opacity: 1;
}
</style>
</head>
<body>
<div class="slider">
<div class="slider-wrapper">
<img src="./images/slider01.jpg" alt="" />
</div>
<!-- 颜色,文字内容 -->
<div class="slider-footer">
<p>对人类来说会不会太超前了?</p>
<ul class="slider-indicator">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="toggle">
<button class="prev"><</button>
<button class="next">></button>
</div>
</div>
</div>
<script>
// 1. 初始数据
const sliderData = [
{
url: "./images/slider01.jpg",
title: "对人类来说会不会太超前了?",
color: "rgb(100, 67, 68)",
},
{
url: "./images/slider02.jpg",
title: "开启剑与雪的黑暗传说!",
color: "rgb(43, 35, 26)",
},
{
url: "./images/slider03.jpg",
title: "真正的jo厨出现了!",
color: "rgb(36, 31, 33)",
},
{
url: "./images/slider04.jpg",
title: "李玉刚:让世界通过B站看到东方大国文化",
color: "rgb(139, 98, 66)",
},
{
url: "./images/slider05.jpg",
title: "快来分享你的寒假日常吧~",
color: "rgb(67, 90, 92)",
},
{
url: "./images/slider06.jpg",
title: "哔哩哔哩小年YEAH",
color: "rgb(166, 131, 143)",
},
{
url: "./images/slider07.jpg",
title: "一站式解决你的电脑配置问题!!!",
color: "rgb(53, 29, 25)",
},
{
url: "./images/slider08.jpg",
title: "谁不想和小猫咪贴贴呢!",
color: "rgb(99, 72, 114)",
},
];
//生成随机数,为数组的索引
const sum = Math.floor(Math.random() * sliderData.length);
console.log(sum);
//根据随机数获取数组对象
console.log(sliderData[sum]);
//根据这个对象修改页面图片,文字,背景颜色
const img = document.querySelector(".slider-wrapper img");
console.log(img);
img.src = sliderData[sum].url;
//改变文字
//获取p标签
const p = document.querySelector(".slider-footer p");
console.log(p);
//更换内容
p.innerHTML = sliderData[sum].title;
//颜色
const footer = document.querySelector(".slider-footer");
//操作样式 背景色可以用style
footer.style.backgroundColor = sliderData[sum].color;
//小圆点改变
//移除以前的高亮效果
const a = document.querySelector(".active");
a.classList.remove("active");
//给当前添加高亮效果
const li = document.querySelector(
`.slider-indicator li:nth-child(${sum + 1})`
);
li.classList.add("active");
</script>
</body>
</html>
操作表单元素属性
表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框,正常的有属性有取值的跟其他的标签属性没有任何区别
获取: DOM对象.属性
设置: DOM对象.属性= 新值
表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示,比如实现禁用按钮,勾选按钮等,如果为 true
代表添加了该属性,如果是 false
代表移除了该属性,比如: disabled
、checked
、selected。
语法:
<script>
// 操作表单属性
// 1. 操作表单 type 和 value 属性
// 1.1 修改type属性
const username = document.querySelector('[name=username]')
console.log(username)
// username.type = 'password'
// 1.2 操作表单的 value 属性
// console.log(username.value) // 查
// username.value = '用户名试试' // 增
// username.value = '请输入用户名' // 改
// username.value = '' // 删
// 2. 禁用按钮或者是勾选复选框 布尔型
// 2.1 禁用按钮
const button = document.querySelector('button')
// button.disabled = true // true 是禁用
button.disabled = false // false 是不禁用
// 2.2 勾选复选框
const agree = document.querySelector('[name=agree]')
console.log(agree)
// agree.checked = true // true 是选中复选框
agree.checked = false // flase 是不选中复选框
</script>
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input type="text" value="" />
<br />
<input type="password" value="23" />
<br />
<input type="radio" />男
<br />
<button>按钮</button>
<br />
<select name="" id="">
<option value="">海南</option>
<option value="" selected>湖南</option>
</select>
<script>
//value属性 收集用户输入的值
const uname = document.querySelector('[type="text"]');
//获取 对象.value
//设置 对象的value属性 对象.value=值
// uname.value = "xiaod";
console.log(uname);
//type属性,规定input的类型
const pwd = document.querySelector('[type="password"]');
console.log(pwd.type); //查看属性类型
pwd.type = "text"; //更改属性类型
//修改单选或复选按钮的选中 --checked
const radio = document.querySelector('[type="radio"]');
//获取
console.log(radio.checked);
//设置false表示不选中,true表示选中
radio.checked = true;
//禁止使用表单--按钮类 对象.disabled
const btn = document.querySelector("button");
//获取
console.log(btn.disabled);
//设置true表示禁用。false表示启用
btn.disabled = true;
//使用selected设置和获取选中项判断是否被选中,选中为true否则为false
const option = document.querySelector("select option:last-child");
console.log(option.selected);
</script>
</body>
</html>
自定义属性
标准属性: 标签天生自带的属性 比如class、id、title等, 可以直接使用点语法操作比如:对象.title
。
自定义属性:
- 在html5中推出来了专门的data-自定义属性
- 使用场景:通过自定义属性可以存储数据,后期可以使用这个数据
- 在标签上一律以data-开头
- 在DOM对象上一律以dataset对象方式获取
语法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div data-index="0" data-id="oyyy"></div>
<!-- 语法:在标签里 data-自定义属性=值
作用:保存某些数据,后续使用
获取 对象.dataset 对象集合
对象.属性名 能获取到属性值
-->
<script>
const div = document.querySelector("div");
console.log(div.dataset); //获取的数据{index:0,id:'oyyy'}
console.log(div.dataset.id); //获取属性值
console.log(div.dataset.index); //获取属性值
</script>
</body>
</html>
定时器-间隔函数
网页中经常会需要一种功能:每隔一段时间需要自动执行一段代码,不需要我们手动去触发,例如:网页中的倒计时
,定时器函数有两种: 间隔函数
和 延迟函数
setInterval
是 JavaScript 中内置的函数,它的作用是间隔固定的时间自动重复执行另一个函数,也叫定时器函数。
开启定时器:
语法:
<script>
setInterval(function () {
console.log('我是1秒钟执行一次')
}, 1000)
</script>
作用:每隔一段时间调用这个函数
注意:间隔时间单位是毫秒
关闭定时器
需要定时器变量名
来关闭,返回的是一个唯一的数字
。
<script>
let timer = setInterval(repeat, 1000) // 注意调用的时候直接写函数名字不需要写小括号
console.log(timer) // 1
let timer1 = setInterval(repeat, 1000) // 注意调用的时候直接写函数名字不需要写小括号
console.log(timer1) // 2
// 2. 关闭定时器
clearInterval(timer)</script>
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- setInterval(函数,间隔时间)
作用:每隔一段时间调用这个函数,间隔时间单位是毫秒,可以每隔指定时间自动重复执行某些代码
-->
<script>
// function setName() {
// console.log("xiao");
// }
// //setInterval(函数,间隔时间)
// setInterval(setName, 1000);
// //方法2
// setInterval(function () {
// console.log("xiao");
// }, 1000);
// //开启定时器
// //输出的每一个数为定时器的Id
// const timeId = setInterval(function () {
// console.log("xiao");
// }, 1000);
// console.log(timeId);
//关闭定时器
// let 变量名=setInterval(函数,间隔时间)
// clearInterval(变量名)
//一般不是开启就清除,有一个条件限制
let num = 1;
function setName() {
num++;
console.log("hi");
//限制条件
if (num === 4) clearInterval(timeId);
}
let timeId = setInterval(setName, 1000);
</script>
</body>
</html>
事件监听
以前写的代码都是自动执行的,我们希望一段代码在某个特定的时机才去执行,比如
-
点击按钮可以弹出警示框
-
比如鼠标经过显示下拉菜单等等
-
所以通过事件监听可以解决这个问题
事件
事件是程序在运行的时候,发生的特定动作或者特定的事情,比如,点击按钮,鼠标经过等等。
事件监听
事件发生后,想要执行的代码写到事件处理函数
里面
-
当触发指定的事件时,则事件处理函数就会被执行
-
事件监听是将事件处理函数注册到元素对象身上
-
事件监听也称为: 事件注册、事件绑定
语法: 元素对象.addEventListener('事件类型', 事件处理函数)
事件监听三要素
-
事件源(谁被触发了)
-
事件类型 (什么情况下触发,点击还是鼠标经过等)
-
事件处理函数(要做什么事情)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>按钮</button>
<script>
//点击按钮弹出警示框
const but = document.querySelector("button");
// 事件三要素=>事件源.addEventListener('事件类型',事件处理函数)
but.addEventListener("click", function () {
alert("点击后执行");
});
</script>
</body>
</html>
注意:
1.事件类型要加引号,小写
2.函数是点击之后再去执行,每次点击都会执行一次
回调函数
回调函数:当一个函数当做参数
来传递给另外一个函数的时候,这个函数就是回调函数(回头调用
的函数)
作用:完成某些特定任务
<script>
// 1. 定时器间隔函数,里面第一个参数又是函数,这个匿名函数就是回调函数
setInterval(function () {
console.log('我是回调函数')
}, 1000)
// 2. addEventListener 函数的第二个参数也是函数,这个匿名函数也是回调函数
btn.addEventListener('click', function () {
console.log('我是回调函数')
})
</script>
事件监听版本
1,DOM0 事件,事件源.on事件类型 = function() { }
btn.onclick = function () {
alert('我是弹窗1')
}
2, DOM 2事件,事件源.addEventListener(事件类型,事件处理函数)
btn.addEventListener('click', function () {
console.log('我是回调函数')
})
区别:
on 方式同名事件会被覆盖,addEventListener则不会,同时拥有事件更多特性,推荐使用
事件类型
将众多的事件类型分类可分为:鼠标事件、键盘事件、表单事件、焦点事件等,我们逐一展开学习。事件类型的大小写敏感的字符串,统一用小写字母
1,鼠标事件
鼠标事件是指跟鼠标操作相关的事件,如单击、经过等。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
width: 300px;
height: 300px;
background-color: #8df;
text-align: center;
line-height: 300px;
color: orange;
font-size: 30px;
margin: 100px auto;
}
</style>
</head>
<body>
<div>九四</div>
<script>
//鼠标事件,
const div = document.querySelector("div");
//点击,表示点击后执行语句
div.addEventListener("click", function () {
alert("oyyy");
});
//鼠标经过/鼠标进入,表示点击后执行
div.addEventListener("mouseenter", function () {
alert("oy");
});
//鼠标离开,表示点击后执行
div.addEventListener("mouseleave", function () {
alert("hxm");
});
</script>
</body>
</html>
焦点事件
主要是针对于表单是否获得光标的事件, 获得焦点 focus 、失去焦点 blur。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input type="text" class="one" />
<br />
<input type="text" class="two" />
<script>
//焦点===文本框,作用域
const one = document.querySelector(".one");
//获取元素,获得焦点
//当文本域获取焦点后执行函数
one.addEventListener("focus", function () {
console.log("666");
});
one.addEventListener("blur", function () {
console.log("999");
});
// 2. 拓展 自动获得焦点 focus() 自动失去焦点 blur()
//默认让two盒子自动获取焦点
const two = document.querySelector(".two");
two.focus();
</script>
</body>
</html>
键盘事件和 input事件
事件 | 触发时机 | 得到表单值 |
---|---|---|
keydown | 按下键盘时触发 | 不带最后一次按键值 ab |
keyup | 弹起键盘时触发 | 输入内容 abc |
input | 表单value发生变化时触发 | 输入内容 abc |
<!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>input事件和键盘事件</title>
<style>
textarea {
width: 300px;
height: 30px;
padding: 10px;
border-color: transparent;
outline: none;
resize: none;
background: #f5f5f5;
border-radius: 4px;
}
</style>
</head>
<body>
<textarea id="tx" placeholder="发一条友善的评论" rows="2"></textarea>
<script>
// 获取元素
const tx = document.querySelector('#tx')
// 1. 键盘事件
// 1.1 键盘按下事件 keydown 当我们按下键盘的时候就触发
tx.addEventListener('keydown', function () {
console.log('我是keydown事件' + tx.value)
})
// 1.2 键盘弹起事件 keyup 当我们键盘弹起的时候就触发
tx.addEventListener('keyup', function () {
console.log('我是keyup事件' + tx.value)
})
// 2. 用户输入事件 input ,是表单value的值发生变化的时候触发
tx.addEventListener('input', function () {
console.log('我是input事件' + tx.value)
})
// 3. 注意事项
// 3.1 执行顺序 keydown → input → keyup
// 3.2 keydown 获取值的时候得不到最后一次按键的值, keyup和input可以得到用户输入内容
</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>小米搜索框显示隐藏案例</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
.mi {
position: relative;
width: 223px;
margin: 100px auto;
}
.mi .search-text {
width: 223px;
height: 48px;
padding: 0 10px;
font-size: 14px;
line-height: 48px;
border: 1px solid #e0e0e0;
outline: none;
}
/* 搜索框边框颜色 */
.mi .search {
border: 1px solid #ff6700;
}
/* 下拉菜单 */
.result-list {
display: none;
position: absolute;
left: 0;
top: 48px;
width: 223px;
border: 1px solid #ff6700;
border-top: 0;
background: #fff;
}
.result-list a {
display: block;
padding: 6px 15px;
font-size: 12px;
color: #424242;
text-decoration: none;
}
.result-list a:hover {
background-color: #eee;
}
</style>
</head>
<body>
<div class="mi">
<input type="search" placeholder="小米笔记本" class="search-text" />
<ul class="result-list">
<li><a href="#">全部商品</a></li>
<li><a href="#">小米11</a></li>
<li><a href="#">小米10S</a></li>
<li><a href="#">小米笔记本</a></li>
<li><a href="#">小米手机</a></li>
<li><a href="#">黑鲨4</a></li>
<li><a href="#">空调</a></li>
</ul>
</div>
<script>
//需求:表单获取焦点显示下拉菜单并且改变边框样式(类名,search),当表单失去焦点
//,隐藏下拉菜单,取消边框样式
//1隐藏下拉菜单
//2给菜单绑定获取焦点事件
const search = document.querySelector(".search-text");
const li = document.querySelector(".result-list");
search.addEventListener("focus", function () {
//表单有变框颜色
//通过添加类
search.classList.add("search");
//下拉菜单显示
li.style.display = "block";
});
//给表单绑定失去焦点事件
search.addEventListener("blur", function () {
//失去边框
search.classList.remove("search");
//隐藏下拉菜单
li.style.display = "none";
});
</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>评论回车发布</title>
<style>
.wrapper {
min-width: 400px;
max-width: 800px;
display: flex;
justify-content: flex-end;
}
.avatar {
overflow: hidden;
width: 48px;
height: 48px;
margin-right: 20px;
border-radius: 50%;
background: url(./images/avatar.jpg) no-repeat center / cover;
}
.wrapper textarea {
flex: 1;
height: 30px;
padding: 10px;
border-color: transparent;
outline: none;
resize: none;
background: #f5f5f5;
border-radius: 4px;
transition: all 0.5s;
}
.wrapper textarea:focus {
height: 50px;
border-color: #e4e4e4;
background: #fff;
}
.wrapper button {
width: 70px;
margin-left: 10px;
border: none;
color: #fff;
background: #00aeec;
border-radius: 4px;
cursor: pointer;
}
.wrapper .total {
margin-right: 80px;
margin-top: 5px;
color: #999;
opacity: 0;
transition: all 0.5s;
}
.list {
display: flex;
min-width: 400px;
max-width: 800px;
}
.list .item {
display: flex;
width: 100%;
}
.list .item .info {
flex: 1;
border-bottom: 1px dashed #e4e4e4;
padding-bottom: 10px;
}
.list .item p {
margin: 0;
}
.list .item .name {
color: #fb7299;
font-size: 14px;
font-weight: bold;
}
.list .item .text {
padding: 10px 0;
color: #333;
font-size: 13px;
}
.list .item .time {
color: #999;
font-size: 12px;
}
</style>
</head>
<body>
<div class="wrapper">
<i class="avatar"></i>
<textarea
id="tx"
placeholder="发一条友善的评论"
rows="2"
maxlength="200"
></textarea>
<button>发布</button>
</div>
<div class="wrapper">
<span class="total">0/200字</span>
</div>
<div class="list">
<div class="item" style="display: none">
<i class="avatar"></i>
<div class="info">
<p class="name">清风徐来</p>
<p class="text">
大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]
</p>
<p class="time">2099-10-10 20:29:21</p>
</div>
</div>
</div>
<script>
//获取元素
const tx = document.querySelector("#tx");
const total = document.querySelector(".total");
//获取文本域元素
const li = document.querySelector(".item");
//获取text元素替换文字
const text = document.querySelector(".text");
//给元素注册事件,获取焦点事件
tx.addEventListener("focus", function () {
total.style.opacity = 1;
});
//失去焦点事件
tx.addEventListener("blur", function () {
total.style.opacity = 0;
});
//统计字数
tx.addEventListener("input", function () {
//改变字数的数据
// console.log(tx.value);
//trim()方法可以去除字符串两边的空格
total.innerHTML = `${tx.value.trim().length}/200字`;
});
//回车发布评论,获取键盘事件
tx.addEventListener("keyup", function (e) {
// // console.log("6");
// //当按下回车键时输出文本域内容
// if (e.key === "Enter") {
// li.style.display = "flex";
// // tx.value获取用户输入的内容
// text.innerHTML = tx.value.trim();
// //清空文本域内容和计数消除
// tx.value = "";
// total.innerHTML = "0/200字";
// tx.blur(); //调用隐藏文字
// }
//方法2 调用click函数
if (e.key === "Enter") {
button.click();
}
});
//点击按钮也可以发布
const button = document.querySelector("button");
button.addEventListener("click", function () {
// console.log("6");
//当按下回车键时输出文本域内容
li.style.display = "flex";
// tx.value获取用户输入的内容
text.innerHTML = tx.value.trim();
//清空文本域内容和计数消除
tx.value = "";
total.innerHTML = "0/200字";
tx.blur(); //调用隐藏文字
});
</script>
</body>
</html>
事件对象
概念:事件对象也是个对象,这个对象里有事件触发时的相关信息,包含属性和方法,例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
使用场景 :可以判断用户按下哪个键,比如按下回车键可以发布新闻,可以判断鼠标点击了哪个元素,从而做相应的操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input type="text" />
<script>
const inp = document.querySelector("input");
//key属性 键盘事件,事件对象携带的属性
inp.addEventListener("keydown", function (e) {
console.log(e.key); //获取当前按下的按键名称
//e.key 判断按下了哪一个键
if (e.key === "Enter") {
console.log("666");
}
//e.targte 表示得到触发事件的元素
console.log(e.targte);
});
</script>
</body>
</html>
事件回调函数的第一个参数即所谓的事件对象,通常习惯性的将这个对数命名为event,ev
环境对象
作用:弄清楚this的指向,可以让我们代码更简洁 ,能够分析判断函数运行在不同环境中 this 所指代的对象。
- 函数的调用方式不同,this 指代的对象也不同
- 【谁调用, this 就是谁】 是判断 this 指向的粗略规则
- 直接调用函数,其实相当于是 window.函数,所以 this 指代 window
环境对象:指的是函数内部特殊的 this, 它指向一个对象,并且受当前环境影响
<body>
<button>点击</button>
<script>
// 环境对象 this 粗略规则: 谁调用函数,this就指向谁
// 1. 全局环境
// console.log(this) // this 指向 window 全局对象
// 2. 普通函数和间歇函数
setInterval(function(){
console.log(this)
},1000)
function fn() {
console.log(this) // this 指向 window 全局对象
}
window.fn()
// 3. 对象方法
const obj = {
uname: '佩奇',
sing: function () {
console.log(this) // this 指向 obj对象
}
}
obj.sing()
// 4. 事件
const btn1 = document.querySelector('button')
btn1.addEventListener('click', function () {
// console.log(this) // this 指向 btn 这个对象
// btn1.style.backgroundColor = 'pink'
this.style.backgroundColor = 'pink'
})
</script>
</body>
排他思想
是一种思路,目的是突出显示某个元素,比如,有多个元素,当鼠标经过时,只有当前元素会添加高亮样式,其余的元素移除样式。
目标:排除其它人,保留自己
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.active {
background-color: #8df;
}
</style>
</head>
<body>
<button class="active">1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<script>
//要求,鼠标经过每一个小盒子,当前盒子亮度显示
//先获取全部小盒子,给每一个盒子添加事件
const bttu = document.querySelectorAll("button");
//先打印
for (let i = 0; i < bttu.length; i++) {
// console.log(bttu[i]);
bttu[i].addEventListener("click", function () {
for (let j = 0; j < bttu.length; j++) {
//先 清除所样式
bttu[j].classList.remove("active");
}
//再给当前点击添加样式
bttu[i].classList.add("active");
});
}
</script>
</body>
</html>
事件流
事件流指的是事件完整执行过程中的流动路径 ,当触发事件时,会经历两个阶段,分别是捕获阶段
、冒泡阶段
。
事件捕获
概念:当一个元素的事件被触发时,会从DOM的根元素开始依次调用同名事件 (从外到里)
语法:元素.addEventListener('click', 回调函数, 是否使用捕获)
<body>
<div class="father">
父盒子
<div class="son">子盒子</div>
</div>
<script>
// 事件流
const father = document.querySelector('.father')
const son = document.querySelector('.son')
// 1. 事件捕获
// // 点击父盒子
father.addEventListener('click', function () {
alert('我是爸爸')
}, true) // 事件捕获
// 点击子盒子
son.addEventListener('click', function () {
alert('我是儿子')
}, true) // 事件捕获
</script>
</body>
注意:
addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)
若传入false代表冒泡阶段触发,默认就是 false
事件冒泡
概念:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
-
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的
同名事件
-
事件冒泡是
默认
存在的,或者第三个参数传入false
都是冒泡 -
实际工作都是使用事件冒泡为主
<body>
<div class="father">
父盒子
<div class="son">子盒子</div>
</div>
<script>
// 事件流
const father = document.querySelector('.father')
const son = document.querySelector('.son')
// 2. 事件冒泡
// 点击父盒子
father.addEventListener('click', function () {
alert('我是爸爸')
})
// 点击子盒子
son.addEventListener('click', function () {
alert('我是儿子')
}, false)
</script>
</body>
阻止冒泡
问题:因为默认就有冒泡阶段的存在,所以容易导致事件影响到父级元素(祖先元素)
需求:若想把事件就限制在当前元素内,就需要阻止事件冒泡
前提: 阻止事件冒泡需要拿到事件对象
<body>
<div class="father">
父盒子
<div class="son">子盒子</div>
</div>
<script>
// 事件流
const father = document.querySelector('.father')
const son = document.querySelector('.son')
// 1. 事件冒泡
// 点击父盒子
father.addEventListener('click', function () {
alert('我是爸爸')
})
// 点击子盒子
son.addEventListener('click', function (e) {
alert('我是儿子')
// 1.1 先获取事件对象
// 1.2 事件对象.stopPropagation() 注意是个方法
e.stopPropagation()
})
</script>
</body>
结论:事件对象中的
ev.stopPropagation
方法,专门用来阻止事件冒泡(事件传播)鼠标经过事件:
mouseover 和 mouseout 会有冒泡效果
mouseenter 和 mouseleave 没有冒泡效果 (推荐)
事件捕获和事件冒泡案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.father {
position: relative;
width: 400px;
height: 400px;
background-color: pink;
margin: 100px auto;
text-align: center;
}
.son {
position: absolute;
top: 100px;
left: 100px;
width: 200px;
height: 200px;
background-color: blue;
text-align: center;
line-height: 200px;
/* margin: 80px auto; */
}
</style>
</head>
<body>
<div class="father">
父盒子
<div class="son">子盒子</div>
</div>
<script>
//事件流
const father = document.querySelector(".father");
const son = document.querySelector(".son");
//默认是冒泡事件流
father.addEventListener("click", function () {
alert("666666");
});
son.addEventListener("click", function (e) {
//事件对象.stopPropagation() 阻止事件冒泡和捕获方法
e.stopPropagation();
alert("666");
});
</script>
</body>
</html>
事件委托
事件委托(EventDelegation):是JavaScript中注册事件的常用技巧,也称为事件委派、事件代理,简单理解:原本需要注册在子元素的事件委托给父元素,让父元素担当事件监听的职务
可以解决的问题
- 如果同时给多个元素注册事件,不需要利用循环多次注册事件
- 减少了大量的事件监听的性能
事件委托是利用事件流的特征解决一些开发需求的知识技巧
-
优点:减少注册次数,可以提高程序性能
-
原理:事件委托其实是利用事件冒泡的特点
-
给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件
-
利用事件委托方式如何得到当前点击的元素呢?
-
实现:事件对象.target. tagName 可以获得真正触发事件的元素
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<ul>
<li>第1个li</li>
<li>第2个li</li>
<li>第3个li</li>
<li>第4个li</li>
<li>第5个li</li>
</ul>
<script>
//事件委托
//事件绑定给父级,父级触发事件
const ul = document.querySelector("ul");
ul.addEventListener("click", function (e) {
// console.log("4");
// this.style.color = "#8df";
//通过事件对象,得到事件源e.target
// console.log(e.target);
//通过e.target.tagName得到事件源的标签名
// console.log(e.target.tagName);
if (e.target.tagName === "LI") {
e.target.style.color = "#8df";
}
});
</script>
</body>
</html>
阻止默认行为
阻止元素发生默认的行为,例如:当点击提交按钮时阻止对表单的提交,还有阻止链接的跳转等等
语法: 事件对象.preventDefault()
<body>
<form action="">
姓名: <input type="text" name="username">
<button>提交</button>
</form>
<a href="http://www.baidu.com">点击跳转</a>
<script>
// 阻止默认行为
const form = document.querySelector('form')
const input = document.querySelector('[name=username]')
form.addEventListener('submit', function (e) {
// 如果input表单的值为空则不允许提交
if (input.value === '') {
// return 无法阻止提交事件
e.preventDefault() // 阻止提交事件
}
})
document.querySelector('a').addEventListener('click', function (e) {
e.preventDefault()
})
</script>
</body>
事件解绑
移除事件处理函数,也称为解绑事件。
<body>
<button class="l2">移除L2事件监听</button>
<button class="l0">移除L0事件监听</button>
<script>
// 需求:按钮就点击一次,然后移除点击事件
// 1. l2事件监听
const l2 = document.querySelector('.l2')
l2.addEventListener('click', fn)
function fn() {
alert('我点击了')
// 移除事件监听
l2.removeEventListener('click', fn)
}
// 2. l0事件监听
const l0 = document.querySelector('.l0')
l0.onclick = function () {
alert('我点击了')
// 移除事件监听
l0.onclick = null
}
</script>
</body>
其他事件
页面加载事件
加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件,
为什么要学?
-
有些时候需要等页面资源全部处理完了做一些事情
-
老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到
语法:事件名:load
监听页面所有资源加载完毕:
window.addEventListener('load', function() {
// xxxxx
})
当初始的 HTML 文档被完全加载和解析完成之后就触发,而无需等待样式表、图像等完全加载
语法:事件名:DOMContentLoaded
document.addEventListener('DOMContentLoaded', function() {
// xxxxx
})
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script>
//页面加载事件,当所有的资源加载完毕后,触发这个事件
// window.addEventListener('load',function(){
// const div=document.querySelector('div')
// div.innerHTML='hd'
// })
//HTML元素加载事件--DOMContentLoaded
//只要HTML标签加载完成了。机会触发这个事件。它不会等待Css,JS,图片视频等执行完成再执行
document.addEventListener("DOMContentLoaded", function () {
const div = document.querySelector("div");
div.innerHTML = "hd";
});
</script>
</head>
<body>
<div>文本</div>
</body>
</html>
元素滚动事件
滚动条在滚动的时候持续触发的事件,
学习原因:很多网页需要检测用户把页面滚动到某个区域后做一些处理,比如固定导航栏,比如返回顶部
语法:事件名:scroll
监听整个页面滚动:
window.addEventListener('scroll', function() {
// xxxxx
})//document.documentElement 获取html标签
const top=document.documentElement.scrollTop//表示页面滚去多少像素,可以获取滚动的距离
scrollTop / scrollLeft, 被卷去的头部或者左侧,可以读取,也可以修改(赋值)
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
min-height: 3000px;
}
div {
width: 300px;
height: 100px;
overflow: auto;
}
</style>
</head>
<body>
<!-- <div>
1
<br />
1
<br />
1
<br />
1
<br />
1
<br />
1
<br />
1
<br />
1
<br />
1
<br />
1
<br />
</div> -->
<script>
//页面滚动事件
window.addEventListener("scroll", function () {
console.log("666");
//document.documentElement--获取html标签
const top = document.documentElement.scrollTop;
console.log(top);
});
//元素添加滚动事件
const div = document.querySelector("div");
div.addEventListener("scroll", function () {
console.log(2);
});
</script>
</body>
</html>
页面尺寸事件
会在窗口尺寸改变的时候触发事件:
window.addEventListener('resize', function() {
// xxxxx
//获取body的宽度
console.log(document.body.clientWidth)
console.log(document.body.clientHeight)
})
clientWidth和clientHeight,获取元素的可见部分宽高(不包含border,margin,滚动条等)
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
window.addEventListener("resize", function () {
// console.log(2);
//获取body的宽度
console.log(document.body.clientWidth);
//获取body的高度
console.log(document.body.clientHeight);
});
</script>
</body>
</html>
元素尺寸与位置
获取元素的自身宽高、包含元素自身设置的宽高、padding、border
日期对象
日期对象:用来表示日期和时间的对象,
作用:可以得到当前系统日期和时间
Date是JavaScript内置对象,日期对象使用必须先实例化
:创建一个日期对象并获取时间,在代码中发现了 new
关键字时,一般将这个操作称为实例化
实例化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//实例化日期 new Date()
//获取当前日期
const dateNow = new Date();
document.write(dateNow);
//获取指定日期
const da = new Date("2024-4-8");
document.write(da);
</script>
</body>
</html>
格式化日期对象
方法 | 作用 | 说明 |
---|---|---|
getFullYear() | 获得年份 | 获取四位年份 |
getMonth() | 获得月份 | 取值为 0 ~ 11 |
getDate() | 获取月份中的每一天 | 不同月份取值也不相同 |
getDay() | 获取星期 | 取值为 0 ~ 6 |
getHours() | 获取小时 | 取值为 0 ~ 23 |
getMinutes() | 获取分钟 | 取值为 0 ~ 59 |
getSeconds() | 获取秒 | 取值为 0 ~ 59 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//1,实例化日期对象
const da = new Date();
//2对日期对象进行格式化
// 获取年份
console.log(da.getFullYear());
//获取月份
console.log(da.getMonth() + 1); //因为月份从0开始记
//获取日期
console.log(da.getDate());
//获取星期
console.log(da.getDay());
//获取小时
console.log(da.getHours());
//获取分钟
console.log(da.getMinutes());
//获取秒钟
console.log(da.getSeconds());
</script>
</body>
</html>
格式化日期对象另外方法
方法 | 作用 | 说明 |
---|---|---|
toLocaleString() | 返回该日期对象的字符串(包含日期和时间) | 2099/9/20 18:30:43 |
toLocaleDateString() | 返回日期对象日期部分的字符串 | 2099/9/20 |
toLocaleTimeString() | 返回日期对象时间部分的字符串 | 18:30:43 |
<body>
<div class="box"></div>
<script>
const date = new Date()
console.log(date.toLocaleString()) // 2023/1/27 23:19:20
console.log(date.toLocaleDateString()) // 2023/1/27
console.log(date.toLocaleTimeString()) // 23:19:20
// 1. 封装一个 getDateTime函数,里面格式化时间对象
function getDateTime() {
const date = new Date()
return date.toLocaleString()
}
// 注意: 先写上这句话,防止盒子有1秒的空白期
document.querySelector('.box').innerText = getDateTime()
// 3. 显示到box盒子里面,并且添加定时器
setInterval(function () {
document.querySelector('.box').innerText = getDateTime()
}, 1000)
</script>
</body>
案例:页面显示当前日期
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>2024年4月6号 21:30:50</div>
<script>
const div = document.querySelector("div");
//实例化日期
function getDateTime() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
//格式化时间
const hours =
date.getHours() >= 10 ? date.getHours() : "0" + date.getHours();
const minutes =
date.getMinutes() >= 10 ? date.getMinutes() : "0" + date.getMinutes();
const second =
date.getSeconds() >= 10 ? date.getSeconds() : "0" + date.getSeconds();
return `${year}年${month}月${day}日${hours}:${minutes}:${second}`;
}
const result = getDateTime();
div.innerHTML = getDateTime();
// document.write(result);
//定时执行函数
setInterval(function () {
div.innerHTML = getDateTime();
}, 1000);
// console.log(result);
</script>
</body>
</html>
时间戳
概念;是指1970年01月01日00时00分00秒起至现在的总毫秒数(数字型),它是一种特殊的计量时间的方式
使用场景: 计算倒计时效果,需要借助于时间戳完成
算法:
-
将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数
-
剩余时间毫秒数转换为年月日时分秒就是倒计时时间
获取时间戳的方法,分别为 getTime 和 Date.now 和 +new Date()
// 1. 实例化
const date = new Date()
// 2. 获取时间戳
console.log(date.getTime())
// 还有一种获取时间戳的方法
console.log(+new Date())
// 还有一种获取时间戳的方法
console.log(Date.now())
DOM 节点
DOM树:DOM 将 HTML文档以树状结构直观的表现出来,我们称之为 DOM 树 或者 节点树
节点(Node)是DOM树(节点树)中的单个点。包括文档本身、元素、文本以及注释都属于是节点。
-
元素节点
(重点)-
所有的标签 比如 body、 div
-
html 是根节点
-
-
属性节点
-
所有的属性 比如 href
-
-
文本节点
-
所有的文本
-
查找节点
利用节点关系查找节点,返回的都是对象
-
父节点
-
子节点
-
兄弟节点
有了查找节点可以使我们选择元素更加方便
父节点
语法:元素.parentNode
<!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>王者荣耀关闭登录案例</title>
<style>
.pop {
display: block;
visibility: visible;
position: fixed;
z-index: 9999;
left: 50%;
top: 50%;
width: 530px;
height: 254px;
margin-top: -127px;
margin-left: -265px;
background: url(./images1/login.webp) no-repeat;
}
.close {
position: absolute;
right: 0;
top: 0;
width: 40px;
height: 40px;
}
</style>
</head>
<body>
<div class="pop">
<a href="javascript:;" class="close"></a>
</div>
<script>
const a = document.querySelector(".close");
// console.log(a.parentNode);
const p = a.parentNode;
a.addEventListener("click", function () {
p.style.display = "none";
});
</script>
</body>
</html>
子节点
语法:父元素.children
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<ul>
<li>第1个li</li>
<li>第2个li</li>
<li>第3个li</li>
<li>第4个li</li>
<li>第5个li</li>
</ul>
<script>
//获取子节点元素
const ul = document.querySelector("ul");
// console.log(ul.children);
// console.log(ul.children[2]);
// console.log(ul.children[2].innerHTML);
//获取兄弟节点
const li3 = ul.children[2];
console.log(li3.previousElementSibling.innerHTML);
console.log(li3.nextElementSibling.innerHTML);
</script>
</body>
</html>
兄弟节点
<body>
<ul>
<li>我是第1个孩子</li>
<li>我是第2个孩子</li>
<li>我是第3个孩子</li>
<li>我是第4个孩子</li>
</ul>
<script>
// 2. 查询兄弟节点
const li2 = document.querySelector('ul li:nth-child(2)')
// console.log(li2)
console.log(li2.previousElementSibling) // 上一个兄弟
console.log(li2.nextElementSibling) // 下一个兄弟
console.log(ul.children[0]) // 第一个孩子
console.log(ul.children[2]) // 第三个孩子
</script>
</body>
增加节点
很多情况下,我们需要在页面中增加元素
-
比如,点击发布按钮,可以新增一条信息
一般情况下,我们新增节点,按照如下操作:
-
创建一个新的节点
-
把创建的新的节点放入到指定的元素内部
-
父元素最后一个子节点之后,插入节点元素,element代表元素
element.append()
2,父元素第一个子元素的之前,插入节点元素
element.prepend()
例如:
<body>
<ul>
<li>我是小li</li>
</ul>
<script>
// 1. 创建节点
const li = document.createElement('li')
li.innerHTML = '我是放到后面的'
console.log(li)
// 2. 追加给父元素
const ul = document.querySelector('ul')
// 2.1 append 放到ul 的最后面 类似css的 after伪元素
ul.append(li)
// 2.2 prepend放到 ul 的最前面 类似css的 before伪元素
const firstli = document.createElement('li')
firstli.innerHTML = '我是放到前面的'
ul.prepend(firstli)
</script>
</body>
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div></div>
<script>
//增加节点
//1创建节点
const span = document.createElement("span");
span.innerHTML = "666";
//追加节点
//元素后面追加
const div = document.querySelector("div");
// div.append(span);
div.prepend(span);
</script>
</body>
</html>
删除节点
语法: element.remove()
-
把对象从它所属的 DOM 树中删除
-
删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从DOM树中删除
<!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>删除节点</title>
</head>
<body>
<div class="remove">我要删除</div>
<div class="none">我要隐藏</div>
<script>
// 1. 删除节点, remove 会从dom树中删除这个元素
const remove = document.querySelector('.remove')
remove.remove()
// 2. display:none 隐藏元素,页面看不见,但是dom树中还存在这个标签
const none = document.querySelector('.none')
none.style.display = 'none'
</script>
</body>
</html>
M端事件
M端(移动端)有自己独特的地方。比如触屏事件 touch
(也称触摸事件),Android 和 IOS都有。
touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。
常见的触屏事件如下:
<body>
<div class="box"></div>
<script>
// 触摸事件
const box = document.querySelector('.box')
// 1. 手指触屏开始事件 touchstart
box.addEventListener('touchstart', function () {
console.log('我开始摸了')
})
// 2. 手指触屏滑动事件 touchmove
box.addEventListener('touchmove', function () {
console.log('我一直摸')
})
// 3. 手指触屏结束事件 touchend
box.addEventListener('touchend', function () {
console.log('我摸完了')
})
</script>
</body>
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
width: 300px;
height: 300px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
const div = document.querySelector("div");
div.addEventListener("touchstart", function () {
console.log("666");
});
div.addEventListener("touchmove", function () {
console.log("6");
});
div.addEventListener("touchend", function () {
console.log("666666");
});
</script>
</body>
</html>
JS插件
插件: 就是别人写好的一些代码,我们只需要复制对应的代码,就可以直接实现对应的效果,
学习插件的思路:
1.看官网。了解这个插件可以完成什么需求 Swiper中文网-轮播图幻灯片js插件,H5页面前端开发
2.查看基本使用流程 。 Swiper使用方法 - Swiper中文网
3.写个小demo。看在线演示,找到符合自己需求的demo Swiper演示 - Swiper中文网
4.应用的开发中。
AlloyFinger
AlloyFinger 是腾讯 AlloyTeam 团队开源的超轻量级 Web 手势插件,为元素注册各种手势事件
github地址:GitHub - AlloyTeam/AlloyFinger: Super tiny size multi-touch gestures library for the web. You can touch this →Super tiny size multi-touch gestures library for the web. You can touch this → - AlloyTeam/AlloyFingerhttps://github.com/AlloyTeam/AlloyFinger
使用步骤:
-
下载js库:http://alloyteam.github.io/AlloyFinger/alloy_finger.js
-
将AlloyFinger库引入当前文件:<scriptsrc="alloy_finger.js"></script>
或者使用在线地址:<script src="<https://unpkg.com/alloyfinger@0.1.16/alloy_finger.js>"></script>
3,配置
new AlloyFinger(element, { // element 是给哪个元素做滑动事件
swipe: function (e) {
// 滑动的时候要做的事情 e.direction 可以判断上下左右滑动 Left Right 等
}
})