作用: 就是使用 JS 去操作 html 和浏览器
分类:DOM (文档对象模型)、BOM(浏览器对象模型)
DOM是浏览器提供的一套专门用来 操作网页内容 的功能
将 HTML 文档以树状结构直观的表现出来,我们称之为文档树或 DOM 树
描述网页内容关系的名词
作用:文档树直观的体现了标签与标签之间的关系
概念:浏览器根据html标签生成的 JS对象,说白了,就是类似java的那种面向对象的对象
document 对象
是 DOM 里提供的一个对象
它提供的属性和方法都是用来访问和操作网页内容的
例:document.write()
网页所有内容都在document里面
(qs和qsa,选则部分和多个)
语法:
2.1下面表示只选则一个选择器
特别强调:()里面必须是字符串,也就是必须加引号
document.querySelector('css属性选择器')
//注意这里的css选择器,就是之前学css的那些,比如像div,span之类的东西
返回值:
CSS选择器匹配的第一个元素,一个 HTMLElement对象。
如果没有匹配到,则返回null。
2.2下面表示选则多个选择器的语法
注意,区别
document.querySelectorAll('ul li')
CSS选择器匹配的NodeList 对象集合
注意:qsa全选最终返回的元素是一个数组形式的,我们想得到的话要用for循环进行遍历
for循环遍历全选的实操如下:
<div>我是一个盒子</div>
<div>我是er个盒子</div>
<div class="three">我是三个盒子</div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<span>就1个</span>
<script>
// 1. js 获取 第一个元素
// let div = document.querySelector('div')
// let div = document.querySelector('.three')
// console.log(div)
// let li = document.querySelector('ul li:last-child')
// console.log(li)
// 2. 获取多个元素 伪数组
let lis = document.querySelectorAll('ul li')
// console.log(lis) [div, div, div]
// 通过遍历的方式,获得里面的每一个dom对象(元素)
for (let i = 0; i < lis.length; i++) {
console.log(lis[i])
}
let span = document.querySelectorAll('span')
console.log(span)
</script>
注意:上面li标签和span标签都是采用全选,并且控制台打印输出,但是结果却呈现下面不同的结果,第四个就是span遍历的时候,因为不是for遍历的,是直接打印的,结果就出错
直接就在页面就打印出来了跟前面input差不多
(下面的html元素已经把这个的作用包括完了,主要讲下面的东西)
// 1. 获取标签(元素)
let box = document.querySelector('div')
// 2. 修改标签(元素)内容 box是对象 innerText 属性
// 对象.属性 = 值 不识别标签
// box.innerText = '有点意思~'
// box.innerText = '有点意思~'
// 3. innerHTML解析标签
box.innerHTML = '有点意思~'
这里的innerHTML后面可以添加任何文字类的东西
不过需要注意的是要用单引号''包括起来
// 1. 获取元素
let box = document.querySelector('div')
// 2. 得到随机的名字
// 随机数()
要求背过!!
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
// 声明一个数组
let arr = ['赵云', '黄忠', '关羽', '张飞', '马超', '刘备', '曹操', 'pink老师']
// 生成1个随机数 作为数组的索引号
取得随机数对象let 对象=getRandom(开始下标,结束下标)
let random = getRandom(0, arr.length - 1)
// console.log(random)
// 3. 写入标签内部
box.innerHTML = arr[random]
// 之后删除这个 人的名字
// arr.splice(从哪里开始删, 删几个)
arr.splice(random, 1)
// console.log(arr)
<img src="./images/1.webp" alt="">
<script>
// 1. 获取图片元素
let pic = document.querySelector('img')
// 2. 随机得到图片序号
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
let num = getRandom(1, 6)
// 3. 完成src 属性赋值
pic.src = `./images/${num}.webp`
</script>
解释:这个操作的目的就是用一个新的类名,且新的操作,来修改原来的样式,将原来的类名和操作样式更换
实操演示
div {
width: 200px;
height: 200px;
background-color: pink;
}
.active {
width: 300px;
height: 300px;
background-color: hotpink;
margin-left: 100px;
}
</style>
</head>
<body>
<div class="one"></div>
<script>
// 1.获取元素
let box = document.querySelector('div')
//修改样式
box.className = 'one active'
</script>
<script>
// 1.获取元素
// let box = document.querySelector('css选择器')
let box = document.querySelector('div')
// add是个方法 添加 追加,这个相当于就是在类名后面加个active的名字
box.classList.add('active')
// remove() 移除 类,移除相当于就是把类名删除了,但是这个盒子的长宽高和颜色依旧保留
box.classList.remove('one')
// 切换类,就是两个类名的css选择器,能一个能切换到宁外个去,转换类名
//one类中盒子是黑色,然后我可以切换到是白色的two类中去,最后显示白色盒子
// box.classList.toggle('one')
</script>
<input type="text" value="请输入">
<button disabled>按钮</button>
<input type="checkbox" name="" id="" class="agree">
<script>
// 1. 获取元素
let input = document.querySelector('input')
// 2. 取值或者设置值 得到input里面的值可以用 value
// console.log(input.value)
input.value = '小米手机'
input.type = 'password'
// 2. 启用按钮
let btn = document.querySelector('button')
// disabled 不可用 = false 这样可以让按钮启用
btn.disabled = false
// // 3. 勾选复选框
let checkbox = document.querySelector('.agree')
checkbox.checked = true
</script>
<script>
//就是网页上常见的那个效果,打开网页,自动翻页那个
//语法 setInterval(函数,间隔时间)
//上面的语法表示 每隔一个时间就调用一次那个时间函数
// setInterval(function () {
// console.log('高薪就业')
// }, 1000)
function show() {
console.log('月薪过2万')
}
let timer = setInterval(show, 1000)
// let timer1 = setInterval(show, 1000)
// 清除定时器,就是停止在定时操作
// clearInterval(timer)
</script>
// 数据
let data = [
{
imgSrc: ‘images/b01.jpg’,
title: ‘挑战云歌单,欢迎你来’
},
{
imgSrc: ‘images/b02.jpg’,
title: ‘田园日记,上演上京记’
},
{
imgSrc: ‘images/b03.jpg’,
title: ‘甜蜜攻势再次回归’
},
{
imgSrc: ‘images/b04.jpg’,
title: ‘我为歌狂,生为歌王’
},
{
imgSrc: ‘images/b05.jpg’,
title: ‘年度校园主题活动’
},
{
imgSrc: ‘images/b06.jpg’,
title: ‘pink老师新歌发布,5月10号正式推出’
},
{
imgSrc: ‘images/b07.jpg’,
title: ‘动力火车来到西安’
},
{
imgSrc: ‘images/b08.jpg’,
title: ‘钢铁侠3,英雄镇东风’
},
{
imgSrc: ‘images/b09.jpg’,
title: ‘我用整颗心来等你’
},
]
//获取元素,图片和h3
let pic = document.querySelector(‘.pic’)
let text = document.querySelector(‘.text’)
let i = 0//记录图片的张数
//因为这几张图片都是采用的是数组存储的方式,那么我们可以通过数组下标,类似于遍历的做法
//2开启定时器
setInterval(function () {
i++//因为点开了网页首先显示的是i=0,即第一张图片,然后第二张图片进行++操作
//并且图片换了,那么图片里的字也要换
//则修改图片中的src属性
pic.src = data[i].imgSrc//这句话的意思相当于就是,前面pic.src=表示重定值
//后面的date[i]表示date数组中第i个元素的值,然后又调用imgSrc,表示将date数组中进行i++,加到哪个数
//然后那个对应的图片的路径赋值给pic对象中的src属性,
//简单地说上面的操作就是按到顺序来进行图片换图片
text.innerHTML = data[i].title
//然后有一个值得注意的点就是
//图片和文字只有9张,那么在数组里头相当于就是只有0-8的索引号
//我们想要的效果就是第九张图片播放完了然后会接着播放,就是那种循环的效果
//那么这里就可以设置循环来播放
// 无缝衔接
if (i === data.length - 1) {
i = -1
}
// i === 8 ? i = -1 : i
}, 1000)
什么是事件?
事件是在编程时系统内发生的动作或者发生的事情
比如用户在网页上单击一个按钮
就是一个
什么是事件监听?
就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 注册事件
语法:
实操
解释:步骤就两步
1,获取元素,用个变量来接,
2,变量名,addEventListener(‘事件’, 事件处理函数)
(注意;这里的事件可以是点击click还有就是后面的会学的鼠标移开的事件)
<button>点击我</button>
<script>
//1. 获取按钮元素
let btn = document.querySelector('button')
//2. 事件监听 绑定事件 注册事件 事件侦听
// 事件源.addEventListener('事件', 事件处理函数)
btn.addEventListener('click', function () {
alert('月薪过万')
})
</script>
<script>
// 1. 获取元素 事件源 i 关闭的 erweima
let close_btn = document.querySelector('.close_btn')
let erweima = document.querySelector('.erweima')
// 2. 事件监听
close_btn.addEventListener('click', function () {
// erweima 关闭 他是隐藏的
erweima.style.display = 'none'
})
</script>
案列:小米搜索框
涉及到;focus和burl两个事件。具体含义如下
Focus事件当元素获得焦点时,触发focus事件。当通过鼠标点击或选中元素或通过tab键定位到元素时,该元素就会获得焦点。Focus()方法触发focus事件,或规定当发生focus事件是运行的函数。
Blur事件会在元素失去焦点时触发,既可以是鼠标行为,也可以是按tab键离开的。与foucsout一样,元素失去焦点时触发。两者唯一的区别存在于foucsout可以在父 元素上检测子元素失去焦点的情况。
当元素获得焦点时触发focus事件,执行focus函数。失去焦点时,触发blur事件,执行blur函数。
// 1. 获取元素 input
let search = document.querySelector('input')
let list = document.querySelector('.result-list')
// 2. 事件监听 获得光标事件 focus
个人理解,他这里的获取标focus应该意思应该就是鼠标一点了过后
search.addEventListener('focus', function () {
// 显示下拉菜单
list.style.display = 'block'
// 文本框变色
this.classList.add('search')
})
// 3. 事件监听 失去光标事件 blur
search.addEventListener('blur', function () {
// 隐藏下拉菜单
list.style.display = 'none'
// 文本框去色
this.classList.remove('search')
})
<script>
// 1. 获取元素 全选 和 ck 小复选框
let all = document.querySelector('#checkAll')
let cks = document.querySelectorAll('.ck')
let span = document.querySelector('span')
// 2. 事件监听 全选按钮
all.addEventListener('click', function () {
// console.log(all.checked) // true false
// 我们需要做的就是把 all.checked 给下面三个小按钮
// 因为三个按钮在伪数组里面,我们需要遍历的方式,挨着取出来,依次给值
for (let i = 0; i < cks.length; i++) {
cks[i].checked = all.checked
}
// 当我们的全选按钮处于选中状态,则可以改为取消
if (all.checked) {
// console.log('要改')
span.innerHTML = '取消'
} else {
span.innerHTML = '全选'
}
})
// 3. 小按钮的做法 同时给多个元素绑定相同事件
for (let i = 0; i < cks.length; i++) {
// 绑定事件
cks[i].addEventListener('click', function () {
// console.log(11)
// 只要点击任何一个小按钮,都要遍历所有的小按钮
for (let j = 0; j < cks.length; j++) {
// 都来看看是不是有人没有选中
if (cks[j].checked === false) {
// 如果有false 则退出循环 结束函数
all.checked = false
span.innerHTML = '全选'
return
}
}
// 当我们的循环结束,如果代码走到这里,说明没有false,都被选中了,则全选按钮要选中
all.checked = true
span.innerHTML = '取消'
})
}
注意:这里省略了一个发布文字的案列,那个效果就是你发布文字,他能显示出你写了多少字‘了,并且还会有个字数限制
<script>
let num = 10
//函数表达式
let fn = function () { }
btn.onclick = function () { }
// 高阶函数 函数的高级用法,把函数当值来看看
// 回调函数
// setInterval(function(){}, 1000)
function fn() { }
setInterval(fn, 1000)
// 此时 fn 就是回调函数 回头去调用的函数
box.addEventListener('click', fun)
function fun() {
}
</script>
<button>点击</button>
<script>
// 环境对象 this 他就是个对象
function fn() {
console.log(this)//这里会打印出结果,也就是window,因为window指向了这个对象
}
// fn()
window.fn()///
let btn = document.querySelector('button')
btn.addEventListener('click', function () {
console.log(typeof this)
// 会打印btn 因为btn 调用了这个函数,所以 this 指向btn
})
</script>
排他思想,就相当于是网页中的那种操作,两个相同的css选择器中,比如两个黑白色的盒子,然后我们想得到白色的盒子,就先要让两个盒子先采用for循环给每个都添加事件,然后采用第二个for,移除每个对象加的事件,最后用环境对象this把自己添加事件,也就是通俗意义上的复活
<button>第1个</button><button>第2个</button><button>第3个</button><button>第4个</button><button>第5个</button>
<script>
let btns = document.querySelectorAll('button')
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function () {
// this.classList.add('pink')
// 干掉所有人
for (let j = 0; j < btns.length; j++) {
btns[j].classList.remove('pink')
}
// 复活我自己
this.classList.add('pink')
})
}
</script>
案列
子元素.parentNode
父节点操作
<div class="father">
<div class="son">儿子</div>
</div>
<script>
子元素.parentNode
let son = document.querySelector('.son')
// 找爸爸
// console.log(son.parentNode)
son.parentNode.style.display = 'none'
</script>
案列:关闭二维码(就是给二维码打×,就会关闭二维码照片)
<script>
// 1. 获取元素 关闭按钮
let close_btn = document.querySelectorAll('.close')
// 2. 绑定多个点击事件给close
for (let i = 0; i < close_btn.length; i++) {
close_btn[i].addEventListener('click', function () {
// 3. 关闭当前的那个二维码 点击谁,就关闭谁的爸爸
this.parentNode.style.visibility = 'hidden'
})
}
</script>
父元素.children
操作(就是一点按钮,会把几个小li变色)
let btn = document.querySelector('button')
let ul = document.querySelector('ul')
btn.addEventListener('click', function () {
// console.log(ul.children)
for (let i = 0; i < ul.children.length; i++) {
ul.children[i].style.color = 'red'
}
})
ul.children[0].style.color = 'green'
// console.log(ul.childNodes)
<button>点击</button>
<ul>
<li>第1个</li>
<li class="two">第2个</li>
<li>第3个</li>
<li>第4个</li>
</ul>
<script>
let btn = document.querySelector('button')
let two = document.querySelector('.two')
btn.addEventListener('click', function () {
// two.style.color = 'red'
two.nextElementSibling.style.color = 'red'
two.previousElementSibling.style.color = 'red'
})
</script>
document.createElement
实操
<ul>
<li>我是大毛</li>
<li>我是二毛</li>
</ul>
<script>
// 二毛 ul.children[1]
// 1. 创建新的标签节点
// let div = document.createElement('div')
// div.className = 'current'
let ul = document.querySelector('ul')
let li = document.createElement('li')
li.innerHTML = '我是xiao ming'
// 2. 追加节点 父元素.appendChild(子元素) 后面追加
// ul.appendChild(li)
// 3. 追加节点 父元素.insertBefore(子元素, 放到那个元素的前面)
ul.insertBefore(li, ul.children[0])
</script>
<button>点击</button>
<ul>
<li>我是内容11111</li>
</ul>
<script>
// 需求,点击按钮,删除小li
let btn = document.querySelector('button')
let ul = document.querySelector('ul')
btn.addEventListener('click', function () {
// 删除的语法 父元素.removeChild(子元素)
ul.removeChild(ul.children[0])
})
</script>
时间对象:用来表示时间的对象
作用:可以得到当前系统时间
let date = new Date()
console.log(date)
// 小括号里面写上时间,可以返回指定的时间
let last = new Date('2021-8-29 18:30:00')
console.log(last)
作用:在控制台输出打印可以得到,当前时间和指定时间,不过都是英文格式的时间
// new 实例化 时间对象
// 小括号为空可以得到当前的时间
let date = new Date()
console.log(date.getFullYear())
console.log(date.getMonth() + 1)
console.log(date.getDate())
// 时分秒
console.log(date.getHours())
console.log(date.getMinutes())
console.log(date.getSeconds())
// 星期几
console.log(date.getDay())
let arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
let div = document.querySelector('div')
// 先调用,就省去了1秒的空白期
getTime()
setInterval(getTime, 1000)
function getTime() {
// 1. 实例化时间对象 一定写到定时器里面才可以额
let date = new Date()
let year = date.getFullYear()
let month = date.getMonth() + 1
let date1 = date.getDate()
let hour = date.getHours()
let min = date.getMinutes()
let sec = date.getSeconds()
let day = date.getDay()
div.innerHTML = `今天是: ${year}年${month}月${date1}日 ${hour}:${min}:${sec} ${arr[day]}`
}
理解:通俗地说就是返回从1970年后到现在时间的毫秒值
时间戳的操作:
// 时间戳是总的毫秒数 是独一无二的
// 计算倒计时: 核心思想:
// 将来时间 9.1 12:00 有一个时间戳 2000000
// 现在的时间 8.29 15:00 有一个时间戳 1000000
// 可以利用将来的时间戳 减去 现在的时间戳 就是剩余的时间毫秒数
// 转换为时分秒就是剩余的时间了
// 1. getTime()
// let date = new Date()
// console.log(date.getTime())
// 2. +new Date()
console.log(+new Date()) // 当前的时间戳
console.log(+new Date('2023-8-30 12:00:00')) // 指定时间的时间戳
// 3. 只能得到当前的
// console.log(Date.now())
let hour = document.querySelector('#hour')
let minutes = document.querySelector('#minutes')
let scond = document.querySelector('#scond')
time()
setInterval(time, 1000)
function time() {
// 1. 得到现在的时间戳
let now = +new Date()
// 2. 得到指定时间的时间戳
let last = +new Date('2023-1-22 00:00:00')
// 3. (计算剩余的毫秒数) / 1000 === 剩余的秒数
let count = (last - now) / 1000
// console.log(count)
// 4. 转换为时分秒
// h = parseInt(总秒数 / 60 / 60 % 24) // 计算小时
let h = parseInt(count / 60 / 60 % 24)
h = h < 10 ? '0' + h : h
// m = parseInt(总秒数 / 60 % 60); // 计算分数
let m = parseInt(count / 60 % 60)
m = m < 10 ? '0' + m : m
// s = parseInt(总秒数 % 60); // 计算当前秒数
let s = parseInt(count % 60);
s = s < 10 ? '0' + s : s
// console.log(h, m, s)
hour.innerHTML = h
minutes.innerHTML = m
scond.innerHTML = s
}
<script>
// maxlength 是一个表单属性, 作用是给表单设置一个最大长度
// 模拟数据
let dataArr = [
{ uname: '司马懿', imgSrc: './images/9.5/01.jpg' },
{ uname: '女娲', imgSrc: './images/9.5/02.jpg' },
{ uname: '百里守约', imgSrc: './images/9.5/03.jpg' },
{ uname: '亚瑟', imgSrc: './images/9.5/04.jpg' },
{ uname: '虞姬', imgSrc: './images/9.5/05.jpg' },
{ uname: '张良', imgSrc: './images/9.5/06.jpg' },
{ uname: '安其拉', imgSrc: './images/9.5/07.jpg' },
{ uname: '李白', imgSrc: './images/9.5/08.jpg' },
{ uname: '阿珂', imgSrc: './images/9.5/09.jpg' },
{ uname: '墨子', imgSrc: './images/9.5/10.jpg' },
{ uname: '鲁班', imgSrc: './images/9.5/11.jpg' },
{ uname: '嬴政', imgSrc: './images/9.5/12.jpg' },
{ uname: '孙膑', imgSrc: './images/9.5/13.jpg' },
{ uname: '周瑜', imgSrc: './images/9.5/14.jpg' },
{ uname: '老夫子', imgSrc: './images/9.5/15.jpg' },
{ uname: '狄仁杰', imgSrc: './images/9.5/16.jpg' },
{ uname: '扁鹊', imgSrc: './images/9.5/17.jpg' },
{ uname: '马可波罗', imgSrc: './images/9.5/18.jpg' },
{ uname: '露娜', imgSrc: './images/9.5/19.jpg' },
{ uname: '孙悟空', imgSrc: './images/9.5/20.jpg' },
{ uname: '黄忠', imgSrc: './images/9.5/21.jpg' },
{ uname: '百里玄策', imgSrc: './images/9.5/22.jpg' },
]
// 需求1:检测用户输入字数
// 1. 注册input事件
// 2. 将文本的内容的长度赋值给对应的数值
// 3. 表单的maxlength属性可以直接限制在200个数之间
let textarea = document.querySelector('textarea')
let useCount = document.querySelector('.useCount')
// 发布按钮
let send = document.querySelector('#send')
// ul
let ul = document.querySelector('#list')
textarea.addEventListener('input', function () {
// console.log(this.value.length)
// this.value可以获取当前输入的值,那么就可以想方法把this的value输入值和那个串联起来
useCount.innerHTML = this.value.length
})
// 需求2: 输入不能为空
注意观察,就是在输入框里点了一下,然后你按空格,他这里面也会计入数值的
我们就需要设置判断条件,让他按空格之后不会算字符数,并且发布不能为空
// 点击button之后判断
// 判断如果内容为空,则提示不能输入为空, 并且直接return 不能为空
// 防止输入无意义空格, 使用字符串.trim()去掉首尾空格
// console.log(' str')
// console.log(' str '.trim())
// 并将表单的value值设置为空字符串
// 同时下面红色为设置为0
send.addEventListener('click', function () {
if (textarea.value.trim() === '') {
// 并将表单的value值设置为空字符串
textarea.value = ''
// 同时下面红色为设置为0
useCount.innerHTML = 0
return alert('内容不能为空')
}
// 随机数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
let random = getRandom(0, dataArr.length - 1)
// 需求3: 新增留言 写到send 的里面
// 创建一个小li,然后里面通过innerHTML追加数据
注意这里的creatElment是创建一个新的节点的意思,表示随着新发布一个评论,多一个新节点
let li = document.createElement('li')
// 随机获取数据数组里面的内容, 替换newNode的图片和名字以及留言内容
注意:这里的innerHTML表示的意思是追加的意思,表示新添加一个
li.innerHTML = `
${dataArr[random].imgSrc}>
${dataArr[random].uname}
${new Date().toLocaleString()}
${textarea.value}
X
`
// 需求4:删除留言 放到追加的前面
// 在事件处理函数里面获取点击按钮, 注册点击事件
// (易错点: 必须在事件里面获取, 外面获取不到)
// 删除对应的元素(通过this获取对应的那条需要删除的元素)
// 教你一招: 放到追加进ul的前面,这样创建元素的同时顺便绑定了事件,赞~~
// 使用 li.querySelector()
let del = li.querySelector('.the_del')
del.addEventListener('click', function () {
// 删除操作 点击的是X 删除的小li 父元素.removeChild(子元素)
ul.removeChild(li)
})
// 利用时间对象将时间动态化 new Date().toLocaleString()
// 追加给 ul 用 父元素.insertBefore(子元素, 那个元素的前面)
ul.insertBefore(li, ul.children[0])
// 需求5:重置
// 将表单域内容重置为空
// 将userCount里面的内容重置为0
textarea.value = ''
// 同时下面红色为设置为0
useCount.innerHTML = 0
})
</script>
<button>点击</button>
<script>
let btn = document.querySelector('button')
btn.addEventListener('mouseenter', function (e) {
console.log(e)
})
// mousemove 鼠标移动事件
document.addEventListener('click', function (e) {
// console.log(11)
// pageX 和 pageY 跟文档坐标有关系
// console.log(e)
console.log('clientX:' + e.clientX, 'clientY:' + e.clientY)
console.log('pageX:' + e.pageX, 'pageY:' + e.pageY)
console.log('offsetX:' + e.offsetX, 'offsetY:' + e.offsetY)
})
document.addEventListener('mousemove', function (e) {
// 不断得到当前的鼠标坐标
// console.log(e.pageX)
// console.log(e.pageY)
// 把坐标给图片
// img.style.left = '100px'
img.style.left = e.pageX - 50 + 'px'
img.style.top = e.pageY - 40 + 'px'
})
说明:假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段
简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('click', function () {
alert('我是爸爸')
}, true)
son.addEventListener('click', function () {
alert('我是儿子')
}, true)
document.addEventListener('click', function () {
alert('我是爷爷')
}, true)
注意,就是这里的末尾添加了true,表示确认事件捕获
点击后,界面弹出来的是自上而下的爷父子,然而如果去掉true或者设置为false就会成事件捕获,即自上而下,子父爷的弹出
// btn.onclick = function() {}
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('click', function (e) {
alert('我是爸爸')
e.stopPropagation()
这里就是具体的用法
})
son.addEventListener('click', function (e) {
alert('我是儿子')
// 阻止流动 Propagation 传播
e.stopPropagation()
})
document.addEventListener('click', function () {
alert('我是爷爷')
})
鼠标经过事件
推荐还是主要写mouseenter和mouseleave
因为前面的mouseover和mouseout会产生冒泡,即就是在鼠标移动的时候会自动增加
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('mouseenter', function () {
console.log(111)
})
<a href="http://www.baidu.com">跳转到百度</a>
<script>
let a = document.querySelector('a')
a.addEventListener('click', function (e) {
// 阻止默认行为 方法
e.preventDefault()
})
</script>
<button>点击</button>
<script>
let btn = document.querySelector('button')
// 1.l0 on
// 多次相同的事件,只执行最后一次
// btn.onclick = function () {
// alert('第一次')
// }
// btn.onclick = function () {
// alert('第二次')
// }
// 解绑事件
// btn.onclick = null
// 2. addEventListener
btn.addEventListener('click', add)
function add() {
alert('第一次')
}
// btn.addEventListener('click', function () {
// alert('第二次')
// })
btn.removeEventListener('click', add)
</script>
<script>
// 不要每个小li注册事件了 而是把事件委托给他的爸爸
// 事件委托是给父级添加事件 而不是孩子添加事件
let ul = document.querySelector('ul')
ul.addEventListener('click', function (e) {
// alert('我点击了')
// 得到当前的元素
// console.log(e.target)
e.target.style.color = 'red'
})
</script>
// 1. 准备好数据后端的数据
let arr = [
{ stuId: 1001, uname: '欧阳霸天', age: 19, gender: '男', salary: '20000', city: '上海' },
{ stuId: 1002, uname: '令狐霸天', age: 29, gender: '男', salary: '30000', city: '北京' },
{ stuId: 1003, uname: '诸葛霸天', age: 39, gender: '男', salary: '2000', city: '北京' },
]
// 获取父元素 tbody
let tbody = document.querySelector('tbody')
// 添加数据按钮
// 获取录入按钮
let add = document.querySelector('.add')
// 获取各个表单的元素
let uname = document.querySelector('.uname')
let age = document.querySelector('.age')
let gender = document.querySelector('.gender')
let salary = document.querySelector('.salary')
let city = document.querySelector('.city')
// 渲染函数 把数组里面的数据渲染到页面中
function render() {
// 先干掉以前的数据 让tbody 里面原来的tr 都没有
tbody.innerHTML = ''
// 在渲染新的数据
// 根据数据的条数来渲染增加 tr
for (let i = 0; i < arr.length; i++) {
// 1.创建tr
let tr = document.createElement('tr')
// 2.tr 里面放内容
tr.innerHTML = `
${arr[i].stuId}
${arr[i].uname}
${arr[i].age}
${arr[i].gender}
${arr[i].salary}
${arr[i].city}
${i}">删除
`
// 3.把tr追加给 tobdy 父元素.appendChild(子元素)
tbody.appendChild(tr)
}
}
// 页面加载就调用函数
render()
add.addEventListener('click', function () {
// alert(11)
// 获得表单里面的值 之后追加给 数组 arr 用 push方法
arr.push({
// 得到数组最后一条数据的学号 1003 + 1
stuId: arr[arr.length - 1].stuId + 1,
uname: uname.value,
age: age.value,
gender: gender.value,
salary: salary.value,
city: city.value
})
// console.log(arr)
// 重新渲染我们的函数
render()
// 复原所有的表单数据
uname.value = age.value = salary.value = ''
gender.value = '男'
city.value = '北京'
})
// 删除操作, 删除的也是数组里面的数据 , 但是我们用事件委托
tbody.addEventListener('click', function (e) {
// alert(11)
// 我们只能点击了链接 a ,才会执行删除操作
// 那我们怎么知道你点击了a呢?
// 俺们只能点击了链接才能做删除操作
// console.dir(e.target.tagName)
if (e.target.tagName === 'A') {
// alert('你点击了链接')
// 删除操作 删除 数组里面的数据 arr.splice(从哪里开始删,1)
// 我要得到a的id 需要
// console.log(e.target.id)
arr.splice(e.target.id, 1)
// 重新渲染我们的函数
render()
}
})
</script>
<div>
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
我里面可以放很多的文字
</div>
<script>
let div = document.querySelector('div')
window.addEventListener('scroll', function () {
console.log(111)
})
// div.addEventListener('scroll', function () {
// console.log(111)
// })
</script>
使用场景:
我们想要页面滚动一段距离,比如100px,就让某些元素
显示隐藏,那我们怎么知道,页面滚动了100像素呢?
就可以使用scroll 来检测页面滚动的距离~~
在这里插入图片描述
使用场景:
前面案例滚动多少距离,都是我们自己算的,最好是页面
滚动到某个元素,就可以做某些事。
简单说,就是通过js的方式,得到元素在页面中的位置
这样我们可以做,页面滚动到这个位置,就可以返回
顶部的小盒子显示
两种定时器对比:
setInterval 的特征是重复执行,首次执行会延时
setTimeout 的特征是延时执行,只执行 1 次
setTimeout 结合递归函数,能模拟 setInterval 重复执行
clearTimeout 清除由 setTimeout 创建的定时任务
JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为 Javascript 这
门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比
如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问
题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
3.1 本地存储特性
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在
本地存储大量的数据,HTML5规范提出了相关解决方案。
1、数据存储在用户浏览器中
2、设置、读取方便、甚至页面刷新不丢失数据
3、容量较大,sessionStorage和localStorage约 5M 左右
3.2 localStorage
1、生命周期永久生效,除非手动删除 否则关闭页面也会存在
2、可以多窗口(页面)共享(同一浏览器可以共享)
3. 以键值对的形式存储使用