- //等待页面所有资源加载完毕,就去执行回调函数
- window.addEventListener('load',function(){
- const btn=document.querySelector('button')
- btn.addEventListener('click',function(){
- alert(11)
- })
- })
- img.addEventListener('load',function(){
- //等待图片加载完毕 再去执行里面的代码
- })
注意:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件
- document.addEventListener('DOMContentLoaded',function(){
-
- })
- window.addEventListener('scroll',function(){
-
- console.log('滚了')
- })
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Documenttitle>
- <style>
- body {
- padding: 100px;
- height: 3000px;
- }
- div {
- display: none;
- overflow: scroll;
- margin: 100px;
- width: 200px;
- height: 200px;
- border: 1px solid #000;
- }
- style>
-
- head>
- <body>
-
- <div>
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- 我里面有很多文字
- <script>
- document.documentElement.scrollTop=800//可改写
- const div=document.querySelector('div')
- window.addEventListener('scroll',function(){
- const n=document.documentElement.scrollTop//返回数字型 不带单位
- if(n>=100){
- div.style.display='block'
- }
- else {
- div.style.display='none'
- }
- })
- // const div=document.querySelector('div')
- // div.addEventListener('scroll',function(){
- // console.log(111)
- // console.log(div.scrollTop)
- // })
- // script>
- body>
- html>
小tip:
- document.body可获得body标签
- document.documentElement可获得html标签
- //获取元素
- const elevator=document.querySelector('.xtx-elevator')
- //1.当页面滚动大于300px,就显示电梯导航
- //2.给页面添加滚动事件
- window.addEventListener('scroll',function(){
- //被卷去的头部大于300
- const n=document.documentElement.scrollTop
- // if(n>=300){
- // elevator.style.opacity=1
- // }
- // else {
- // elevator.style.opacity=0
- // }
- elevator.style.opacity=n>300?1:0
- })
- //点击返回页面顶部
- const backTop=document.querySelector('#backTop')
- backTop.addEventListener('click',function(){
- //可读写
- // document.documentElement.scrollTop=0
- window.scrollTo(0,0)
- })
tip:
页面滚动事件-滚动到指定的坐标
- scrollTo()方法可把内容滚动到指定的坐标
- 语法:元素.scrollTo(x,y)
//让页面滚动到y轴1000px的位置 window.scrollTo(0,1000)
会在窗口尺寸改变的时候触发事件:
resize
- //resize浏览器窗口大小发生变化的时候触发的事件
- window.addEventListener('resize',function(){
- console.log(1)
- })
获取宽高:
- const div=document.querySelector('div')
- console.log(div.clientWidth)
- //resize浏览器窗口大小发生变化的时候触发的事件
- window.addEventListener('resize',function(){
- console.log(1)
- })
使用场景:
- const div=document.querySelector('div')
- console.log(div.offsetLeft)
需求:当页面滚动到秒杀模块,导航栏自动滑入,否则滑出
分析:
- const sk=document.querySelector('.sk')
- const header=document.querySelector('.header')
- // 1.页面滚动事件
- window.addEventListener('scroll',function(){
- //当页面滚动到秒杀模块时,就改变头部的top值
- //页面被卷去的头部>=秒杀模块的位置offsetTop
- const n=document.documentElement.scrollTop
- if(n>=sk.offsetTop){
- header.style.top=0
- }
- else {
- header.style.top='-80px'
- }
- })
需求:当点击链接,下面红色滑块跟着移动
分析:
- // 1. 事件委托的方法 获取父元素 tabs-list
- const list = document.querySelector('.tabs-list')
- const line = document.querySelector('.line')
- // 2. 注册点击事件
- list.addEventListener('click', function (e) {
- // 只有点击了A 才有触发效果
- if (e.target.tagName === 'A') {
- // console.log(11)
- // 当前元素是谁 ? e.target
- // 得到当前点击元素的位置
- // console.log(e.target.offsetLeft)
- // line.style.transform = 'translateX(100px)'
- // 把我们点击的a链接盒子的位置 然后移动
- line.style.transform = `translateX(${e.target.offsetLeft}px)`
- }
- })
element.getBoundingClientRect()
方法返回元素的大小及其相对于视口的位置
区别于offsetTop:offsetTop是相对于整个页面来说的,而getVBoundingClientRect()是相对于视口来说,如果滚动整个界面,则位置坐标就会改变
属性 | 作用 | 说明 |
---|---|---|
scrollLeft和scrollTop | 被卷去的头部和左侧 | 配合页面滚动来写,可读写 |
clientWidth和clientHeight | 获得元素宽高 | 不包含border,margin,滚动条用于js获取元素的大小,只读属性 |
offsetWidth和offsetHeight | 获取元素宽度和高度 | 包含border,padding,滚动条等,只读 |
offsetLeft和offsetTop | 获取元素距离自己定位父级元素的左,上距离 | 获取元素位置的时候使用,只读属性 |
需求:点击不同的模块,页面可以自动跳转不同的位置
模块分析:
- 显示隐藏电梯盒子和返回顶部已经完成,可以放到自执行函数里面,防止变量污染
- 电梯模块单独放到自执行函数里面
模块分析2:点击每个模块,页面自动滚动到对应模块,使用事件委托方法更加简单
解决方案:
- 不能直接获取这个类,然后移除,这样会报错
- 先获取这个类,然后加个判断:如果有这个类,就移除,如果没有,返回null,就不执行移除,就不报错了
点击每个模块,页面跳转至对应大盒子位置
核心思想:
模块分析3:页面滚动到大盒子位置,电梯导航小盒子对应模块自动处于选中状态
- // 第一模块 页面滑动可以显示和隐藏
- (function(){
- //获取元素
- const entry=document.querySelector('.xtx_entry')
- const elevator=document.querySelector('.xtx-elevator')
- //1.当页面滚动大于300px,就显示电梯导航
- //2.给页面添加滚动事件
- window.addEventListener('scroll',function(){
- //被卷去的头部大于300
- const n=document.documentElement.scrollTop
- // if(n>=300){
- // elevator.style.opacity=1
- // }
- // else {
- // elevator.style.opacity=0
- // }
- 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(){
- 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
- //先获取这个类名
- //若找不到该类名,就返回空null
- const old=document.querySelector('.xtx-elevator-list .active')
- //判断
- if(old){
- old.classList.remove('active')
- }
- //当前元素添加active
- e.target.classList.add('active')
- // 获得自定义属性
- // console.log(e.target.dataset.name)
- // 根据小盒子的自定义属性值去选择 对应的大盒子
- // console.log(document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop)
- const top=document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
- // 让页面滚动到对应的位置
- document.documentElement.scrollTop=top
- }
- })
- // 3.页面滚动事件 可以根据大盒子选 添加active类
-
- window.addEventListener('scroll',function(){
- //先获取这个类名
- //若找不到该类名,就返回空null
- const old=document.querySelector('.xtx-elevator-list .active')
- //判断
- if(old){
- old.classList.remove('active')
- }
- // 判断当前页面滑动的位置 选择小盒子
- //获取四个大盒子
- 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
offsetTop){ - //选择第一个小盒子
- document.querySelector('[data-name=new]').classList.add('active')
- }else if(n>=popular.offsetTop&&n
offsetTop){ - document.querySelector('[data-name=popular]').classList.add('active')
-
- }else if(n>=brand.offsetTop&&n
offsetTop){ - document.querySelector('[data-name=brand]').classList.add('active')
-
- }else if(n>=topic.offsetTop){
- document.querySelector('[data-name=topic]').classList.add('active')
-
- }
- })
-
- })();
tip:
html {
scroll-behavior: smooth;//让滚动条添加滑动效果
}
- //实例化 new
- // const date=new Date()
- // console.log(date)
- // 获得指定时间
- const date=new Date('2008-8-8 08:30:00')
- console.log(date)
使用场景:因为日期对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用格式
方法 | 作用 | 说明 |
---|---|---|
getFullYear() | 获得年份 | 获取四位年份 |
getMonth() | 获得月份 | 取值为0~11 |
getDate() | 获取月份中的每一天 | 不同月份取值也不相同 |
getDay() | 获取星期 | 取值为0~6 |
getHours() | 获取小时 | 取值为0~23 |
getMinutes() | 获取分钟 | 取值为0~59 |
getSeconds() | 获取秒 | 取值为0~59 |
需求:将当前时间以:YYYY-MM-DD HH:mm形式显示在页面 2008-08-08 08:08
分析:
- 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)
- //得到日期对象
- const date=new Date()
- div.innerHTML=date.toLocaleDateString()// 2024/4/1
- div.innerHTML=date.toLocaleString()//2024/4/1 21:00:15
- div.innerHTML=date.toLocaleTimeString()//21:01:16
三种方式获取时间戳:
1、使用getTime()方法
2、简写 +new Date() (无需实例化)
3、使用Date.now() (无需实例化)
但是只能得到当前的时间戳,而前面两种可以返回指定时间的时间戳
- // 1.getTime()
- const date=new Date()
- console.log(date.getTime())
- // 2.+new Date()
- console.log(+new Date())
- // 3.Date.now()
- console.log(Date.now())
- console.log(+new Date())
- console.log('---------------')
- //返回指定时间
- console.log(+new Date('2022-4-1 18:30:00'))
- const arr=['星期天','星期一','星期二','星期三','星期四','星期五','星期六']
- console.log(arr[new Date().getDay()])
需求:计算到下课还有多少时间
分析:
注意:
1.通过时间戳得到的时毫秒,需要转换为秒再计算
2.转换公式:
- d=parseInt(总秒数/60/60/24);//计算天数
- h=parseInt(总秒数/60/60%24);//计算小时
- m=parseInt(总秒数/60%60);//计算分数
- s=parseInt(总秒数%60);//计算秒数
- // 1.自定义一个随机颜色函数
- function getRandomcolor(flag=true){
- if(flag){
- let str='#'
- let arr=['0','1' ,'2','3','4','5','6','7','8','9','a','b','c','d','e','f']
- //利用for循环循环六次,累加到str里面
- for(let i=1;i<=6;i++){
- let Random=Math.floor(Math.random()*arr.length)
- str+=arr[Random]
- }
- return str
- }
- else{
- let r=Math.floor(Math.random()*256)
- let g=Math.floor(Math.random()*256)
- let b=Math.floor(Math.random()*256)
- return `rgb(${r},${g},${b})`
- }
- }
- const countdown=document.querySelector('.countdown')
- countdown.style.backgroundColor=getRandomcolor(true)
-
- //函数封装 getCountTime
- function getCountTime(){
- const next=document.querySelector('.next')
- function gettime(){
- let date=new Date()
- return `今天是${date.getFullYear()}年${date.getMonth()+1}月${date.getDate()}日`
- }
- next.innerHTML=gettime()
- // 1.得到当前的时间戳
- const now=+new Date()
- // 2.得到将来的时间戳
- const last=+new Date('2024-4-1 23:00:00')
- // 3.得到剩余的时间戳 count 记得转化为秒数
- const count=(last-now)/1000
- // 转换为时分秒
- let d=parseInt(count/60/60/24)
- let h=parseInt(count/60/60%24)//计算小时
- let m=parseInt(count/60%60)//计算分数
- let s=parseInt(count%60)//计算秒数
- h=h<10?'0'+h:h
- m=m<10?'0'+m:m
- s=s<10?'0'+s:s
- // console.log(d,h,m,s)
- // 5.把时分秒写到对应的盒子里面
- const hour=document.querySelector('#hour')
- const minutes=document.querySelector('#minutes')
- const second=document.querySelector('#second')
- hour.innerHTML=h
- minutes.innerHTML=m
- second.innerHTML=s
- }
- getCountTime()
- // 开启定时器
- setInterval(getCountTime,1000)
DOM树里的每一个内容都称之为节点
关闭二维码案例:
parentNode属性
返回最近一级的父节点 找不到返回null
子元素.parentNode
- const close=document.querySelectorAll('.close')
- for(let i=0;i
length;i++){ - close[i].addEventListener('click',function(){
- this.parentNode.style.display='none'//按钮的父元素即为盒子,其父元素不再显示
- })
- }
获得所有的子节点,包括文本节点(空格,换行)、注释节点等
父元素.children
- const ul=document.querySelector('ul')
- console.log(ul.children)//得到伪数组 选择的是亲儿子
1.下一个兄弟节点
nextElementSibling属性
2.上一个兄弟节点
previousElementSibling属性
- console.log(li2.previousElementSibling)//上一个兄弟
- console.log(li2.nextElementSibling)//下一个兄弟
很多情况下,我们需要在页面中增加元素
比如:点击发布按钮,可以新增一条信息
一般情况下,我们新增节点,按照如下操作:
追加节点
- 父元素.appendChild(插入的元素)
- document.body.appendChild(div)
在ul里末尾添加li元素
- <ul>ul>
- <script>
- const ul=document.querySelector('ul')
- const li=document.createElement('li')
- li.innerHTML='我是li'
- ul.appendChild(li)
- script>
- //插入到某个子元素的前面
- 父元素.insertBefore(要插入的元素,在哪个元素前面)
- ul.insertBefore(li,ul.children[0])//放在数组第一个元素前面
即创建出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点
创建元素节点方法:
const div =document.createElement('div')
需求:按照数据渲染界面
分析:
- // 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 ul')
- // 1. 根据数据的个数,创建 对应的小li
- for (let i = 0; i < data.length; i++) {
- // 2. 创建新的小li
- const li = document.createElement('li')
- // 把内容给li 属性之间记得保留空格
- li.innerHTML = `
- ${data[i].src} alt="">
-
- ${data[i].title}
-
-
- 高级 • ${data[i].num}人在学习
-
-
- `
- // 3. ul追加小li
- ul.appendChild(li)
- }
特殊情况下,我们新增节点,按照如下操作:
- //克隆一个已有的元素节点
- 元素.cloneNode(布尔值)
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值
- //克隆一个节点并追加到ul元素的最后面
- const ul=document.querySelector('ul')
- //1.克隆节点 元素.cLoneNode(true)
- const li1=ul.children[0].cloneNode(true)
- ul.appendChild(li1)
语法:父元素.removeChild(要删除的元素)
- const ul=document.querySelector('ul')
- ul.removeChild(ul.children[0])
注:
移动端也有自己独特的地方,比如触屏事件touch(也称触摸事件),Android和IOS都有
触屏touch事件 | 说明 |
---|---|
touchstart | 手指触摸到一个DOM元素时触发 |
touchmove | 手指在一个DOM元素上滑动时触发 |
touchend | 手指从一个DOM元素上移开时触发 |
插件:就是别人写好的一些代码,我们只需要复制对应的代码,就可以直接实现对应的效果
学习插件的基本过程
插件的具体使用参见pink老师124-swiper的使用
核心思路:
1.首先取消表单默认提交事件
2.创建新的对象,里面存储表单获取过来的数据
3.追加给数组
4.渲染数据,遍历数组,动态生成tr,里面填写对应td数据,并追加给tbody
5.重置表单
6..注意防止多次生成多条数据,先清空tbody
1.采用事件委托形式,给tbody注册点击事件
2.点击链接,要删除的是对应数组里面的这个数据,而不是dom节点
1.获取所有需要填写的表单,他们共同特点都有name属性
2.遍历这些表单,如果有一个值为空,则return返回提示输入为空中断程序
3.注意书写的位置,应该放到新增数据的前面,阻止默认行为的后面
- html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta http-equiv="X-UA-Compatible" content="ie=edge" />
- <title>学生信息管理title>
- <link rel="stylesheet" href="css/index.css" />
- head>
-
- <body>
- <h1>新增学员h1>
-
- <form class="info" autocomplete="off">
- 姓名:<input type="text" class="uname" name="uname" />
- 年龄:<input type="text" class="age" name="age" />
- 性别:
- <select name="gender" class="gender">
- <option value="男">男option>
- <option value="女">女option>
- select>
- 薪资:<input type="text" class="salary" name="salary" />
- 就业城市:<select name="city" class="city">
- <option value="北京">北京option>
- <option value="上海">上海option>
- <option value="广州">广州option>
- <option value="深圳">深圳option>
- <option value="曹县">曹县option>
- select>
- <button class="add">录入button>
- form>
-
- <h1>就业榜h1>
- <table>
- <thead>
- <tr>
- <th>学号th>
- <th>姓名th>
- <th>年龄th>
- <th>性别th>
- <th>薪资th>
- <th>就业城市th>
- <th>操作th>
- tr>
- thead>
- <tbody>
-
- tbody>
- table>
- <script>
- //获取元素
- const uname=document.querySelector('.uname')
- const age=document.querySelector('.age')
- const gender=document.querySelector('.gender')
- const salary=document.querySelector('.salary')
- const city=document.querySelector('.city')
- const tbody=document.querySelector('tbody')
- // 获取所有带有name属性的元素
- const items=document.querySelectorAll('[name]')
- //声明一个空的数组 增加和删除都是对这个数组进行操作
- const arr=[]
- // 1.录入模块
- // 1.1表单提交事件
- const info=document.querySelector('.info')
- info.addEventListener('submit',function( e){
- //阻止form默认行为 点击提交之后不跳转至新页面
- e.preventDefault()
- // 这里进行表单验证 如果不通过 直接中断 不需要添加数据
- // 先遍历循环
- for(let i=0;i
length;i++){ - if(items[i].value===''){
- return alert('输入内容不能为空')
- }
- }
- // console.log(11)
- //创建新的对象
- const obj={
- stuID:arr.length+1,
- uname:uname.value,
- age:age.value,
- gender:gender.value,
- salary:salary.value,
- city:city.value
- }
- // console.log(obj)
- //追加到数组里面
- arr.push(obj)
- // console.log(arr)
- //提交之后输入表单
- this.reset()//重置表单 恢复默认状态
- //调用渲染函数
- render()
- })
- function render(){
- //先清空tbody,把最新数组里面的数据渲染完毕
- tbody.innerHTML=''
- // 遍历数组
- for(let i=0;i
length;i++){ - //生成tr
- const tr=document.createElement('tr')
- tr.innerHTML=`
-
${arr[i].stuID} -
${arr[i].uname} -
${arr[i].age} -
${arr[i].gender} -
${arr[i].salary} -
${arr[i].city} -
- ${i}>删除
-
- `
- // 追加元素 父元素.appendChild(子元素)
- tbody.appendChild(tr)
- }
- }
- // 3.删除操作
- // 3.1事件委托 tbody
- tbody.addEventListener('click',function(e){
- if(e.target.tagName==='A'){
- //得到当前元素的自定义属性 data-id
- // console.log(e.target.dataset.id)
- // 删除arr 数组里面对应的数据
- arr.splice(e.target.dataset.id,1)
- // 重新渲染一次
- render()
- }
- })
- script>
-
- body>
-
- html>