JavaScript

书写位置

<!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>/*CSS代码*/</style></head>
<body>/*HTML代码*/<script>/*js代码*/</script>
</body>
</html>

表单

1、input的type属性值不同,表单的功能不同

<input type = '...'>

2、提示信息(占位文本)

<input type="password" placeholder="输入密码">

3、单选框type = radio,需要增加属性name,name属性值相同的只能选一个;添加checked表示默认选中男

<input type="radio" name="gender" checked> 男
<input type="radio" name="gender"> 女

4、上传文件 type = file,增加属性multiple表示一次可以上传多个文件

5、多选框 type = checkbox,增加checked属性表示默认选中

<input type="checkbox" checked> java
<input type="checkbox" > C++
<input type="checkbox" > python

check = true表示选中

6、下拉菜单select-option,为option增加selected属性表示默认显示

 <select><option>1</option><option>2</option><option>3</option><option>4</option><option selected>5</option>
</select>

7、label标签

增大表单控件的点击范围,写法:直接用label标签包裹住input标签

<label><input type="radio" name="gender">男</label>
<label><input type="radio" name="gender">女</label>
    <label><input type="checkbox" >java</label><label><input type="checkbox" >c++</label><label><input type="checkbox" >python</label>

8、按钮标签 <button type = '...'>按钮内容</button>

type属性值不同,按钮的功能不同

①type = submit,提交 ②type = reset,重置表单,要想使提交或重置生效,需要将表单包裹在form标签中

<form><input type="text" placeholder="请输入姓名"><br><br><input type="password" placeholder="请输入密码"><br><br>兴趣爱好 <input type="checkbox">java<input type="checkbox">c++<input type="checkbox">python<br><br><label><input type="radio" name="gender">男</label><label><input type="radio" name="gender">女</label><br><br><button type="reset">重置</button>
</form>

CSS的引入方式

CSS选择器

标签选择器

使用 标签名作为选择器,例如: p, h1, div, a, img......
<style>
p{color:red;  
}
</style>

类选择器

<style>
.red {
color: red;
}
</style>
<div class="red">这是 div 标签</div>
<div class="red size">div 标签</div>

注意:

Ⅰ、一个标签可以有多个类名,通过其中一个类名就可以找到这个标签;例如,通过item、active

都可以找到该div标签

<div class="item active"><img src="./images/tab00.png" alt="" /></div>

Ⅱ、该类名选择器表示选择类名同时为item和active的标签中间没有空格

.item.active {display: block;}<div class="item active"><img src="./images/tab00.png" alt="" /></div>
<div class="item"><img src="./images/tab01.png" alt="" /></div>
<div class="item"><img src="./images/tab02.png" alt="" /></div>
<div class="item"><img src="./images/tab03.png" alt="" /></div>
<div class="item"><img src="./images/tab04.png" alt="" /></div>

id选择器

<style>
#red {
color: red;
}
</style>
<div id="red">这是 div 标签</div>

不要忘记#

通配符选择器

查找页面 所有 标签,设置相同样式。
* {
color: red;
}

后代选择器

1、选择某元素的 所有后代元素
2、父选择器 子选择器 {......},父子选择器之间用 空格 隔开。
3、 父选择器 子选择器可以用标签选择器、类选择器、id选择器。
<style>
/*选择div下的所有span标签*/
div span {
color: red;
}
</style><div>
<span>这是 div 的儿子 span</span >
</div>

子代选择器

1、选择某元素最近的一个后代元素

2、父选择器>子选择器 {......}

/*选择div下的第一个span标签*/
div > span {
color: red;
}<div>
<span>这是 div 里面的 span</span>
<p>
<span>这是 div 里面的 p 里面的 span</span>
</p>
</div>

交集选择器

1、选中 同时满足多个条件 的元素。
2、 选择器1选择器2 {......},两个选择器 连着写
3、如果选择器1 2中有标签选择器,则标签选择器放在前面
/*选择p标签、类名为box的元素*/
p.box {
color: red;
}<p class="box">p 标签,使用了类选择器 box</p>
<p>p 标签</p>
<div class="box">div 标签,使用了类选择器 box</div>

选择a标签下,类名为active的标签

