其他事件
页面加载事件
外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
原因:有些时候需要等页面资源全部处理完了做一些事情,老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到。
事件名: load
监听页面所有资源加载完毕:给 window 添加 load 事件
不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件
当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载
事件名: DOMContentLoaded
监听页面DOM加载完毕:给 document 添加 DOMContentLoaded 事件
页面滚动事件
滚动条在滚动的时候持续触发的事件。很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部。
事件名:scroll
监听整个页面滚动:window.addEventListenter.('scroll',function(){console.log('man!')})
scroll不会冒泡,要想给单独标签加上滚动条可以直接写在这个标签上
scrollLeft 和 scrollTop (属性):
获取被卷去的大小,获取元素内容往左、往上滚出去看不到的距离,这两个值是可读写的,
<script>
const div = document.querySelector('div')
// 页面滚动事件
window.addEventListener('scroll', function () {
// 获取html元素写法
// document.documentElement
const n = document.documentElement.scrollTop
if (n >= 100) {
div.style.display = 'block'
} else {
div.style.display = 'none'
}
})
</script>
返回顶部
<script>
// 点击返回页面顶部
const backTop = document.querySelector('#backTop')
backTop.addEventListener('click', function () {
// 可读写
// document.documentElement.scrollTop = 0
window.scrollTo(0, 0)
})
</script>
小兔鲜显示导航和返回顶部案例
将融合在综合案例中来写
页面尺寸事件
window.addEventListener('resize',function(){console.log(manbaout)})
检测屏幕宽度
这里其实有一个源码
元素尺寸与位置
就是通过js的方式,得到 元素在页面中的位置
● 获取宽高: offsetWidth和offsetHeight (内容 + padding + border)
获取元素的自身宽高、包含元素自身设置的宽高、padding、border。 获取的是数值,方便计算。
注意: 获取的是可视宽高, 如果盒子是隐藏的,获取的结果是0
● 获取位置:
1.offsetLeft和offsetTop
获取元素距离自己 定位父级元素 的左、上距离, 如果都没有则以 文档左上角 为准。
注意:offsetLeft和offsetTop 是只读属性
仿京东效果导航栏案例
<!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>
* {
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: 600px;
}
</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>
// 获取 header
let header = document.querySelector('.header');
// 获取sk
let sk = document.querySelector('.sk');
// 当窗口滚动距离 大于或者等于 sk距离父亲的距离 的时候 让header显示
window.addEventListener('scroll', function () {
// 网页距离 : document.documentElement
// scrollTop : 是元素内容滚动的距离
// offsetTop : 是距离自己定位离父元素的距离
if (document.documentElement.scrollTop >= sk.offsetTop) {
//让顶部元素显示
header.style.top = 0;
} else {
// 让顶部元素隐藏
header.style.top = '-80px';
}
});
</script>
</body>
</html>
哔哩哔哩小红色滑块
缺少代码,但是有核心思想
通过视口来获得元素位置
<style>
body{
height: 2000px;
}
div {
width:200px; height: 200px; background-color:
pink; margin: 100px;
}
</style>
</head>
<body>
<div></div>
<script>
const div = document.querySelector('div')
console.log(div.getBoundingClientRect())
</script>
</body>
不用锚点链接做小兔鲜电梯导航
<script>
// 第一大模块,页面滑动可以显示和隐藏
(function () {
// 获取元素
const entry = document.querySelector('.xtx_entry')
const elevator = document.querySelector('.xtx-elevator')
// 1. 当页面滚动大于 300像素,就显示 电梯导航
// 2. 给页面添加滚动事件
window.addEventListener('scroll', function () {
// 被卷去的头部大于 300
const n = document.documentElement.scrollTop
elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
})
// 点击返回页面顶部
const backTop = document.querySelector('#backTop')
backTop.addEventListener('click', function () {
// 可读写
// document.documentElement.scrollTop = 0
window.scrollTo(0, 0)
})
})();
// 第二第三都放到另外一个执行函数里面
(function () {
// 2. 点击页面可以滑动
const list = document.querySelector('.xtx-elevator-list')
list.addEventListener('click', function (e) {
// console.log(11)
if (e.target.tagName === 'A' && e.target.dataset.name) {
// 排他思想
// 先移除原来的类active
// 先获取这个active的对象
const old = document.querySelector('.xtx-elevator-list .active')
// console.log(old)
// 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
if (old) old.classList.remove('active')
// 当前元素添加 active
e.target.classList.add('active')
// 获得自定义属性 new topic
// console.log(e.target.dataset.name)
// 根据小盒子的自定义属性值 去选择 对应的大盒子
// console.log(document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop)
// 获得对应大盒子的 offsetTop
const top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
// 让页面滚动到对应的位置
document.documentElement.scrollTop = top
}
})
// 3. 页面滚动,可以根据大盒子选 小盒子 添加 active 类
window.addEventListener('scroll', function () {
// 3.1 先移除类
// 先获取这个active的对象
const old = document.querySelector('.xtx-elevator-list .active')
// console.log(old)
// 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
if (old) old.classList.remove('active')
// 3.2 判断页面当前滑动的位置,选择小盒子
// 获取4个大盒子
const news = document.querySelector('.xtx_goods_new')
const popular = document.querySelector('.xtx_goods_popular')
const brand = document.querySelector('.xtx_goods_brand')
const topic = document.querySelector('.xtx_goods_topic')
const n = document.documentElement.scrollTop
if (n >= news.offsetTop && n < popular.offsetTop) {
// 选择第一个小盒子
document.querySelector('[data-name=new]').classList.add('active')
} else if (n >= popular.offsetTop && n < brand.offsetTop) {
document.querySelector('[data-name=popular]').classList.add('active')
} else if (n >= brand.offsetTop && n < topic.offsetTop) {
document.querySelector('[data-name=brand]').classList.add('active')
} else if (n >= topic.offsetTop) {
document.querySelector('[data-name=topic]').classList.add('active')
}
})
})();
</script>
日期对象
实例化
const date=new Date()//得到当前时间
const date1=new Date('2022-5-1 08:30:00')//指定时间
目标:能够使用日期对象中的方法写出常见日期
使用场景:因为日期对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
getFullYear()获得年份获取四位年份
getMonth()获得月份取值为0~11
getDate()获取月份中的每一天,不同月份取值也不相同
getDay()获取星期,取值为0~6
getHours()获取小时,取值为0~23
getMinutes()获取分钟,取值为0~59
getSeconds()获取秒,取值为0~59
页面显示日期
<style>
div{width:300px;
height:40px;
border:1px solid pink;
text-align:center;
line-height:50px;
}
</style>
</head>
<body>
<div></div>
<script>
const div = document.querySelector('div')
function getMyDate() {
const date = new Date()
let h = date.getHours()
let m = date.getMinutes()
let s = date.getSeconds()
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
return `今天是: ${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}号 ${h}:${m}:${s}`
}
div.innerHTML = getMyDate()
setInterval(function () {
div.innerHTML = getMyDate()
}, 1000)
</script>
</body>
这是自定义格式,不想写可以用系统的。
<body>
<div></div>
<script>
const div = document.querySelector('div')
//得到日期对象
const date = new Date()
div.innerHTML = date.toLocaleString() // 2022/4/1 09:41:21
setInterval(function () {
const date = new Date()
div.innerHTML = date.toLocaleString() // 2022/4/1 09:41:21
},1000)
div.innerHTML = date.toLocaLeDateString() // 2022/4/1
div.innerHTML = date.toLocaleTimeString() // 09:41:21
</script>
</body>
时间戳
实际开发中,经常和后端对接口的时候就经常用到这个时间戳
使用场景: 如果计算倒计时效果,前面方法无法直接计算,需要借助于时间戳完成
时间戳:是指1970年01月01日00时00分00秒起至现在的 毫秒数 ,是一种特殊的计量时间的方式
算法:
将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数
剩余时间毫秒数 转换为 剩余时间的 年月日时分秒 就是 倒计时时间
比如:将来时间戳 2000ms - 现在时间戳 1000ms = 1000ms,1000ms 转换为就是 0小时0分1秒
1. 使用 getTime() 方法
const date = new Date()
console.log(date.getTime())
2.简写 +new Date()
重点记住 +new Date() 因为可以返回当前时间戳或者指定的时间戳
console.log(+new Date())
3. 使用 Date.now()
console.log(Date.now()) 但是只能得到当前的时间戳, 而前面两种可以返回指定时间的时间戳
毕业倒计时效果
<!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" <!DOCTYPE html>
<style>
.countdown {
width: 240px;
height: 305px;
text-align: center;
line-height: 1;
color:
#fff;
background-color:
brown;
/* background-size: 240px; */
/* float: Left;*/
overflow: hidden;
}
.countdown .next {
font-size: 16px;
margin: 25px 0 14px;
}
.countdown .title {
font-size: 33px;
}
.countdown .tips {
margin-top: 80px;
font-size: 23px;
}
.countdown small {
font-size: 17px;
}
.countdown .clock {
width: 142px;
margin: 18px auto 0;
overflow: hidden;
}
.countdown .clock span,
.countdown .clock i {
display: block;
text-align: center;
line-height: 34px;
font-size: 23px;
float: left;
}
.countdown.clock span {
width: 34px;
height: 34px;
border-radius: 2px;
background-color: □#303430;
}
.countdown .clock i {
width: 20px;
font-style: normal;
}
</style>
<body>
<div class="countdown">
<p class="next">今天是2222年2月22日</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>
<p class="tips">18: 30: 00下课</p>
</div>
<script>
// 函数封装 getCountTime
function getCountTime() {
// 1. 得到当前的时间戳
const now = +new Date()
// 2. 得到将来的时间戳
const last = +new Date('2022-4-1 18:30:00')
// console.log(now, last)
// 3. 得到剩余的时间戳 count 记得转换为 秒数
const count = (last - now) / 1000
// console.log(count)
// 4. 转换为时分秒
// h = parseInt(总秒数 / 60 / 60 % 24) // 计算小时
// m = parseInt(总秒数 / 60 % 60) // 计算分数
// s = parseInt(总秒数 % 60) // 计算当前秒数
// let d = parseInt(count / 60 / 60 / 24) // 计算当前天数
let h = parseInt(count / 60 / 60 % 24)
h = h < 10 ? '0' + h : h
let m = parseInt(count / 60 % 60)
m = m < 10 ? '0' + m : m
let s = parseInt(count % 60)
s = s < 10 ? '0' + s : s
console.log(h, m, s)
// 把时分秒写到对应的盒子里面
document.querySelector('#hour').innerHTML = h
document.querySelector('#minutes').innerHTML = m
document.querySelector('#scond').innerHTML = s
}
// 先调用一次
getCountTime()
// 开启定时器
setInterval(getCountTime, 1000)
</script>
</body>
</html>
添加随机颜色
DOM节点操作
DOM节点:DOM树里每一个内容都称之为节点
元素节点: 所有的标签 比如 body、 div,html 是根节点
属性节点:所有的属性 比如 href
文本节点:所有的文本
查找父结点
这是举了例子,XX.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>
<body>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<script>
const closeBtn = document.querySelectorAll('.box1')
for (let i = 0; i < closeBtn.length; i+) {
closeBtn[i].addEventlistener('click', function(){
this. parentNode. style.display = 'none'
})
</script>
</body>
子节点
childNodes 属性,获得所有子节点、包括文本节点(空格、换行)、注释节点等 children 属性(重点) 仅获得所有元素节点,返回的还是一个 伪数组, 例如:父元素.children
兄弟节点
1. 下一个兄弟节点: nextElementSibling 属性
2. 上一个兄弟节点: previousElementSibling 属性
增加节点
document.createElement('标签名')
追加节点
要想在界面看到,还得插入到某个父元素中
(1) 插入到父元素的最后一个子元素: 父元素.appendChild(要插入的元素)
(2)插入到父元素中某个子元素的前面:父元素.insertBefore(要插入的元素,在哪个元素前面)
你们错了,其实这种方式开发中很少用,都是用框架
最开始没有元素会得到一个空数组,空数组[0]返回undefined 然后你继续用insertBefore 也不会报错的,刚刚试过了,最开始没有也不会报错
学成在线案例渲染
缺少源码...?
克隆节点和删除节点
元素.cloneNode(布尔值)
特殊情况下我们新增节点按如下操作: 1.复制一个原有的节点 2.把复制的节点放到指定的元素内部
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值。
若为true,则克隆时会包含后代节点一起克隆。 若为false(默认),则克隆时不包含后代节点。
深拷贝与浅拷贝
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
const ul = document.querySelector('ul')
//1克隆节点元素.cloneNode(true)
// const li1 = ul.children[0].cloneNode(true)
// console.log(li1)
//2,追加
ul.appendChild(ul.children[0].cloneNode(true))
</script>
</body>
在 JavaScript 原生 DOM 操作中,要删除元素必须通过 父元素删除。
语法: 父元素.removeChlid(子元素), 如不存在父子关系则删除不成功删除节点和隐藏节点(display:none) 是有区别的:显然的
隐藏节点还是存在的,但是删除,则从html中删除节点
Mobile端事件
目标:了解M端常见的事件
移动端也有自己独特的地方。比如触屏事件touch (也称触摸事件),Android和IOS都有。
• 触屏事件touch (也称触摸事件),Android和IOS都有。
• touch对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)
对屏幕或者触控板操作。
•常见的触屏事件如下:
触屏touch事件 说明
touchstart " 手指到一个DOM元素时触发
touchmove 手指在一个DOM元素上滑动时触发
touchend 手指从一个DOM元素上移开时触发
学习轮播 插件的基本过程
1. 熟悉官网,了解这个插件可以完成什么需求 https://www.swiper.com.cn/
2. 看在线演示,找到符合自己需求的demo https://www.swiper.com.cn/demo/index.html
3. 查看基本使用流程 https://www.swiper.com.cn/usage/index.html
4. 查看APi文档,去配置自己的插件 https://www.swiper.com.cn/api/index.html
注意:多个swiper同时使用的时候, 类名需要注意区分
下载好后,打开package..............
P123