1-addEventListener注册事件
1.1掌握dom两种注册事件语法特点:
(1).点语法注册事件: 事件源.事件类型 = 事件处理函数
* 特点:不能注册‘同名事件’, 否则会覆盖
(2).事件源.addEventListener('事件类型',事件处理函数)
* 特点:可以注册‘同名事件’,依次触发
addEventListener
第一个参数:事件类型 前面不需要加 on 例如onclick直接写成click
第二个事件处理函数
点语法注册事件: 事件源.事件类型 = 事件处理函数
let box = document.querySelector('#box')
box.onclick = function () {
alert('假如生活欺骗你')
}
addEventListener():事件源.addEventListener('事件类型',事件处理函数)
let box = document.querySelector('#box')
box.addEventListener('click', function () {
alert('我们的朋友')
})
box.addEventListener('click', function () {
alert('是勤奋和努力')
})
2-removeEventListener移除事件
点语法注册事件: 事件源.事件类型 = 事件处理函数
let box = document.querySelector('#box')
box.onclick = function () {
alert('假如生活欺骗了你')
}
移除事件
box.onclick = null
addEventListener()移除事件
box.addEventListener( 'click' ,function(){
alert('1-假如生活欺骗了你,请不要悲伤')
} )
function fn(){
alert('2-请不要悲伤,因为它明天一定会继续欺骗你')
}
/*
fn: 变量取值。 取出的是fn的地址
fn(): 函数调用。 取出的是fn的返回值
box.addEventListener( 'click' , fn )//取出的是fn的地址和数据
box.removeEventListener('click', fn )
3-阻止默认事件
3.1.黙认事件:html中有部分标签自带点击事件 : form表单,a标签
3.2.如果给这些标签注册点击事件,会默认跳转.
黙认事件对开发影响:form表单和a标签注册点击事件,,则会(1)先执行注册点击事件
(2)后执行黙认点击跳转业
3.3 阻止默认事件 : 执行自己注册的事件
e.preventDefault()
3.4.阻止默认跳转应用:如果想给form表单和a标签注册点击事件,就需要阻止默认跳转
(1)方式一: e.preventDefault()
获取元素
let a = document.querySelector('a')
let btn = document.querySelector('.btn')
注册事件
a.onclick = function(e){
e.preventDefault()
console.log('111111')
}
btn.onclick = function(e){
let uname = document.querySelector('.username').value
let pwd = document.querySelector('.password').value
console.log( uname,pwd )
e.preventDefault()
}
(2)方式二: 设置a标签的href <a href="javascript:;"></a>
4. 事件对象介绍
/*
1.事件对象 : 是存储与事件相关的对象。
* 当用户触发事件的时候,浏览器会自动捕捉触发时(鼠标坐标和键盘按键)的信息,存入对象中。
这个对象称之为事件对象。
2.如何获取事件对象 : 给事件处理函数添加形参 event ev e
3.事件对象常用属性 :
*/
<div id="box" style="width: 200px;
height: 200px;background-color: red"></div>
let box = document.querySelector('#box')
box.onclick = function (e) {
console.log(e);
alert(111)
}//点击红色盒子会弹出111
5. 事件对象常用属性
1.事件对象: 存储事件相关数据
2.事件对象语法 :
声明: 浏览器在触发事件的时候,自动存储触发数据(鼠标坐标、键盘按键)
取值: 给事件处理函数添加形参 e
3.事件对象常用属性和方法
e.pageX / e.pageY : 鼠标触发点到页面 左上角 距离
<style>
body {
width: 3000px;
height: 3000px;
}
#box {
position: absolute;
left: 50px;
top: 50px;
}
</style>
</head>
<body>
<div id="box" style="width: 200px;
height: 200px;background-color: red"></div>
<script>
let box = document.querySelector('#box')
//注册点击事件
box.onclick = function (e) {
console.log(e)
//pageX/Y : 获取鼠标触发点到 页面 左上角距离(定位坐标系)
console.log('pageX:' + e.pageX + ' pageY:' + e.pageY)
}
</script>
案例:鼠标跟随移动
/*
1.鼠标事件
鼠标单击:onclick
鼠标双击:ondblclick
鼠标移入:onmouseenter
鼠标移出:onmouseleave
鼠标移动:onmousemove
2.网页鼠标移动 : window.onmousemove
*/
img {
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<img src="./tianshi.gif" alt="" />
<script>
window.onmousemove = function (e) {
//上面位置不能用body,因为body的高度由内容撑开,图片只能在图片高度的位置移动
只能用window.onmousemove或者document.documentElement
console.log('鼠标移出');
console.log(e.pageX, e.pageY)
let img = document.querySelector('img')
//pageX是数字,赋值的时候需要在后面拼接单位'px'
img.style.left = e.pageX + 'px'
img.style.top = e.pageY + 'px'
}
</script>
window.onmousemove 获取整个窗口
document.documentElement 获取dom树下的根元素html
6.键盘事件及获取按键
1.键盘事件总结
oninput:键盘输入(一般用于实时获取输入框'内容'')
onfocus:键盘成为焦点
onblur:键盘失去焦点
onkeydown:键盘按下(一般用于获取按键)
onkeyup:键盘松开
2.如何获取用户按键
e.key:按键字串
e.keyCode:键盘ASCII码(键盘上的每一个按键对应一个数字,称之为ASCII码)
确认键ASCII码:13
document.querySelector('input').onkeydown = function (e) {
console.log(e);
console.log(e.key, e.keyCode)
if (e.key == 'Enter') {
alert('用户按了enter键')
}
// keyCode : enter的ascii码
if (e.keyCode == 13) {
console.log('执行搜索功能')
}
}
document.querySelector('input').onkeyup = function () {
// console.log('2-键盘松开')
7. 事件冒泡介绍
1.事件冒泡: 当触发子元素的事件时,该子元素的所有“父级元素” 的“同名事件”会依次触发
* 事件冒泡现象一直都存在,只是以前没有给父元素注册同名事件
* 子元素 -> 父元素 -> body -> html -> document -> window
子元素
document.querySelector('.son').addEventListener('click', function () {
alert('我是子元素')
})
父元素
document.querySelector('.father').addEventListener('click', function () {
alert('我是父元素')
})
body
document.body.addEventListener('click', function () {
alert('我是body')
})
html
document.documentElement.addEventListener('click', function () {
alert('我是html')
})
document
document.addEventListener('click', function () {
alert('我是document')
})
window
document.addEventListener('click', function () {
alert('我是window')
})
8.事件委托
(1).事件委托 :给"动态新增"元素注册事件
(2)什么是事件委托:给父元素注册事件,委托子元素处理
(3) 事件委托原理:事件冒泡
(4)事件委托注意点:
this:不能使用.this指向父元素
e.target:推荐使用.事件目标指向触发冒泡的子元素
需求: 点击按钮,新增li元素,并且点击新增li元素的内容,改变新增内容的颜色
<button class="btn">点我新增一行li元素</button>
<ul>
<li>我是班长1</li>
<li>我是班长2</li>
<li>我是班长3</li>
<li>我是班长4</li>
<li>我是班长5</li>
<li>我是班长6</li>
</ul>
(1)点击按钮,新增li元素
document.querySelector('.btn').onclick = function () {
创建空标签
let newLi = document.createElement('li')
设置内容
newLi.innerText = '我是新来的'
添加到ul
document.querySelector('ul').appendChild(newLi)
}
事件委托:给父元素注册事件,委托子元素处理
document.querySelector('ul').onclick = function (e) {
this:父元素ul
console.log(this);
e : 事件对象
console.log(e);
e.target:事件目标(点哪一个li触发的冒泡)
e.target.style.backgroundColor = 'pink'
}
9. 事件捕获
1.事件捕获 : 当触发子元素的事件时候,先从最顶级父元素,一级一级往里触发
1.1 规则: window->document->html->body->父元素->子元素
2.默认情况下,所有的注册事件都是冒泡事件。 只有唯一一种方式可以注册捕获事件:
元素.addEventListener('事件类型',事件处理函数,true)
<style>
.father {
width: 300px;
height: 300px;
background-color: red;
}
.son {
width: 100px;
height: 100px;
background-color: cyan;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
//子元素
document.querySelector('.son').addEventListener('click',function(){
alert('我是蓝色子元素')
},true)
//父元素
document.querySelector('.father').addEventListener('click',function(){
alert('我是红色父元素')
},true)
//body
document.body.addEventListener('click',function(){
alert('我是body')
},true)
//html
document.documentElement.addEventListener('click',function(){
alert('我是html')
},true)
//document
document.addEventListener('click',function(){
alert('我是document')
},true)
//window
window.addEventListener('click',function(){
alert('我是window')
},true)
10.事件流三个阶段
事件流三个阶段: e.eventPhase
1-捕获阶段
2-目标阶段
3-冒泡阶段
//子元素
// document.querySelector('.son').addEventListener('click',function(e){
// alert('我是蓝色子元素' + e.eventPhase )
// },false)//冒泡
//父元素
document.querySelector('.father').addEventListener('click', function (e) {
alert('我是红色父元素' + e.eventPhase)
}, false)
//body
document.body.addEventListener('click', function (e) {
alert('我是body' + e.eventPhase)
}, false)
//html
document.documentElement.addEventListener('click', function (e) {
alert('我是html' + e.eventPhase)
}, false) //冒泡
//document
document.addEventListener('click', function (e) {
alert('我是document' + e.eventPhase)
}, true) //捕获
//window
window.addEventListener('click', function (e) {
alert('我是window' + e.eventPhase)
}, true) //捕获
11. 阻止事件流动
阻止事件流动 :e.stopPropagation()
无论是冒泡还是捕捉都可以阻止(停止事件流)
//子元素
document.querySelector('.son').addEventListener('click', function (e) {
alert('我是蓝色子元素' + e.eventPhase)
}, false) //冒泡
//父元素
document.querySelector('.father').addEventListener('click', function (e) {
alert('我是红色父元素' + e.eventPhase)
}, false)
//body
document.body.addEventListener('click', function (e) {
alert('我是body' + e.eventPhase)
}, false)
//html
document.documentElement.addEventListener('click', function (e) {
alert('我是html' + e.eventPhase)
}, false) //冒泡
//document
document.addEventListener('click', function (e) {
alert('我是document' + e.eventPhase)
}, true) //捕获
//window
window.addEventListener('click', function (e) {
alert('我是window' + e.eventPhase)
e.stopPropagation()
}, true) //捕获
12.案例:排他思想---循环排他(万能的)
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
/*
1.排他思想场景 : 多个元素,只能选中一个(多选一)
2.排他思想流程 :(1)干掉所有兄弟 (2)复活自己
*/
//1.获取页面元素
let buttonList = document.querySelectorAll('button')
//2.给每一个按钮注册点击事件
for (let i = 0; i < buttonList.length; i++) {//i = 0 1 2 3 4
buttonList[i].onclick = function () {
/*
i : 你点击的按钮下标
buttonList[i] : 你点击的按钮
this === buttonList[i]: 你点击的按钮
*/
console.log(i, buttonList[i], this)
//排他思想 两个步骤
//(1)干掉所有兄弟
for (let j = 0; j < buttonList.length; j++) {
buttonList[j].style.backgroundColor = ''
}
//(2)复活自己
this.style.backgroundColor = 'pink'
}
}
</script>
</body>
13.案例 搜索框
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
.mi {
position: relative;
width: 223px;
margin: 100px auto;
}
.mi input {
width: 223px;
height: 48px;
padding: 0 10px;
font-size: 14px;
line-height: 48px;
border: 1px solid #e0e0e0;
outline: none;
}
.mi .search {
border: 1px solid #ff6700;
}
.result-list {
position: absolute;
left: 0;
top: 48px;
width: 223px;
border: 1px solid #ff6700;
border-top: 0;
background: #fff;
}
.result-list a {
display: block;
padding: 6px 15px;
font-size: 12px;
color: #424242;
text-decoration: none;
}
.result-list a:hover {
background-color: #eee;
}
</style>
</head>
<body>
<div class="mi">
<input type="search" placeholder="小米笔记本" />
<ul class="result-list" style="display: none">
<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>
const input = document.querySelector('input')
const ul = document.querySelector('.result-list')
input.addEventListener('focus', function () {
input.classList.add('search')
ul.style.display = 'block'
})
input.addEventListener('blur', function () {
input.classList.remove('search')
ul.style.display = 'none'
})
</script>
14.案例 随机点名
<style>
* {
margin: 0;
padding: 0;
}
h2 {
text-align: center;
}
.box {
width: 600px;
margin: 50px auto;
display: flex;
font-size: 25px;
line-height: 40px;
}
.qs {
width: 450px;
height: 40px;
color: red;
}
.btns {
text-align: center;
}
.btns button {
width: 120px;
height: 35px;
margin: 0 50px;
}
</style>
</head>
<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 = ['马超', '黄忠', '赵云', '关羽', '张飞']
let id
let i
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
//获取标签
const start = document.querySelector('.start')
const qs = document.querySelector('.qs')
//给开始按钮注册事件
start.addEventListener('click', function () {
if (id) clearInterval(id)
//开始定时器
id = setInterval(function () {
i = getRandom(0, arr.length - 1)
qs.innerHTML = arr[i]
}, 100)
//判断数组的长度,当长度等于1时就禁用开始按钮和结束按钮
if (arr.length === 1) {
start.disabled = true
end.disabled = true
}
})
//获取结束标签
const end = document.querySelector('.end')
//给结束按钮注册事件
end.addEventListener('click', function () {
//停止定时器
clearInterval(id)
//删除这个补选中的元素
arr.splice(i, 1)
}
)
</script>
15.案例 全选反选
<style>
* {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #c0c0c0;
width: 500px;
margin: 100px auto;
text-align: center;
}
th {
background-color: #09c;
font: bold 16px "微软雅黑";
color: #fff;
height: 24px;
}
td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
.allCheck {
width: 80px;
}
</style>
</head>
<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 checkAll = document.querySelector('#checkAll')
const ck = document.querySelectorAll('.ck')
//给最上面的盒子注册事件
checkAll.addEventListener('click', function () {
//循环每一个小盒子
for (let i = 0; i < ck.length; i++) {
ck[i].checked = checkAll.checked
}
})
for (let i = 0; i < ck.length; i++) {
//给下面的盒子注册点击事件
ck[i].addEventListener('click', function () {
//获取下面盒子的元素的长度(借助css选择器:checked)
const ckLength = document.querySelectorAll('.ck:checked').length
checkAll.checked = ckLength === ck.length
})
}
</script>
16.评论回车发布
<style>
.wrapper {
min-width: 400px;
max-width: 800px;
display: flex;
justify-content: flex-end;
}
.avatar {
width: 48px;
height: 48px;
border-radius: 50%;
overflow: hidden;
background: url(./images/avatar.jpg) no-repeat center / cover;
margin-right: 20px;
}
.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 button {
background: #00aeec;
color: #fff;
border: none;
border-radius: 4px;
margin-left: 10px;
width: 70px;
cursor: pointer;
}
.wrapper .total {
margin-right: 80px;
color: #999;
margin-top: 5px;
opacity: 0;
transition: all 0.5s;
}
.list {
min-width: 400px;
max-width: 800px;
display: flex;
}
.list .item {
width: 100%;
display: flex;
}
.list .item .info {
flex: 1;
border-bottom: 1px dashed #e4e4e4;
padding-bottom: 10px;
}
.list .item p {
margin: 0;
}
.list .item .name {
color: #FB7299;
font-size: 14px;
font-weight: bold;
}
.list .item .text {
color: #333;
padding: 10px 0;
}
.list .item .time {
color: #999;
font-size: 12px;
}
</style>
</head>
<body>
<div class="wrapper">
<i class="avatar"></i>
<textarea id="tx" placeholder="发一条友善的评论" rows="2" maxlength="200"></textarea>
<button>发布</button>
</div>
<div class="wrapper">
<span class="total">0/200字</span>
</div>
<div class="list">
<div class="item" style="display: none;">
<i class="avatar"></i>
<div class="info">
<p class="name">清风徐来</p>
<p class="text">大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]</p>
<p class="time">2022-10-10 20:29:21</p>
</div>
</div>
</div>
<script>
const tx = document.querySelector('#tx')
const total = document.querySelector('.total')
tx.addEventListener('focus', function () {
total.style.opacity = 1
})
tx.addEventListener('blur', function () {
total.style.opacity = 0
})
tx.addEventListener('input', function () {
const length = tx.value.length
total.innerHTML = `${length}/200字`
})
//获取button元素,以及item元素text元素
const button = document.querySelector('button')
const item = document.querySelector('.item')
const text = document.querySelector('.text')
//给按钮注册点击事件
button.addEventListener('click', function () {
//获得文本框的内容
const val = tx.value.trim()
if (val.length === 0) {
alert('没有输入内容')
} else {
//让item盒子显示出来
item.style.display = 'block'
//把输入的内容写到text盒子里面
text.innerHTML = tx.value
tx.value = ''
}
})
tx.addEventListener('keydown', function (e) {
if (e.key === 'Enter') {
button.click()
}
})
</script>
17.点击关闭广告
<style>
.box {
position: relative;
width: 1000px;
height: 200px;
background-color: pink;
margin: 100px auto;
text-align: center;
font-size: 50px;
line-height: 200px;
font-weight: 700;
}
.close {
position: absolute;
right: 20px;
top: 10px;
width: 20px;
height: 20px;
background-color: skyblue;
text-align: center;
line-height: 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box">
我是广告
<div class="close">X</div>
</div>
<script>
const close1 = document.querySelector('.close')
const box = document.querySelector('.box')
close1.addEventListener('click', function () {
box.style.display = 'none'
})
</script>
18.tab栏切换----循环排他(万能的)
<style>
.Box {
width: 240px;
border: 1px solid #000;
margin: 100px auto;
padding: 20px;
}
.con {
width: 100%;
height: 200px;
background-color: #cccccc;
border: 1px solid #000;
margin-top: 10px;
display: none;
}
.current {
background-color: pink;
border: 2px black solid;
}
</style>
</head>
<body>
<div class="Box" id="box">
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<div class="con" style="display:block">内容1</div>
<div class="con">内容2</div>
<div class="con">内容3</div>
<div class="con">内容4</div>
</div>
<script>
1.排他思想应用场景 : 多个元素只能选中一个元素的场景
2.排他思想实现思路:两种思路
循环排他(万能的) : (1)循环干掉所有兄弟 (2)复活自己
类名排他(一定要有类名) : (1)使用类选择器干掉选中的兄弟 (2)复活自己
总结: 元素有类名就用类名排他, 没有类名就用 循环排他。 切记两者不可混用
类名排他: 通过classList类名修改样式
循环排他: 通过style修改样式
3.tab栏切换(选项卡) = 两个排他
//1.获取元素
let buttonList = document.querySelectorAll('button')
let conList = document.querySelectorAll('.con')
//2.注册事件
for (let i = 0; i < buttonList.length; i++) {
buttonList[i].addEventListener('click', function () {
//3.事件处理 : 循环排他
console.log(i, this) //自己的下标,自己
//(1)循环干掉所有兄弟
for (let j = 0; j < buttonList.length; j++) {
buttonList[j].style.backgroundColor = ''
conList[j].style.display = 'none'
}
//(2)复活自己
buttonList[i].style.backgroundColor = 'pink'
conList[i].style.display = 'block'
})
}
</script>
19.隔行变色高级版---鼠标经过时会变成红色
<body>
<ul>
<li>我是班长1</li>
<li>我是班长2</li>
<li>我是班长3</li>
<li>我是班长4</li>
<li>我是班长5</li>
<li>我是班长6</li>
<li>我是班长7</li>
<li>我是班长8</li>
<li>我是班长9</li>
<li>我是班长10</li>
</ul>
<script>
/* 1.设置每一个li元素颜色: 单绿 双黄
2.鼠标移入li元素: 颜色变红
3.鼠标移出li元素: 颜色恢复原先的颜色
*/
let liList = document.querySelectorAll('li')
for (let i = 0; i < liList.length; i++) {
//1.设置颜色
liList[i].style.backgroundColor = i % 2 == 0 ? 'green' : 'yellow'
//2.鼠标移入
liList[i].addEventListener('mouseenter', function () {
//先存储当前颜色
this.setAttribute('bgc', this.style.backgroundColor)
//后修改红色
this.style.backgroundColor = 'red'
})
//3.鼠标移出
liList[i].addEventListener('mouseleave', function () {
//取出自定义属性的值 赋值给 背景颜色
this.style.backgroundColor = this.getAttribute('bgc')
})
}
</script>
20.案例:图片切换
<style>
.title {
background-color: skyblue;
color: white;
}
img {
width: 200px;
height: 200px;
box-shadow: 0 0 20px hotpink;
}
</style>
</head>
<body>
<h2 class="title">图片切换</h2>
<img alt="" src="./images/01.jpg" />
<br />
<input id="prev" type="button" value="上一张" />
<input id="next" type="button" value="下一张" />
<script>
/*思路分析
0. 图片切换类功能一定要声明 全局变量index 存储下标
(1)为什么要声明变量: 因为下一页需要让下标自增, 而字面量0是无法自增 0++(程序报错),
=左边只能是变量
(2)为什么要是全局变量:因为下一页 和 上一页 事件处理函数 是两个不同的局部作用域。
要想变量在任何地方都能使用, 就必须要是全局变量
1.点击下一张 :
2.点击上一张 :
//多个数据 使用数组存储
let imgArr = [
"./images/01.jpg",
"./images/02.jpg",
"./images/03.jpg",
"./images/04.jpg",
"./images/05.jpg",
]
//1.声明'全局变量'记录下标
let index = 0
//获取元素
let img = document.querySelector("img")
let prev = document.querySelector("#prev")
let next = document.querySelector("#next")
//2.1 下一页
next.onclick = function () {
//3.1 无限切换思路
//(1)如果index是最后一张下标 == 数组长度-1 ,则 index = 0 (2)否则index++
// if( index == imgArr.length-1 ){
// index = 0
// }else{
// index++
// }
//三元表达式 表达式?代码1:代码2
index == imgArr.length-1 ? index = 0 : index++
//3.2 修改img标签的src
img.src = imgArr[index]
}
//2.2 上一页
prev.onclick = function () {
//3.1 下标自减 (1)如果index是第一张 == 0,则index=数组长度-1 (2)否则index--
index == 0 ? index = imgArr.length-1 : index--
//3.2 修改img标签的src
img.src = imgArr[index]
}
</script>
</body>
21.突出展示
<style type="text/css">
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
body {
background: #000;
}
.wrap {
margin: 100px auto 0;
width: 630px;
height: 394px;
padding: 5px;
background: #000;
overflow: hidden;
border: 1px solid #fff;
}
.wrap li {
float: left;
padding: 5px;
}
.wrap img {
display: block;
border: 0;
}
</style>
</head>
<body>
<div class="wrap">
<ul>
<li>
<a href="#"><img src="images/01.jpg" alt=""/></a>
</li>
<li>
<a href="#"><img src="images/02.jpg" alt=""/></a>
</li>
<li>
<a href="#"><img src="images/03.jpg" alt=""/></a>
</li>
<li>
<a href="#"><img src="images/04.jpg" alt=""/></a>
</li>
<li>
<a href="#"><img src="images/05.jpg" alt=""/></a>
</li>
<li>
<a href="#"><img src="images/06.jpg" alt=""/></a>
</li>
</ul>
</div>
<script>
/* 鼠标移入每一个li元素 : 排他思想
(1)干掉兄弟: opacity:0.5 (2)复活自己: opacity:1
*/
//1.获取
let liList = document.querySelectorAll('li')
//2.给每一个li元素注册鼠标移入事件
for(let i = 0;i<liList.length;i++){
liList[i].onmouseenter = function(){
//3.排他
//(1)干掉兄弟
for(let j = 0;j<liList.length;j++){
liList[j].style.opacity = 0.5
}
//(2)复活自己 this
this.style.opacity = 1
}
}
</script>
</body>
22.排他思想升级---类名排他(一定要有类名)
<style>
.pink {
background-color: pink;
}
</style>
</head>
<body>
<button class="pink">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
/*
1.排他思想应用场景 : 多个元素只能选中一个元素的场景
2.排他思想实现思路:两种思路
循环排他(万能的) : (1)循环干掉所有兄弟 (2)复活自己
类名排他(一定要有类名) : (1)使用类选择器干掉选中的兄弟 (2)复活自己
总结: 元素有类名就用类名排他, 没有类名就用 循环排他。 切记两者不可混用
类名排他: 通过classList类名修改样式
循环排他: 通过style修改样式
*/
//1.获取元素
let buttonList = document.querySelectorAll('button')
//2.给每一个按钮注册点击事件
for(let i = 0;i<buttonList.length;i++){
buttonList[i].onclick = function(){
//3.事件处理:排他
//(1)使用类选择器干掉选中的兄弟
document.querySelector('.pink').classList.remove('pink')
//(2)复活自己
this.classList.add('pink')
}
}
</script>
</body>
23.tab栏切换---类名排他(一定要有类名)
<style type="text/css">
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.wrapper {
width: 1000px;
height: 475px;
margin: 0 auto;
margin-top: 100px;
}
.tab {
border: 1px solid #ddd;
border-bottom: 0;
height: 36px;
width: 320px;
}
.tab li {
position: relative;
float: left;
width: 80px;
height: 34px;
line-height: 34px;
text-align: center;
cursor: pointer;
border-top: 4px solid #fff;
}
.tab span {
position: absolute;
right: 0;
top: 10px;
background: #ddd;
width: 1px;
height: 14px;
overflow: hidden;
}
.products {
width: 1002px;
border: 1px solid #ddd;
height: 476px;
}
.products .main {
float: left;
display: none;
}
.products .main.selected {
display: block;
}
.tab li.active {
border-color: red;
border-bottom: 0;
}
</style>
</head>
<body>
<div class="wrapper">
<ul class="tab">
<li class="tab-item active">国际大牌<span>◆</span></li>
<li class="tab-item">国妆名牌<span>◆</span></li>
<li class="tab-item">清洁用品<span>◆</span></li>
<li class="tab-item">男士精品</li>
</ul>
<div class="products">
<div class="main selected">
<a href="###"><img src="images/guojidapai.jpg" alt=""/></a>
</div>
<div class="main">
<a href="###"><img src="images/guozhuangmingpin.jpg" alt=""/></a>
</div>
<div class="main">
<a href="###"><img src="images/qingjieyongpin.jpg" alt=""/></a>
</div>
<div class="main">
<a href="###"><img src="images/nanshijingpin.jpg" alt=""/></a>
</div>
</div>
</div>
<script>
/* 点击上方li元素
1.tab栏 = 两个排他
上面类名排他 : active
下面类名排他 : selected
*/
//1.获取元素
let liList = document.querySelectorAll('.tab-item')
let mainList = document.querySelectorAll('.main')
//2.点击每一个li元素
for(let i = 0;i<liList.length;i++){
liList[i].onclick = function(){
//3. 类名排他
//3.1 上面排他
document.querySelector('.active').classList.remove('active')
liList[i].classList.add('active')
//3.2 下面排他
document.querySelector('.selected').classList.remove('selected')
mainList[i].classList.add('selected')
}
}
</script>
</body>
24.开关思想
<body>
<script>
/*
1.排他思想 : 多个元素,只能选中一个(多选一)
循环排他 : (1)循环干掉所有兄弟 (2)复活自己
语法: 元素.style.样式名 = 样式值
类名排他: (1)类选择器干掉上一次选中兄弟 (2)复活自己
语法: 元素.classList.add(类名)
2.开关思想 : 判断数组中 是否所有元素都满足条件
(1)声明布尔类型开关变量 let bol = true
(2)遍历数组,检测开关变量是否成立 : 找false
(3)获取开关变量的值
*/
//需求:判断数组中元素 是不是都大于10
let arr = [20,50,80,90,55]
//(1) 声明布尔类型开关变量 let bol = true
let bol = true
//(2) 遍历数组,检测开关变量是否成立 : 找false
for(let i = 0;i<arr.length;i++){
// 检测开关变量是否成立 : 找false
if( arr[i] < 10 ){
bol = false
break
}
}
//(3) 获取开关变量的值
console.log(bol)//true
</script>
</body>
25.案例:全选与反选
<style>
* {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
border: 1px solid #c0c0c0;
width: 500px;
margin: 100px auto;
text-align: center;
}
th {
background-color: #09c;
font: bold 16px '微软雅黑';
color: #fff;
height: 24px;
}
td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
</style>
</head>
<body>
<table>
<tr>
<th><input type="checkbox" id="checkAll" />全选/全不选</th>
<th>菜名</th>
<th>商家</th>
<th>价格</th>
</tr>
<tr>
<td>
<input type="checkbox" class="check" />
</td>
<td>红烧肉</td>
<td>隆江猪脚饭</td>
<td>¥200</td>
</tr>
<tr>
<td>
<input type="checkbox" class="check" />
</td>
<td>香酥排骨</td>
<td>隆江猪脚饭</td>
<td>¥998</td>
</tr>
<tr>
<td>
<input type="checkbox" class="check" />
</td>
<td>北京烤鸭</td>
<td>隆江猪脚饭</td>
<td>¥88</td>
</tr>
</table>
<script>
/* 思路分析
1.点击每一个单选框: 开关思想 判断数组每一个元素是否选中 ( checked值为true )
2.点击全选框 : 设置每一个单选框的checked值与 全选框 一致
一致: 全选为true,单选框也要为true. 全选为false,单选框为false
*/
//1.获取元素
let checkList = document.querySelectorAll('.check')//单选框数组
let checkAll = document.querySelector('#checkAll')//全选框
//2.点击每一个单选框
for (let i = 0; i < checkList.length; i++) {
checkList[i].onclick = function () {
//3.开关思想 判断数组每一个元素是否选中 ( checked值为true )
//(1)声明开关变量,默认值为true
let bol = true
//(2)遍历数组检测开关变量:找false
for (let j = 0; j < checkList.length; j++) {
if ( !checkList[j].checked ) {
bol = false
break
}
}
//(3)获取开关变量结果
// console.log(bol)
checkAll.checked = bol
// if( bol ){
// checkAll.checked = true
// }else{
// checkAll.checked = false
// }
}
}
//2.2 点击全选框
checkAll.onclick = function(){
//this : 全选框checkAll
console.log( this.checked )
//3. 设置每一个单选框的checked值与 全选框一致
for(let i = 0;i<checkList.length;i++){
checkList[i].checked = this.checked
}
}
</script>
</body>
案例第二种方法:
案例介绍
26.attribute语法及属性
27.隔行变色高级版
<body>
<ul>
<li>我是班长1</li>
<li>我是班长2</li>
<li>我是班长3</li>
<li>我是班长4</li>
<li>我是班长5</li>
<li>我是班长6</li>
<li>我是班长7</li>
<li>我是班长8</li>
<li>我是班长9</li>
<li>我是班长10</li>
</ul>
<script>
/* 1.设置每一个li元素颜色: 单绿 双黄
2.鼠标移入li元素: 颜色变红
3.鼠标移出li元素: 颜色恢复原先的颜色
*/
//1.获取所有li元素
let liList = document.querySelectorAll('li')
//2.遍历数组
for(let i = 0;i<liList.length;i++){
//2.1 设置颜色
liList[i].style.backgroundColor = (i % 2 == 0 ? 'green' : 'yellow')
//2.2 鼠标移入
liList[i].onmouseenter = function(){
//3.1 先存储当前的颜色
this.setAttribute('aaa', this.style.backgroundColor )
//3.2 修改颜色
this.style.backgroundColor = 'red'
}
//2.3 鼠标移出
liList[i].onmouseleave = function(){
//3.恢复原来的颜色
this.style.backgroundColor = this.getAttribute('aaa')
}
}
</script>
</body>
28.案例
<style>
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
color: #721c24;
}
h1 {
text-align: center;
color: #333;
margin: 20px 0;
}
table {
margin: 0 auto;
width: 800px;
border-collapse: collapse;
color: #004085;
}
th {
padding: 10px;
background: #cfe5ff;
font-size: 20px;
font-weight: 400;
}
td,
th {
border: 1px solid #b8daff;
}
td {
padding: 10px;
color: #666;
text-align: center;
font-size: 16px;
}
tbody tr {
background: #fff;
}
tbody tr:hover {
background: #e1ecf8;
}
.info {
width: 900px;
margin: 50px auto;
text-align: center;
}
.info input {
width: 80px;
height: 25px;
outline: none;
border-radius: 5px;
border: 1px solid #b8daff;
padding-left: 5px;
}
.info button {
width: 60px;
height: 25px;
background-color: #004085;
outline: none;
border: 0;
color: #fff;
cursor: pointer;
border-radius: 5px;
}
.info .age {
width: 50px;
}
</style>
</head>
<body>
<h1>新增学员</h1>
<form action="">
<div class="info">
姓名:<input type="text" class="uname" /> 年龄:<input type="text"
class="age" />
性别:
<select name="gender" id="" class="gender">
<option value="男">男</option>
<option value="女">女</option>
</select>
薪资:<input type="text" class="salary" /> 就业城市:<select name="city"
id="" class="city">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
<option value="曹县">曹县</option>
</select>
<button class="add">录入</button>
</div>
</form>
<h1>就业榜</h1>
<table>
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>薪资</th>
<th>就业城市</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- <tr>
<td>1001</td>
<td>欧阳霸天</td>
<td>19</td>
<td>男</td>
<td>15000</td>
<td>上海</td>
<td>
<a href="javascript:" class="delete">删除</a>
</td>
</tr> -->
</tbody>
</table>
<script>
//准备好数据后端的数据
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: '北京'
}
]
//1.把数组中的元素 显示到页面
for (let i = 0; i < arr.length; i++) {
//(1)创建空标签
let tr = document.createElement('tr')
//(2)设置内容
tr.innerHTML = `<td>1001</td>
<td>${arr[i].uname}</td>
<td>${arr[i].age}</td>
<td>${arr[i].gender}</td>
<td>${arr[i].salary}</td>
<td>${arr[i].city}</td>
<td>
<a href="javascript:" class="delete">删除</a>
</td>`
//(3)添加到tbody
document.querySelector('tbody').appendChild(tr)
}
/* 2.点击录入 : 表单中的按钮需要阻止默认跳转
2.1 非空判断 : 输入框文本不能为空
2.2 新增元素
(1)创建空标签
(2)设置内容
(3)添加到tbody
2.3 清空表单
*/
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')
document.querySelector('.add').onclick = function(e){
//(0)阻止表单默认跳转
e.preventDefault()
//(1)非空判断 : 如果有空,不能添加
if( uname.value == '' || age.value == '' || salary.value == '' ){
alert('输入框不能为空')
return
}
//(2)创建tr
//创建空标签
let tr = document.createElement('tr')
//设置内容
tr.innerHTML = `<td>1001</td>
<td>${uname.value}</td>
<td>${age.value}</td>
<td>${gender.value}</td>
<td>${salary.value}</td>
<td>${city.value}</td>
<td>
<a href="javascript:" class="delete">删除</a>
</td>`
//添加到tbody
document.querySelector('tbody').appendChild(tr)
//(3)清空表单
/* 如果是单个input : input.value = ''
如果是form表单 : form.reset()
*/
document.querySelector('form').reset()
}
/* 3.点击删除 : 删除是动态新增元素,需要注册委托事件
(1)事件委托 : 给父元素注册, 委托子元素处理
* 父元素也不能是新增的,如果分不清楚,可以直接给body注册
(2)事件委托注意点:
不能用this : 指向事件源(父元素)
用e.target : 指向事件目标 (触发本次冒泡的子元素)
*/
//事件: 给父元素注册
document.body.onclick = function(e){
console.log(e.target)
//委托: 找到委托的子元素: 判断到底是不是删除按钮
if( e.target.classList.contains('delete') ){
/*
e.target : 删除按钮
e.target.parentNode : td
e.target.parentNode.parentNode : tr
*/
document.querySelector('tbody').removeChild( e.target.parentNode.parentNode )
}
}