a.active {border-color: #e1251b;color: #e1251b;}<li><a class="active" href="javascript:;">精选</a></li>
<li><a href="javascript:;">美食</a></li>
<li><a href="javascript:;">百货</a></li>
<li><a href="javascript:;">个护</a></li>
<li><a href="javascript:;">预告</a></li>

伪类选择器

1、伪类表示元素某种状态,伪类选择器表示为元素的某种状态下设置样式
2、鼠标悬停状态: 选择器:hover{....}
a:hover {
color: red;
}</style>
<a href="#">a 标签</a>

鼠标悬停时a标签变为红色

3、焦点状态:选择器:focus{.....}

<style>input{width: 200px;transition: all 0.3s;}input:focus{width: 350px;}
</style>
<body><input type="text" name="" id="">
</body>

4、选择器:checked{...} 表示已经选中的复选框

<style>.ck:checked{width: 20px;  height: 20px;}
</style>
<body><input type="checkbox" class = 'ck'>1<input type="checkbox" class = 'ck'>2<input type="checkbox" class = 'ck'>3<input type="checkbox" class = 'ck'>4
</body>

注意:Ⅰ、 transition: all 0.3s属于css过渡属性,用于元素的某些属性发生变化时,添加平滑过渡效果;Ⅱ、例如:上例中,input标签获得焦点时输入框宽由200px变为350px,该变化不立刻发生,而是在0.3秒内平滑过渡

结构伪类选择器

E是CSS选择器

<style>li:first-chile:red;/*选择第一个li标签*/
</style><ul><li>li1</li><li>li2</li><li>li3</li><li>li4</li>
</ul>

属性选择器

选取所有带有 target属性值为"_blank" 的 <a> 元素;

a[target="_blank"] { background-color: yellow;
}

注意:写法:[]

JavaScript

 引入方式

JavaScript 程序不能独立运行,它需要被嵌入 HTML 中,然后浏览器才能执行 JavaScript 代码。通过 script 标签将 JavaScript 代码引入到 HTML 中,有两种方式:

内部方式

通过 script 标签包裹 JavaScript 代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JavaScript 基础 - 引入方式</title>
</head>
<body><!-- 内联形式:通过 script 标签包裹 JavaScript 代码 --><script>alert('嗨,欢迎来传智播学习前端技术!')</script>
</body>
</html>
外部形式

一般将 JavaScript 代码写在独立的以 .js 结尾的文件中,然后通过 script 标签的 src 属性引入

// demo.js
document.write('嗨,欢迎来传智播学习前端技术!')
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JavaScript 基础 - 引入方式</title>
</head>
<body><!-- 外部形式:通过 script 的 src 属性引入独立的 .js 文件 --><script src="demo.js"></script>
</body>
</html>

如果 script 标签使用 src 属性引入了某 .js 文件,那么 标签的代码会被忽略!!!如下代码所示:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JavaScript 基础 - 引入方式</title>
</head>
<body><!-- 外部形式:通过 script 的 src 属性引入独立的 .js 文件 --><script src="demo.js">// 此处的代码会被忽略掉!!!!alert(666);  </script>
</body>
</html>

数据类型

计算机世界中的万事成物都是数据。

计算机程序可以处理大量的数据,为了方便数据的管理,将数据分成了不同的类型:

注:通过 typeof 关键字检测数据类型

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>JavaScript 基础 - 数据类型</title>
</head>
<body><script> // 检测 1 是什么类型数据,结果为 numberdocument.write(typeof 1)</script>
</body>
</html>

数组

1、声明数组

let arr = [1,2,3,4]

2、数组操作方法

Ⅰ、增

①arr.push() :将一个或多个元素添加到数组的末尾

②arr.unshift():将一个或多个元素添加到数组的开头

Ⅱ、删

①arr.pop() :从数组中删除最后一个元素,并返回该元素的值

②arr.shift():从数组中删除第一个元素,并返回该元素的值

③arr.splic(start,count):从start位置开始,删除count个元素

模板字符串

1、用于拼接字符串和变量

2、若不使用模板字符串,需要频繁使用单引号和加号拼接字符串和变量

3、使用模板字符串:使用反引号``,用${}包裹住变量

数据类型转换

使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。

        let num1 = prompt()//输入1let num2 = prompt()//输入2document.write(num1+num2);//结果为12

隐式转换

1、 + 号两边只要有一个是字符串,都会把另外一个转成字符串

document.write(1+'1')//11

2、除了+以外的算术运算符 比如 - * / 等都会把数据转成数字类型

document.write(1-'1')//0

3、+号将数据可以转换成数字型

 alert(typeof +'1')//number

函数

匿名函数

function() {}

一般函数为

function 函数名() {}

使用方式:

函数表达式

将匿名函数赋值给一个变量,并且通过变量名称进行调用

let fn = function(){...}//匿名函数赋值给fn变量
fn();//调用
立即执行函数
(function(){...})()

对象

1、声明

let 对象名 = {属性名:属性值方法名:函数}
let obj = {uname:'pink'gender:'男'age:18'goods-name':'撒旦'sayHi:function(){...}
}

2、查属性名对应的属性值

方式1:obj.uname

方式2:obj['goods-name']

注意:属性goods-name只能通过方式2使用

3、遍历对象

let obj = {uname:'赵展鹏',age:18,gender:'男'}for (let key in obj) {//key获得属性名、obj[key]获得属性值console.log(key);console.log(`${key} = ${obj[key]}`)//uname = 赵展鹏、age = 18、gender = 男}

数组的遍历用 for(let i = 0;i<arr.len;i++)

4、内置对象Math

①常用方法:

random:生成0-1之间的随机数(包含0不包括1)

ceil:向上取整            floor:向下取整            max:找最大数       min:找最小数     
pow:幂运算              abs:绝对值            
生成0-10之间的一个随机数
Math.floor(Math.random()*11)

生成1-10之间的一个随机数

Math.floor(Math.random()*10)+1

简单数据类型&&引用数据类型

1、存储方式

简单数据类型包括number、boolen、string,这些类型的变量存储的是值,当将一个简单数据类型的值赋给另一个变量时,实际发生的是值的复制,即两个变量拥有各自独立的值。

引用数据类型包括object、array、function、Data这些类型的变量存储的是内存地址(即引用)。当将一个引用类型的变量赋给另一个变量时,实际的是内存地址的复制,这意味着两个变量指向同一个对象。

2、比较方式

当比较两个简单数据类型的变量时,比较的是它们的实际值

当比较两个引用数据类型的变量时,比较的是它们的引用地址,即它们是否指向同一个对象。

3、内存分配

简单数据类型的值通常存储在中。

引用数据类型的值存储在堆内存中,而栈中保存的是指向堆中的指针。

4、能否用const修饰

let num = 1
num = num+1

num不能用const修饰

let arr = [1,2,3]
arr.push(4)

arr可以用const修饰,因为arr本身存储的是地址,该地址永远不会变,故可以用const修饰;

但以下情况arr存储的地址会变

let arr = [1,2,3]
arr = ['111','22','333']

arr由数组【1,2,3】的地址变为数组【'111','22','333'】的地址了,故此时arr不能用const修饰

 DOM

文档对象模型,是用来操作网页内容的;核心思想是把HTML标签当dom对象处理

获取DOM元素

1、document.querySelector('CSS选择器')

①通过CSS选择器获取DOM元素CSS选择器可以是标签选择器、id选择器、类选择器

②document.querySelector('CSS选择器'),返回值是第一个DOM对象

const obj =  document.querySelector('div')

③document.querySelector('CSS选择器')只选择匹配的第一个dom对象

2、document.querySelectorAll('CSS选择器')

①返回值是一个dom对象的集合,该集合可视为一个伪数组,可以使用索引(box[i])、也可以使用length(box.length),但该数组没有push、pop方法

<body><div>diiiii1</div><div>diiiii2</div><script>const box = document.querySelectorAll('div')console.log(box)</script>
</body>

使用集合中的单个dom元素时需要遍历

 for(let i = 0;i<box.length;i++){box[i].style.color = 'red';}

注意:以上两个获取DOM对象的方法中,参数均是CSS选择器,且需要用单引号

操作标签内容

1、innerText和innerHTML都可以获取dom对象中的内容

<body><div>diiiii</div>
<script>const box = document.querySelector('div')console.log(box.innerText);/*diiiii*/console.log(box.innerHTML);/*diiiii*/
</script>
</body>

2、也可以通过innerHTML或innerText修改dom对象中的内容

 box.innerHTML = '11111'

3、修改dom对象的内容时,innerText不解析标签、innerHTML解析标签

案例

从人名数组随机抽取一等奖、二等奖和三等奖,显示到对应的标签里面。人名数组为['周杰伦', '刘德华', '周星驰', 'Pink老师', '张学友']
<body><h1><strong>一等奖:</strong><span id = "one"></span></h1><h2>二等奖:<span id = "two"></span></h2><h3>三等奖:<span id = "three"></span></h3>
<script>const personArr = ['周杰伦', '刘德华', '周星驰', 'Pink老师', '张学友']/*一等奖*/const random1 = Math.floor(Math.random()*personArr.length)/*获取0-personArr.length随机数*/const one = document.querySelector('#one')/*获取one元素*/one.innerHTML = personArr[random1]/*把随机名字给one元素*/personArr.splice(random1,1)/*将名字从数组中删除*//*二等奖*/const random2 = Math.floor(Math.random()*personArr.length)/*获取0-personArr.length随机数*/const two = document.querySelector('#two')/*获取two元素*/two.innerHTML = personArr[random2]/*把随机名字给two元素*/personArr.splice(random2,1)/*将名字从数组中删除*//*三等奖*/const random3 = Math.floor(Math.random()*personArr.length)/*获取0-personArr.length随机数*/const three = document.querySelector('#three')/*获取two元素*/three.innerHTML = personArr[random3]/*把随机名字给two元素*/personArr.splice(random3,1)/*将名字从数组中删除*/</script>
</body>

操作标签属性

1、操作常用属性
2、操作css样式属性
①通过style:可以为标签添加css样式,那么便可以 通过style方式修改css的样式
<div></div><script>const box = document.querySelector('div')/*获取标签*/box.style.width = '200px'/*修改标签样式属性值*/box.style.backgroundColor = 'red'/*background-color采用驼峰命名*/</script>

注意:若属性中有-,如background-color,采用驼峰命名法

②通过className

<style>
.box{
width:200px
height:100px
}
.nav{
color:red
}
</style><div class = 'nav'>11111</div>
<script>
const div = querySelector('div')
div.className = 'box'
</script>

更新div标签的类名为box,其中box类名绑定了css样式

<script>
const div = querySelector('div')
div.className = 'box nav'
</script>

更新div标签的类名为box和nav,此时类选择器box和nav的css样式都会应用于div标签上

注意:可以为某个标签设置两个类名,写法如下;通过.box和.nav都能找到这个div标签

<div class = 'box nav'></div>

③通过classList

 <style>.box{width: 200px;height: 200px;background-color: aquamarine; /* 背景色 */padding: 20px; /* 内边距, 上 右 下 左 */border: 10px solid red; /* 边框, 宽度 线条类型 颜色 */margin: 30px; /* 外边距, 上 右 下 左 */}.nav{color:  red;}</style><div class = 'box'>111</div>

Ⅰ、追加类名add()

<script>const div = document.querySelector('div')div.classList.add('nav')
</script>
此时div的类名有两个:box和nav
Ⅱ、删除类名remove()
<script>const div = document.querySelector('div')div.classList.remove('nav')
</script>

Ⅲ、切换类名toggle():将div的类名由box切换到nav

script>const div = document.querySelector('div')div.classList.toggle('nav')
</script>

注:Ⅰ、classList和className参数若是类名选择器,则不需要加 . ,直接写类名即可

Ⅱ、className和classList 均先通过css类选择器设置好css样式,再为标签设置类名

操作表单属性

①表单.value获取表单内容
 <input type="text" value="电脑"><script>const input = document.querySelector('input')console.log(input.value)/*电脑*/</script>
②表单.type = ‘password’设置表单密码不可见
③ disabled、checked、selected
注:为按钮增加 disabled属性表示禁用按钮,为复(单)选框增加checked属性表示默认选中、为下拉菜单中option标签增加selected属性表示默认显示
<body><form><button type="reset">重置</button></form><script>const btn = document.querySelector('button')btn.disabled = true/*禁用按钮*/</script>
</body>

check = true表示选中;btn.disabled = true表示禁用按钮

自定义属性

①为标签设置自定义属性,以data-开头
②以dataset方式获取自定义属性
<body><form action=""><input type="text" placeholder="请输入姓名" data-id="1"><br><br><input type="password" placeholder="请输入密码" data-id="2"></form><script>const ipt = document.querySelector('input')console.log(ipt.dataset.id);/*获取自定义属性*/</script>
</body>

定时器

每隔一段时间自动执行一段代码

1、开启定时器

let timer = setInterval(函数,时间间隔)
开启定时器时有一个number类型的返回值,表示定时器号;时间间隔的单位是毫秒
2、停止定时器
clearInterval(定时器号)

3、案例:阅读用户协议倒计时

<body><textarea name="" id="" cols="30" rows="10">用户注册协议欢迎注册成为京东用户!在您注册过程中,您需要完成我们的注册流程并通过点击同意的形式在线签署以下协议,请您务必仔细阅读、充分理解协议中的条款内容后再点击同意(尤其是以粗体或下划线标识的条款,因为这些条款可能会明确您应履行的义务或对您的权利有所限制)。【请您注意】如果您不同意以下协议全部或任何条款约定,请您停止注册。您停止注册后将仅可以浏览我们的商品信息但无法享受我们的产品或服务。如您按照注册流程提示填写信息,阅读并点击同意上述协议且完成全部注册流程后,即表示您已充分阅读、理解并接受协议的全部内容,并表明您同意我们可以依据协议内容来处理您的个人信息,并同意我们将您的订单信息共享给为完成此订单所必须的第三方合作方(详情查看</textarea><br><button class="btn">我已经阅读用户协议(60)</button><script>//1、先禁用按钮const btn = document.querySelector('.btn')btn.disabled = true//2、开启定时器,60s后启用标签let i = 60function fn(){btn.innerHTML = `我已经阅读用户协议(${i})`i--if(i==-1){clearInterval(id)btn.disabled = falsebtn.innerHTML = "我已经阅读用户协议"    }}let id = setInterval(fn,1000)</script>
</body>

综合案例:定时轮播图

开启一个定时器,一秒钟轮播图切换一张照片

<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">&lt;</button><button class="next">&gt;</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 img = document.querySelector('img')const p = document.querySelector('.slider-footer p')const col = document.querySelector('.slider-footer')let i = 0let id = setInterval(function(){img.src = sliderData[i].url//更新图片p.innerHTML = sliderData[i].title//更新图片下的文字col.style.backgroundColor = sliderData[i].color//更新文字的背景颜色/*注意:以上索引i的范围为0-7*/document.querySelector('.slider-indicator .active').classList.remove('active')//先删除之前的li的小圆点样式,注意:第一个li标签需要手动添加active类名let li = document.querySelector(`.slider-indicator li:nth-child(${i+1})`)//i的范围从0-7,li标签的标号从1-8li.classList.add('active')i++if(i >= sliderData.length){i = 0}},1000)</script>
</body>

尤其注意小圆点样式怎么写:先删除之前li标签的小圆点样式(注意第一个li标签要手动加active类名),再加当前li标签的小圆点样式

事件监听

1、格式:元素对象.addEventListenser('事件类型',要执行的函数); 

2、事件类型(参数事件类型要加单引号

Ⅰ、鼠标事件:①鼠标单击事件click、鼠标经过事件mouseenter、鼠标离开事件mouseleave

Ⅱ、焦点事件:获得焦点focus、失去焦点blur(表单获得\失去光标)

Ⅲ、键盘事件:键盘按下keydown、键盘抬起keyup(发表评论时敲击“回车”评论自动发出)

Ⅳ、文本事件:用户输入input(监听文本框是否有数据输入,若有可以通过input.value获取输入的内容)

3、事件的三个组成部分:①事件源:即哪个dom对象触发事件,因此需要获取dom对象(querySelector) ②事件类型 ③事件调用的函数

案例:随机点名(click)

<body><h2>随机点名</h2><div class="box"><span>名字是:</span><div class="qs">这里显示姓名:</div></div><div class="btns"><button class="start">开始</button><button class="end">结束</button></div><script>// 数据数组const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']//获取开始按钮const btn_start = document.querySelector('.start')const div = document.querySelector('.box div')let timerId//注意,定时器号要定义为全局变量,这样在为结束按钮绑定事件时定时器号才能使用//为开始按钮绑定鼠标单击事件//该事件要完成的功能有开启一个定时器,随机闪动不同的名字btn_start.addEventListener('click',function(){timerId = setInterval(function(){//随机生成一个名字显示在div标签中const random = Math.floor(Math.random()*arr.length)div.innerHTML = `这里显示姓名:${arr[random]}`},50)})//获取结束按钮const btn_end = document.querySelector('.end')//为结束按钮绑定鼠标单击事件//该事件要完成:1、关闭定时器(关闭名字闪动),2、然后从随机抽取一个名字显示在div标签中 3、从arr中删除被选中的名字btn_end.addEventListener('click',function(){//1、关闭定时器(关闭名字闪动)clearInterval(timerId)//timerId为全局变量//2、然后从随机抽取一个名字显示在div标签中const random = Math.floor(Math.random()*arr.length)div.innerHTML = `这里显示姓名:${arr[random]}`//3、从arr中删除被选中的名字arr.splice(random,1)})</script>
</body>

案例:轮播图完整版

1、鼠标不经过时轮播图自动播放

2、鼠标经过时关闭定时器,通过点击按钮切换轮播图;鼠标离开时再开启定时器

3、需要的事件:click、mouseenter、mouseleave以及定时器的开关

<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">&lt;</button><button class="next">&gt;</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 img = document.querySelector('.slider-wrapper img')const p = document.querySelector('.slider-footer p')const div = document.querySelector('.slider-footer')let i = 0//1、通过按钮切换轮播图//1.1 获取按钮const btn_pre = document.querySelector('.prev')const btn_next = document.querySelector('.next')//1.2为按钮绑定事件btn_pre.addEventListener('click',function(){if(i<=0){   //i=0表示已是第一张图片,此时点击按钮时要回到最后一张图片i = sliderData.length-1toggle(i)}else{toggle(i-1)}i--  })btn_next.addEventListener('click',function(){if(i>=sliderData.length-1){  //i=sliderData.length-1表示已经是最后一张图片,点击按钮时回到第一张图片i = 0toggle(i)}else{toggle(i+1)}i++  })//2、鼠标不经过时轮播图自动播放let timerId = setInterval(function(){btn_next.click()//通过调用单击事件实现自动播放},1000)//3、鼠标经过大盒子时暂停定时器//3.1 获取大盒子对象const slider = document.querySelector('.slider')//3.2鼠标经过暂停定时器slider.addEventListener('mouseenter',function(){clearInterval(timerId)})//3.3鼠标移出开启定时器slider.addEventListener('mouseleave',function(){timerId = setInterval(function(){btn_next.click()},1000) })//抽取“渲染数据”的公共代码function toggle(num){img.src= sliderData[num].urlp.innerHTML = sliderData[num].titlediv.style.backgroundColor = sliderData[num].colordocument.querySelector('.slider-indicator .active').classList.remove('active')const li = document.querySelector(`.slider-indicator li:nth-child(${num+1})`)li.classList.add('active')}</script>
</body>

注意:如何关闭定时器后再开启这个定时器;

Ⅱ、轮播图自动播放可以通过调用点击事件函数实现,即btn_next.click(),用于程序化地触发btn_next 按钮的点击事件,而无需手动点击按钮;

Ⅲ、鼠标移入轮播图大盒子时暂停定时器

案例:小米搜索框(焦点事件)

需求:搜索框获得焦点时,弹出下拉菜单、同时搜索框颜色变为下拉菜单的颜色;搜索框失去焦点时隐藏(css样式中设置display:"none")下拉菜单

<body><div class="mi"><input type="search" placeholder="小米笔记本"> <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>//获取dom对象const ipt = document.querySelector('input[type=search]') //属性选择器const ul = document.querySelector('.result-list')//为dom对象绑定事件ipt.addEventListener('focus',function(){//首先需要css中默认下来菜单是隐藏的,获得焦点时将下拉菜单显示出来ul.style.display = 'block'//设置搜索框颜色同下拉菜单的颜色:只需要加search类即可,search类上绑定了css样式属性ipt.classList.add('search')})//失去焦点时隐藏下拉菜单ipt.addEventListener('blur',function(){//失去焦点时隐藏下拉菜单ul.style.display = 'none'ipt.classList.remove('search')})</script>
</body>

注意:Ⅰ、css中可以设置display = "none"表示隐藏该样式;display = "block"表示显示样式

Ⅱ、已为search类写好了css样式,标签需要该样式时直接为该标签添加类名search

案例:评论字数统计(文本事件)

需求:1、评论区域获得焦点时评论框缓慢变大、统计字数缓慢显示出来 2、统计评论区用户已输入的字数,保证输入字数≤200

注意:Ⅰ、通过input.value获取用户文本框输入的内容;此处需要为文本框绑定的事件为文本事件(input),监听文本框是否数据输入,若有则获取文本框的内容(input.value

 textarea.addEventListener('input',function(){span.innerHTML = `${ textarea.value.length}/200字`})

Ⅱ、需求1中缓慢变化都是通过css过渡实现的

.wrapper textarea {outline: none;border-color: transparent;resize: none;background: #f5f5f5;border-radius: 4px;flex: 1;padding: 10px;transition: all 0.5s;height: 30px;}.wrapper textarea:focus {border-color: #e4e4e4;background: #fff;height: 50px;}
.wrapper .total {margin-right: 80px;color: #999;margin-top: 5px;opacity: 0;transition: all 0.5s;}

评论框的缓慢变化通过css完成: .wrapper textarea:focus{....}

而评论字数缓慢显示通过js完成:即在textarea获得焦点时将 opacity改为1;

完整代码如下:

<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">2022-10-10 20:29:21</p></div></div></div><script>const total = document.querySelector('.wrapper .total')const textarea = document.querySelector('#tx')const span = document.querySelector('.total')//评论区域获得焦点时,评论字数缓慢显示出来textarea.addEventListener('focus',function(){total.style.opacity = 1})//评论区域失去焦点时,评论字数缓慢隐藏textarea.addEventListener('blur',function(){total.style.opacity = 0})//文本框输入事件textarea.addEventListener('input',function(){span.innerHTML = `${ textarea.value.length}/200字`})</script>
</body>

事件对象

1、什么是事件对象:表示事件触发时事件的相关信息,例如,鼠标单击事件触发时鼠标的位置...

2、事件绑定时的回调函数中第一个参数就是事件对象,一般命名为e、ev、event

ipt.addEventListener('click',function(e){})

3、事件对象常用属性:

① type:该事件的类型

<script>const btn = document.querySelector('button')btn.addEventListener('click',function(e){console.log(e.type);//click})</script>

②clientX/clientY:光标对于浏览器左上角的坐标

③key:用户按下的键盘的值

案例:回车发布评论

思路:

1、用户敲击回车(绑定keyup事件,判断事件对象的key是否为'Enter')之后将下方隐藏的内容显示(display:block)出来

2、如果用户评论的内容为一堆空格,则禁止发布该评论(trim方法) 

3、用户敲击回车发布评论后,将输入框中的内容清空

完整版代码:

<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">2022-10-10 20:29:21</p></div></div></div><script>const total = document.querySelector('.wrapper .total')const textarea = document.querySelector('#tx')const span = document.querySelector('.total')const item = document.querySelector('.item')const p = document.querySelector('.item .text')//评论区域获得焦点时,评论字数缓慢显示出来textarea.addEventListener('focus',function(){total.style.opacity = 1})//评论区域失去焦点时,评论字数缓慢隐藏textarea.addEventListener('blur',function(){total.style.opacity = 0})//文本框输入事件textarea.addEventListener('input',function(){span.innerHTML = `${ textarea.value.length}/200字`})//按下回车键时,将评论显示出来,textarea.addEventListener('keyup',function(e){if(e.key === 'Enter'){if(textarea.value.trim()!=''){//禁止用户评论一堆空格item.style.display = 'block'//将下方评论区显示出来p.innerHTML = textarea.value//将输入框内容渲染到评论区}textarea.value = ' '//清空输入框内容}})</script>
</body>

注意:Ⅰ、trim()方法是去掉字符串左右两侧的空格 Ⅱ、绑定事件时注意为哪个dom对象绑定事件,例如keyup事件绑定在textarea对象上,表示输入框中抬起键时触发事件

环境对象this

1、每一个函数内部都有一个特殊的变量this,它代表着当前函数运行时所处的环境

2、函数的调用方式不同,this指向也不同;this指向函数的调用者

<script>function fn(){console.log(',,,');}fn();//直接调用函数,相当于是window.fn();故this指向window</script>
button.addEventListener('click', function () {console.log(`轻轻的我来了`)})
//button调用的函数,故this指向button

回调函数

1、将函数A作为函数B的参数时,称函数A为回调函数

2、addEventListener函数中有一个匿名函数作为参数,该匿名函数就是回调函数;表示鼠标单击事件发生时触发一次回调函数

button.addEventListener('click', function () {console.log(`轻轻的我来了`)})

setInterval函数中也有一个匿名函数作为参数,该匿名函数就是回调函数;表示每隔35ms执行一次回调函数

let timerId = setInterval(function () {// 随机数random = parseInt(Math.random() * arr.length)// console.log(arr[random])qs.innerHTML = arr[random]}, 35)

案例:Tab栏切换 

注意:Ⅰ、需要为所有的a标签绑定鼠标经过事件;每一个事件触发的函数功能为:①将导航栏颜色换掉  ②将下面的图片换掉

 <style>* {margin: 0;padding: 0;}.tab {width: 590px;height: 340px;margin: 20px;border: 1px solid #e4e4e4;}.tab-nav {width: 100%;height: 60px;line-height: 60px;display: flex;justify-content: space-between;}.tab-nav h3 {font-size: 24px;font-weight: normal;margin-left: 20px;}.tab-nav ul {list-style: none;display: flex;justify-content: flex-end;}.tab-nav ul li {margin: 0 20px;font-size: 14px;}.tab-nav ul li a {text-decoration: none;border-bottom: 2px solid transparent;color: #333;}.tab-nav ul li a.active {border-color: #e1251b;color: #e1251b;}.tab-content {padding: 0 16px;}.tab-content .item {display: none;}.tab-content .item.active {display: block;}</style>
<body><div class="tab"><div class="tab-nav"><h3>每日特价</h3><ul><li><a class="active" href="javascript:;">精选</a></li><li><a href="javascript:;">美食</a></li><li><a href="javascript:;">百货</a></li><li><a href="javascript:;">个护</a></li><li><a href="javascript:;">预告</a></li></ul></div><div class="tab-content"><div class="item active"><img src="./images/tab00.png" alt="" /></div><div class="item"><img src="./images/tab01.png" alt="" /></div><div class="item"><img src="./images/tab02.png" alt="" /></div><div class="item"><img src="./images/tab03.png" alt="" /></div><div class="item"><img src="./images/tab04.png" alt="" /></div></div></div><script>//功能1:鼠标经过时,导航栏变样式:需要为所有的a标签绑定鼠标经过事件const as = document.querySelectorAll('.tab-nav a')for(let i = 0;i<as.length;i++){as[i].addEventListener('mouseenter',function(){//先将其他a标签的active类名去掉document.querySelector('.tab-nav .active').classList.remove('active')//再为这个a标签添加active类this.classList.add('active')//as[i]调用的函数,故this指向as[i]//功能2:将下面的图片换掉//将原来的active类名去掉document.querySelector('.tab-content .active').classList.remove('active')const divs = document.querySelectorAll('.tab-content div')//为本div标签添加active类名divs[i].classList.add('active')})}</script>
</body>

注意 Ⅰ、关注导航栏的红色样式怎么写,排他思想:先将其他a标签的active类名去掉:document.querySelector('.tab-content .active').classList.remove('active'),再为本a标签添加active类名 ;

案例:表单全选反选

需求:1、大复选框控制小复选框:点击“全选”框后实现下面复选框的全选和反选功能 2、小复选框控制大复选框:若下面复选框全部选中后,上面“全选框”自动选中

<body><table><tr><th class="allCheck"><input type="checkbox" name="" id="checkAll"> <span class="all">全选</span></th><th>商品</th><th>商家</th><th>价格</th></tr><tr><td><input type="checkbox" name="check" class="ck"></td><td>小米手机</td><td>小米</td><td>¥1999</td></tr><tr><td><input type="checkbox" name="check" class="ck"></td><td>小米净水器</td><td>小米</td><td>¥4999</td></tr><tr><td><input type="checkbox" name="check" class="ck"></td><td>小米电视</td><td>小米</td><td>¥5999</td></tr></table><script>const allCheck = document.querySelector('#checkAll')const cks = document.querySelectorAll('.ck')let flag = true//全选、反选:大复选框控制小复选框allCheck.addEventListener('click',function(){for(let i =0;i<cks.length;i++){cks[i].checked = allCheck.checked }})//小复选框控制大复选框//先为所有的小复选框绑定事件for(let i = 0;i<cks.length;i++){cks[i].addEventListener('click',function(){//获取所有已经选中的小复选框const smallchecked = document.querySelectorAll('.ck:checked')//若已选中的小复选框的数量==小复选框的数量,就把大复选框选上;否则,不选大复选框if(smallchecked.length === cks.length){allCheck.checked = true}else{allCheck.checked = false}})}</script>
</body>

注意Ⅰ、cks[i].checked = allCheck.checked  将所有小复选框的状态设置为大复选框的状态,即可通过大复选框控制小复选框

Ⅱ、已选中的小复选框为 document.querySelectorAll('.ck:checked'),其中.ck:checked是伪类选择器,表示已选中的复选框

事件捕获

1、事件从文档的根节点(通常是windowdocument对象)开始,沿着DOM树向下传递,直到到达事件的目标元素;传递路径上的同名事件都会执行(document->目标dom对象

2、写法:dom对象.addEventListener(事件类型,事件功能,是否使用捕获机制),第三个参数为fasle时为事件冒泡、为true时为事件捕获;默认为false

<style>.father{width: 200px;height: 200px;background-color:red;}.son{width: 100px;height: 100px;background-color: green;}
</style>
<body><div class="father"><div class="son"></div></div><script>const father = document.querySelector('.father')const son = document.querySelector('.son')document.addEventListener('click',function(){alert('document');},true)father.addEventListener('click',function(){alert('father');},true)son.addEventListener('click',function(){alert('son');},true)</script>
</body>

当点击son对象时,会依次调用document、father、son鼠标点击事件

事件冒泡

1、事件从目标元素开始,逐层向上传播到其祖先元素,传递路径上的同名事件都会执行

目标dom对象->document,目标元素的事件发生时,其所有父元素的同名事件也会发生

2、将上例的true都改为false后,点击son对象时,会依次调用son、father、document鼠标点击事件

3、事件都会经过冒泡这个阶段

阻止冒泡

<script>const father = document.querySelector('.father')const son = document.querySelector('.son')document.addEventListener('click',function(){alert('document');})father.addEventListener('click',function(){alert('father');})son.addEventListener('click',function(e){alert('son')e.stopPropagation()})</script>

解绑事件

function fn(){
...}
btn.addEventListener('click',fn)
btn.removeEventListener('click',fn)

注意:前面写的事件绑定时用的都是匿名函数,但匿名函数无法解绑

mouseover&&mouseleave、mouseout&&mouseleave

<body><div class="father"><div class="son"></div></div><script>const father = document.querySelector('.father')const son = document.querySelector('.son')father.addEventListener('mouseover',function(){console.log('鼠标经过')})father.addEventListener('mouseout',function(){console.log('鼠标离开')})</script>
</body>

1、mouseover/mouseout属于冒泡事件:当鼠标指针进入/离开目标元素或者目标元素的子元素时触发

      mouseenter/mouseleave不属于冒泡事件:只有当鼠标指针真正进入/离开目标元素时才会触发

2、上例中,当鼠标从father区域进入son区域时,首先会触发father的mouseout(鼠标真正离开),其次还会触发father的mouseover(鼠标进入father的子元素son,也会触发father的mouseover);当鼠标从son区域进入father区域时,首先会触发father的mouseout(鼠标离开father的子元素son,也会触发father的mouseout),其次还会触发father的mouseover(鼠标真正进入)

3、将mouseover改为mouseenter、mouseout改为mouseleave后,从father区域进入son区域时,不会触发father的事件

两种注册事件的区别

事件委托

<ul><li> </li><li> </li><li> </li><li> </li>
</ul>

1、事件冒泡是必然发生的,因此为四个li标签绑定事件时等价于为其父元素ul标签绑定事件,当任何一个li标签触发事件后,该事件都会冒泡到父元素ul标签上;

2、事件委托利用了冒泡性质,可以减少事件绑定的次数、从而提高程序性能

3、某个父元素下可能有许多子元素,因此需要找到冒泡事件来自哪个子元素:

Ⅰ、事件对象.target表示该冒泡事件来自哪个dom对象

Ⅱ、事件对象.target.tagName:得到该dom对象的标签名,结果为大写字符串

注:事件对象.target得到的是一个dom对象,dom对象常用的属性有tagName、innerHTML、className、style...

案例:事件委托版的tab栏切换

  <style>* {margin: 0;padding: 0;}.tab {width: 590px;height: 340px;margin: 20px;border: 1px solid #e4e4e4;}.tab-nav {width: 100%;height: 60px;line-height: 60px;display: flex;justify-content: space-between;}.tab-nav h3 {font-size: 24px;font-weight: normal;margin-left: 20px;}.tab-nav ul {list-style: none;display: flex;justify-content: flex-end;}.tab-nav ul li {margin: 0 20px;font-size: 14px;}.tab-nav ul li a {text-decoration: none;border-bottom: 2px solid transparent;color: #333;}.tab-nav ul li a.active {border-color: #e1251b;color: #e1251b;}.tab-content {padding: 0 16px;}.tab-content .item {display: none;}.tab-content .item.active {display: block;}</style>
</head><body><div class="tab"><div class="tab-nav"><h3>每日特价</h3><ul><li><a class="active" href="javascript:;" data-id="0">精选</a></li><li><a href="javascript:;" data-id="1">美食</a></li><li><a href="javascript:;" data-id="2">百货</a></li><li><a href="javascript:;" data-id="3">个护</a></li><li><a href="javascript:;" data-id="4">预告</a></li></ul></div><div class="tab-content"><div class="item active"><img src="./images/tab00.png" alt="" /></div><div class="item"><img src="./images/tab01.png" alt="" /></div><div class="item"><img src="./images/tab02.png" alt="" /></div><div class="item"><img src="./images/tab03.png" alt="" /></div><div class="item"><img src="./images/tab04.png" alt="" /></div></div></div><script>const ul = document.querySelector('.tab .tab-nav ul')ul.addEventListener('mouseover',function(e){if(e.target.tagName === 'A'){//先移除之前a标签的active类名document.querySelector('a.active').classList.remove('active')//再为现在的a标签添加active类名e.target.classList.add('active')//更换下面的图片const i = +e.target.dataset.id//a标签的索引号document.querySelector('.tab-content .active').classList.remove('active')document.querySelector(`.tab-content div:nth-child(${i+1})`).classList.add('active')}})
</script>
</body>

 注意:Ⅰ、为a标签的父元素ul绑定鼠标经过事件时,使用mouseover而非mouseenter,因为此处要利用冒泡性质,而mouseenter没有冒泡性质,只有真正经过ul标签时才触发事件、而mouseover经过ul标签或ul的子标签时都会触发事件

Ⅱ、a标签有自定义属性,表示该a标签的索引号,该索引号是字符串型,在使用时将其转为数字型,转换方式为在该id前加+即可

阻止元素默认行为

页面加载事件

1、load

①等待页面所有资源(事件类型为load)加载完毕之后执行回调函数;

②给windowdocument绑定事件

  <script>document.addEventListener('load', function () {const btn = document.querySelector('button')btn.addEventListener('click', function () {alert(11)})})</script>
<body><button>点击</button></body>

2、DOMContentLoaded

只等待HTML结构加载完毕(事件类型为DOMContentLoaded)就执行回调函数,而无需等样式表、图片全部资源加载完毕;

②给document绑定事件

页面滚动事件

1、监听整个页面滚动:需要先将整个body标签拉大,这样才能显示出滚动条

  <style>body {padding-top: 100px;height: 3000px;}</style>
</head><body><script>window.addEventListener('scroll',function(){console.log('滚动');})</script>
</body>

2、监听某个元素内部滚动:①overflow: scroll 表示始终显示滚动条不管内容是溢出了标签;overflow: auto 表示只有元素溢出时才显示滚动条

  <style>body {padding-top: 100px;height: 3000px;}div{overflow: scroll;width: 54px;height: 200px;border: 1px solid black;}</style>
</head><body><div>
sasdasdasd 
sasdasdasd 
sasdasdasd 
asdasdasd 
sasdasdasd 
sasdasdasd 
sasdasdasd 
sasdasdasd 
sasdasdasd 
sasdasdasd </div><script>const div = document.querySelector('div')div.addEventListener('scroll',function(){console.log('滚动');})</script>
</body>

3、获取位置

①scrollTop元素被卷去的大小,也即元素往上滚动出去看不到的大小

②scrollLefthtml页面被卷去的大小,也即元素往左滚动出去看不到的大小

③这两个属性可读可写,但这两个属性的值没有单位

④获取页面被卷去的大小:

document.documentElement.scrollTop

注意:Ⅰ、document.documentElement是获取整个HTML对象的方法

Ⅱ、scrollTop是某个html元素被卷去的大小,例如:document.documentElement.scrollTop是整个html页面被卷去的大小

案例:电梯导航栏

需求1:当页面滚动大于300像素时,显示电梯导航栏;需求2:电梯导航栏中有一个“顶部”按钮,点击返回页面顶部

  <div class="xtx-elevator"><ul class="xtx-elevator-list"><li><a href="javascript:;" data-name="new">新鲜好物</a></li><li><a href="javascript:;" data-name="popular">人气推荐</a></li><li><a href="javascript:;" data-name="brand">热门品牌</a></li><li><a href="javascript:;" data-name="topic">最新专题</a></li><li><a href="javascript:;" id="backTop"><i class="sprites"></i>顶部</a></li></ul></div>
<script>const elevator = document.querySelector('.xtx-elevator')const t = document.querySelector('.xtx-elevator-list #backTop')const html = document.documentElement//获取整个html//需求1window.addEventListener('scroll',function(){if(html.scrollTop>=300){elevator.style.opacity = 1}else{elevator.style.opacity = 0}})//需求2t.addEventListener('click',function(){//写法1//html.scrollTop = 0//写法2window.scrollTo(0,0)})
</script>
</body>

注意:Ⅰ、绑定scroll事件时是为window绑定,意为监听整个页面滚动,而非其他dom对象,window在动,其他dom对象不动,故scrollTop才能表示dom元素被卷去的大小;

Ⅱ、scrollTop和scrollLeft是DOM元素的属性,不是window的属性,故不能写window.scrollTop = 0

Ⅲ、页面回滚到顶部有两种写法:

①document.documentElement.scrollTop = 0

②window.scrollTo(0,0)

获取盒子的大小(client家族)

1、clientWidth、clientHeight

获取盒子的大小,不包含border和margin,只包含content和padding

获取盒子的位置(offset家族)

offsetLeft、offsetTop是距离其最近定位父级的左、上距离

案例:电梯导航栏(改进版)

需求:当页面移动到这个位置时,显示导航栏

 <div class="xtx-elevator"><ul class="xtx-elevator-list"><li><a href="javascript:;" data-name="new">新鲜好物</a></li><li><a href="javascript:;" data-name="popular">人气推荐</a></li><li><a href="javascript:;" data-name="brand">热门品牌</a></li><li><a href="javascript:;" data-name="topic">最新专题</a></li><li><a href="javascript:;" id="backTop"><i class="sprites"></i>顶部</a></li></ul></div>
<script>const entry = document.querySelector('.xtx_entry')const html = document.documentElementconst elevator = document.querySelector('.xtx-elevator')//需求1window.addEventListener('scroll',function(){if(html.scrollTop>=entry.offsetTop){elevator.style.opacity = 1}else{elevator.style.opacity = 0}})

注意写法:html.scrollTop>=entry.offsetTop,即html被卷去的大小大于初始offsetTop时,显示导航栏

案例:仿新浪固定头部

需求:如图,当页面滚动到秒杀模块时,顶部自动弹出导航栏

    <style>* {margin: 0;padding: 0;box-sizing: border-box;}.content {overflow: hidden;width: 1000px;height: 3000px;background-color: pink;margin: 0 auto;}.backtop {display: none;width: 50px;left: 50%;margin: 0 0 0 505px;position: fixed;bottom: 60px;z-index: 100;}.backtop a {height: 50px;width: 50px;background: url(./images/bg2.png) 0 -600px no-repeat;opacity: 0.35;overflow: hidden;display: block;text-indent: -999em;cursor: pointer;}.header {position: fixed;top: -80px;left: 0;width: 100%;height: 80px;background-color: purple;text-align: center;color: #fff;line-height: 80px;font-size: 30px;transition: all .3s;}.sk {width: 300px;height: 300px;background-color: skyblue;margin-top: 500px;}</style>
</head><body><div class="header">我是顶部导航栏</div><div class="content"><div class="sk">秒杀模块</div></div><div class="backtop"><img src="./images/close2.png" alt=""><a href="javascript:;"></a></div><script>const html = document.documentElementconst sk = document.querySelector('.sk')const header = document.querySelector('.header')window.addEventListener('scroll',function(){if(html.scrollTop >= sk.offsetTop){header.style.top = '0px'}else{header.style.top = '-80px'}})</script>
</body>

注意:Ⅰ、关注写法html.scrollTop >= sk.offsetTop

Ⅱ、css样式中,top属性值表示元素距离顶部的距离,负值表示元素向上偏移、正值表示元素向下偏移 

Ⅲ、top属性值带单位px, 故header.style.top = '-80px'要带引号

案例:电梯导航(最终版)

需求1:当页面移动到这个位置时,显示导航栏;需求2:右侧导航栏真正发挥导航的作用,点击哪个按钮页面就跳到相应的部分;需求3:点击顶部时页面返回顶部;需求4:页面滑动到哪个模块,导航栏对应的按钮就高亮(顶部按钮除外);需求5:让通过电梯导航栏让页面滑动时效果更平滑

日期对象

1、获取当前时间:参数为空

const date = new Date()//Sat Jan 25 2025 01:19:51

2、获取指定的时间:参数为指定日期

const date = new Date('2025-1-25') //Sat Jan 25 2025 00:00:00

参数为一个日期字符串,date保存的是从该日期开始的0点时间

3、日期对象的方法:需要先通过new获得日期对象,再使用日期对象方法

注意:①以上方法都有括号

②getMonth()和getDay()取值是从0开始,实际的月份从1开始取值、星期取0表示为星期日

③以上方法得到的都是数字都是number型

④注意getDay()和getDate()的区别,前者是获取星期,后者是获取月份中的某一天

案例:页面显示时间

需求:将当前时间以:YYYY-MM-DD HH:mm 形式显示在页面,例如 2025-01-25 01:16
写法1:
<body><div></div><script>function rq(){let div = document.querySelector('div')let date = new Date() let y = date.getFullYear()let month = date.getMonth() + 1let day = date.getDate() + 1 let hour = date.getHours()let min = date.getMinutes()let sec = date.getSeconds()month = month < 10 ? '0' + month : month day = day < 10 ? '0' + day : day hour = hour < 10 ? '0' + hour : hour min = min < 10 ? '0' + min : min sec = sec < 10 ? '0' + sec : sec div.innerHTML = `今天是${y}年${month}月${day}日,${hour}时${min}分${sec}秒`}rq()setInterval(rq,1000)</script>
</body>

注意:①getDay()和getDate()的区别

month = month < 10 ? '0' + month : month   将月份表示为两位数,例如1月为01月

getDate()方法得到的是number型,其与'0'相加会自动转为string型,从而将1变为01

将当前时间以:YYYY-MM-DD HH:mm 形式显示在页面还可以这么写
let date = new Date() 
div.innerHTML = date.toLocaleString() //2025/1/25 01:44:09

务必注意方法后面要加括号

时间戳

1、从1970年01月01日00时00分00秒起,到当前时刻的毫秒数

2、获取时间戳的三种方式

①先实例化日期对象,再调用getTime()方法

const date = new Date()
date.getTime()

②简写+new Date()

new Date()是获取当前的时间,结果为字符串,+的作用是将字符串转为number型,即时间戳

③Date.now()

案例:倒计时


<body><div class="countdown"><p class="next">今天是2025年1月28日</p><p class="title">新年倒计时</p><p class="clock"><span id="hour">00</span><i>:</i><span id="minutes">25</span><i>:</i><span id="scond">20</span></p></div><script>const last = +new Date('2025-1-29')let now = +new Date()let seconds = (last-now)/1000 let hour = parseInt(seconds/60/60%24)let min = parseInt(seconds/60%60)let sec = parseInt(seconds%60)let h = document.querySelector('#hour')let m = document.querySelector('#minutes')let s = document.querySelector('#scond')h.innerHTML = hourm.innerHTML = mins.innerHTML = secsetInterval(function(){now = +new Date()seconds = (last-now)/1000 parseInt(seconds/60/60%24)min = parseInt(seconds/60%60)sec = parseInt(seconds%60)h = document.querySelector('#hour')m = document.querySelector('#minutes')s = document.querySelector('#scond')h.innerHTML = hourm.innerHTML = mins.innerHTML = sec},1000)</script>
</body>

注意:1、JavaScript中/是除法,而不是只取商;

2、parseInt方法是将其他类型的数据(小数或字符串)变为整数

3、需要在定时器外面也写上同样的代码,防止页面启动的前1秒,定时器还没开始执行、页面数据显示不正确

DOM结点

1、DOM结点的类型

①元素结点(标签结点),比如div标签、a标签等等

②属性结点,比如div标签中有id属性、class属性。。。

③文本结点,标签里的文字

2、结点查找

①查找一个父节点parentNode

<body><div class="yeye"><div class="dad"><div class="baby">x</div></div></div><script>const baby = document.querySelector('.baby')console.log(baby)  // 返回dom对象console.log(baby.parentNode)  // 返回dom对象console.log(baby.parentNode.parentNode)  // 返回dom对象</script>
</body>

案例:点击关闭:点击box1按钮时,关闭box盒子

<body><div class="box">我是广告<div class="box1">X</div></div><script>const box1 = document.querySelector('.box1')box1.addEventListener('click',function(){this.parentNode.style.display = 'none'})</script>
</body>

②查找所有子元素结点children:同querySelectorAll一样,得到的是一个伪数组,

<body><ul><p></p><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><script>const ul = document.querySelector('ul')  // ulconsole.log(ul.children)  // 得到伪数组:HTMLCollection(6) [p, li, li, li, li, li]</script>
</body>

③上一个兄弟结点previousElementSibling、下一个兄弟结点nextElementSibling

注意:以上查找结点的操作:parentNode、children、previousElementSiblingnextElementSibling均是属性不是方法,在使用的时不要加括号

2、结点增加

appendChild():在父节点后追加一个结点,写法:父节点.appendChild(要插入的结点)

Ⅰ、先创建元素结点:const li = document.createElement('li'),创建之后的结点是一个dom对象

Ⅱ、再将其追加到某个父节点后面:ul.appendChild(li)

<body><ul><li>我是老大</li></ul><script>const ul = document.querySelector('ul')const li = document.createElement('li')ul.appendChild(li)li.innerHTML = '我是老二'</script>
</body>

②插入到父元素中某个子元素的前面:父元素.insertBefore(插入的元素,放到哪个子元素前面)

<body><ul><li>我是老大</li><li>我是老二</li><li>我是老三</li></ul><script>const ul = document.querySelector('ul')const p = document.createElement('p')ul.insertBefore(p,ul.children[0])p.innerHTML = '11111'</script>
</body>

案例:学成在线

<body><!-- 4. box核心内容区域开始 --><div class="box w"><div class="box-hd"><h3>精品推荐</h3><a href="#">查看全部</a></div><div class="box-bd"><ul class="clearfix"></ul></div></div><script>// 1. 以下为初试数据,将其渲染到网页中  let data = [{src: 'images/course01.png',title: 'Think PHP 5.0 博客系统实战项目演练',num: 1125},{src: 'images/course02.png',title: 'Android 网络动态图片加载实战',num: 357},{src: 'images/course03.png',title: 'Angular2 大前端商城实战项目演练',num: 22250},{src: 'images/course04.png',title: 'Android APP 实战项目演练',num: 389},{src: 'images/course05.png',title: 'UGUI 源码深度分析案例',num: 124},{src: 'images/course06.png',title: 'Kami2首页界面切换效果实战演练',num: 432},{src: 'images/course07.png',title: 'UNITY 从入门到精通实战案例',num: 888},{src: 'images/course08.png',title: 'Cocos 深度学习你不会错过的实战',num: 590},]const ul = document.querySelector('.box-bd .clearfix')for(let i = 0;i<data.length;i++){const li = document.createElement('li')ul.appendChild(li)li.innerHTML = `<a href="#"><img src="${data[i].src}" alt=""><h4>${data[i].title}</h4><div class="info"><span>高级</span> • <span>${data[i].num}</span>人在学习</div></a>`}</script>
</body>

注意:

1、每一个li标签中的标签和文本可以用模板字符串拼接 2、需要先创建li标签,再将其添加到ul标签中 

克隆结点

1、写法:要克隆的元素结点.cloneNode(布尔值),参数为true时为深克隆,表示既克隆标签又克隆标签中的文本;参数为false时为浅克隆,只克隆标签

2、

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/9782.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go的内存逃逸

Go的内存逃逸 内存逃逸是 Go 语言中一个重要的概念&#xff0c;指的是本应分配在栈上的变量被分配到了堆上。栈上的变量在函数结束后会自动回收&#xff0c;而堆上的变量需要通过垃圾回收&#xff08;GC&#xff09;来管理&#xff0c;因此内存逃逸会增加 GC 的压力&#xff0…

python学opencv|读取图像(四十九)原理探究:使用cv2.bitwise()系列函数实现图像按位运算

【0】基础定义 按位与运算&#xff1a;两个等长度二进制数上下对齐&#xff0c;全1取1&#xff0c;其余取0。 按位或运算&#xff1a;两个等长度二进制数上下对齐&#xff0c;有1取1&#xff0c;其余取0。 按位异或运算&#xff1a; 两个等长度二进制数上下对齐&#xff0c;相…

图论——最小生成树的扩展应用

最小生成树相关原理 acwing1146.新的开始 假设存在一个“超级发电站” 在每一个矿井修发电站相当于从这个“超级发电站”到各个矿井连一条长度为 v [ i ] v[i] v[i]的边。 这样一来这就是一个最短路的模板题。 #include <iostream> #include <cstring> using na…

供应链系统设计-供应链中台系统设计(十)- 清结算中心概念片篇

综述 我们之前在供应链系统设计-中台系统设计系列&#xff08;五&#xff09;- 供应链中台实践概述文章中针对中台到底是什么进行了描述&#xff0c;对于中台的范围也进行划分&#xff0c;如下图所示&#xff1a; 关于商品中心&#xff0c;我们之前用4篇文章介绍了什么是商品中…

Git图形化工具【lazygit】

简要介绍一下偶然发现的Git图形化工具——「lazygit」 概述 Lazygit 是一个用 Go 语言编写的 Git 命令行界面&#xff08;TUI&#xff09;工具&#xff0c;它让 Git 操作变得更加直观和高效。 Github地址&#xff1a;https://github.com/jesseduffield/lazygit 主要特点 主要…

为大模型提供webui界面的利器:Open WebUI 完全本地离线部署deepseek r1

为大模型提供webui界面的利器&#xff1a;Open WebUI Open WebUI的官网&#xff1a;&#x1f3e1; Home | Open WebUI 开源代码&#xff1a;WeTab 新标签页 Open WebUI是一个可扩展、功能丰富、用户友好的自托管AI平台&#xff0c;旨在完全离线运行。它支持各种LLM运行程序&am…

全程Kali linux---CTFshow misc入门(14-24)

第十四题&#xff1a; dd命令&#xff1a;dd是一个用于复制和转换数据的命令&#xff0c;它可以对文件、设备等进行操作&#xff0c;在数据备份、转换格式等场景经常使用。 ifmisc14.jpg&#xff1a;if表示 “input file”&#xff08;输入文件&#xff09;&#xff0c;这里指…

网络爬虫学习:应用selenium获取Edge浏览器版本号,自动下载对应版本msedgedriver,确保Edge浏览器顺利打开。

一、前言 我从24年11月份开始学习网络爬虫应用开发&#xff0c;经过2个来月的努力&#xff0c;于1月下旬完成了开发一款网络爬虫软件的学习目标。这里对本次学习及应用开发进行一下回顾总结。 前几天我已经发了一篇日志&#xff08;网络爬虫学习&#xff1a;应用selenium从搜…

C语言连接Mysql

目录 C语言连接Mysql下载 mysql 开发库 方法介绍mysql_init()mysql_real_connect()mysql_query()mysql_store_result()mysql_num_fields()mysql_fetch_fields()mysql_fetch_row()mysql_free_result()mysql_close() 完整代码 C语言连接Mysql 下载 mysql 开发库 方法一&#xf…

前端-Rollup

Rollup 是一个用于 JavaScript 的模块打包工具&#xff0c;它将小的代码片段编译成更大、更复杂的代码&#xff0c;例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式&#xff0c;而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由…

Ubuntu20.04 磁盘空间扩展教程

Ubuntu20.04 磁盘空间扩展教程_ubuntu20 gpart扩容-CSDN博客文章浏览阅读2w次&#xff0c;点赞38次&#xff0c;收藏119次。执行命令查看系统容量相关的数据&#xff1a;df -h当前容量为20G&#xff0c;已用18G&#xff08;96%&#xff09;&#xff0c;可用844M&#xff0c;可用…

使用Ollama本地部署DeepSeek R1

前言 DeepSeek是一款开源的智能搜索引擎&#xff0c;能够通过深度学习技术提高搜索的智能化水平。如果你正在寻找一种方式来将DeepSeek部署在本地环境中&#xff0c;Ollama是一个非常方便的工具&#xff0c;它允许你在本地快速部署并管理各种基于AI的模型。 在本篇博客中&…

数据结构选讲 (更新中)

参考 smWCDay7 数据结构选讲2 by yyc 。 可能会补充的&#xff1a; AT_cf17_final_j TreeMST 的 F2 Boruvka算法 目录 AT_cf17_final_j Tree MSTP5280 [ZJOI2019] 线段树 AT_cf17_final_j Tree MST link 题意 给定一棵 n n n 个点的树&#xff0c;点有点权 w i w_i wi​&am…

Redis学习之哨兵二

一、API 1.sentinel masters:展示被监控的主节点状态及相关的统计信息 2.sentinel master <master name>:展示指定的主节点的状态以及相关的统计信息 3.sentinel slaves <master name>:展示指定主节点的从节点状态以及相关的统计信息 4.sentinel sentinels <mas…

iperf 测 TCP 和 UDP 网络吞吐量

注&#xff1a;本文为 “iperf 测网络吞吐量” 相关文章合辑。 未整理去重。 使用 iperf3 监测网络吞吐量 Tom 王 2019-12-21 22:23:52 一 iperf3 介绍 (1.1) iperf3 是一个网络带宽测试工具&#xff0c;iperf3 可以擦拭 TCP 和 UDP 带宽质量。iperf3 可以测量最大 TCP 带宽…

Kafka 副本机制(包含AR、ISR、OSR、HW 和 LEO 介绍)

文章目录 Kafka 副本机制&#xff08;包含AR、ISR、OSR、HW 和 LEO 介绍&#xff09;1. 副本的基本概念2. 副本同步和一致性2.1 AR&#xff08;Assigned Replicas&#xff09;2.2 ISR&#xff08;In-Sync Replicas&#xff09;2.3 OSR&#xff08;Out-of-Sync Replicas&#xf…

java求职学习day18

常用的设计原则和设计模式 1 常用的设计原则&#xff08;记住&#xff09; 1.1 软件开发的流程 需求分析文档、概要设计文档、详细设计文档、编码和测试、安装和调试、维护和升级 1.2 常用的设计原则 &#xff08;1&#xff09;开闭原则&#xff08;Open Close Principle…

github制作静态网页

打开gihub并新建仓库 命名仓库&#xff1a;xxx.github.io 点击create repository进行创建 点击蓝色字体“creating a new file”创建文件 文件命名为index.html, 并编写html 右上角提交 找到setttings/pages&#xff0c;修改路径&#xff0c;点击保存&#xff0c;等…

shell脚本

Shell内容讲解 一、Shell 脚本基础概念 什么是 Shell 脚本&#xff1f; Shell 脚本是一个包含一系列 Shell 命令的文本文件&#xff0c;用于自动化执行任务&#xff08;如文件操作、程序调用、系统管理等&#xff09;。 Shell 类型 bash&#xff08;Bourne-Again Shell&#…

python:斐索实验(Fizeau experiment)

斐索实验&#xff08;Fizeau experiment&#xff09;是在1851年由法国物理学家阿曼德斐索&#xff08;Armand Fizeau&#xff09;进行的一项重要实验&#xff0c;旨在测量光在移动介质中的传播速度。这项实验的结果对当时的物理理论产生了深远的影响&#xff0c;并且在后来的相…