Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:
<button onclick="console.log(this.innerHTML)">button</button>
<button>button2</button>
<script>
const btn2=document.querySelector("body button:nth-of-type(2)");
// 1.2.1添加事件
btn2.onclick=function(){
console.log(this.innerHTML);
}
// 又一次添加事件后,上一个添加的事件将会失效,因为onclick不能重复定义同一个事件
btn2.onclick=function(){
this.style.color="red";
}
// 1.2.2移出事件
btn2.onclick=null;
</script>
<!-- // addEventListener(事件类型,事件回调方法,触发阶段) -->
<button>button3</button>
<script>
const btn3=document.querySelector("body button:nth-of-type(3)");
btn3.addEventListener("click",function(){
console.log(this.innerHTML,"第一次");
})
// 1.3.1事件移出,通过回调函数添加的事件是无法移除的,可以通过声明一个事件函数,添加和移出事件都操作这个事件函数
// 1.3.1.1 声明事件方法函数
const handle=()=>console.log(btn3.innerHTML,"第二次");
// 1.3.1.2 添加事件
btn3.addEventListener("click",handle);
// 1.3.1.3移出事件
btn3.removeEventListener("click",handle);
</script>
<button>点击广告</button>
<script>
// 自定义事件
const btn4=document.querySelector("body button:nth-of-type(4)");
const ev=new Event("click");
btn4.addEventListener("click",function(){
console.log("点击了广告");
})
btn4.dispatchEvent(ev);//将会自动点击"点击广告"事件
// 通过间歇式自动点击器来自动点击广告
setInterval("btn4.dispatchEvent(ev)",1000);
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
// 事件传递: 1.捕获:从最外层元素逐级向内直到事件的绑定者; 2.目标:到达事件目标; 3.冒泡:从目标再由内逐级向上直到最外层属性
const lis=document.querySelectorAll("li");
lis.forEach(
li=>(li.onclick=ev=>{
// 事件对象:保存着当前对象的所有信息
console.log(ev);
// 事件类型
console.log(ev.type);
// 事件绑定者
console.log(ev.currentTarget);
// 事件触发者
console.log(ev.target);
// 事件传递的路径
console.log(ev.path);
// 阻止事件冒泡
ev.stopPropagation();
})
)
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
// 事件代理也叫事件委托
const lis=document.querySelectorAll("li");
//遍历每一个li,并逐个为它添加点击事件
lis.forEach(li=>(li.onclick=ev=>console.log(ev.currentTarget)));
//也可以将点击事件添加到其父元素上,通过事件触发者来获取元素
document.querySelector("ul").addEventListener("click",ev=>{
//获取事件绑定者
console.log(ev.currentTarget);
// 获取事件触发者,通常是“事件绑定者”的子元素
console.log(ev.target);
})
#login{
width: 20em;
border: 1px solid #888;
padding: 1em 2em 1em;
margin: 2em auto;
box-sizing: border-box;
background-color: lightcyan;
display: grid;
grid-template-columns: 3em 1fr;
gap: 1em 0;
}
#login .title{
grid-area: auto / span 2;
place-self: center;
}
#login button{
grid-area: auto / 2 / auto;
}
<form action="" method="POST" id="login">
<label class="title">用户登录</label>
<label for="username">账号:</label>
<input type="text" name="username">
<label for="password">密码:</label>
<input type="password" name="password">
<button type="submit" name="submit">登录</button>
</form>
// 获取表单
const login=document.forms["login"];
// 其他方法
// const login=document.forms[0];
// const login=document.forms["login"];
// const login=document.forms.item(0);
// const login=document.forms.item("login");
// const login=document.forms.namedItem("login");
// const login=document.querySelector("#login");
// submit()提交
// login.onsubmit=()=>alert("success");
// 如果是自定义表单的提交行为,应该禁用掉默认的提交
// login.onsubmit=ev=>ev.preventDefault();
login.submit.onclick=ev=>{
ev.preventDefault();//禁止默认的提交
ev.stopPropagation()//阻止事件冒泡,不然会触发父级或祖先级的事件
console.log(ev.currentTarget.form);
// 表单中每一个元素都有一个form属性,并指向它所属的表单
isEmpty(ev.currentTarget.form);
}
// 非空验证
function isEmpty(form){
if(form.username.value.length===0){
alert("请输入帐号!");
form.username.focus();
return false;
}else if(form.password.value.length===0){
alert("请输入密码!");
form.password.focus();
return false;
}else{
alert("验证通过!");
}
}
1.focus:获取焦点事件
2.blur:失去焦点事件
3.input:只要值发生变化时连续触发,不等到失去焦点
4.change:值发生了变化且失去了焦点时触发,适用于<input><select><textarea>
5.select:选中值时触发,适用于<input><textarea>
6.reset:将表单值全部重置到默认值
7.submit:提交表单时触发,注意触发对象是<form>,提交的是表单不是按钮
8.keydown:按下键盘时
9.keyup:松开键盘时
10.keypress:按住了键盘(除了Ctrl、alt、shift、meta等之外有值的键)时,会先触发keydown,然后再keypress,一直重复这两个,直到触发keyup松开键盘时才结束
11.load
12.error
13.invalid:提交时表单元素值不满足验证条件时触发
<!-- 留言输入框 -->
<input type="text" name="msg">
<!-- 历史留言列表 -->
<ol id="list"></ol>
// 获取元素
const msg=document.querySelector("input");
const list=document.querySelector("#list");
msg.onkeydown=ev=>{
// 键盘事件中,key表示按下的键名
// console.log(ev.key);
if(ev.key==="Enter"){
if(ev.currentTarget.value.length===0){
alert("留言不能为空!");
}else{
// 不为空则将留言添加到列表中
// 创建留言
let str=`<li>${ev.currentTarget.value}</li>`;
// 最新留言应放置首位
list.insertAdjacentHTML("afterBegin",str);
// 留言添加后将留言框清空
ev.target.value=null;
}
}
}
const strs="a1b2c3d4e5f6g7h8i9j";
// 1.concat(); 拼装
let str="html".concat(" css"," js"," php"," !");//html css js php !
// 2.slice(start,end); 取子串,start表示开始截取的位置,end表示截取结束的位置;正数从0开始数,负数从-1开始数;正数负数可以同时用,但是不能出现start的位置在end位置后面。
str=strs.slice(2,5); //b2c
str=strs.slice(-7,-5); //g7
// 3.substr(start,length); 取子串; start表示开始的位置,length表示截取多少位;支持正负数。
str=strs.substr(2,5);//b2c3d
// 4.trim() 删除两端空格
let psd=" password ";//length=12
psd=psd.trim();//length=8
// 5.split() 将字符串通过指定字符转换为数组
str=strs.split("");//(19) ["a", "1", "b", "2", "c", "3", "d", "4", "e", "5", "f", "6", "g", "7", "h", "8", "i", "9", "j"]
str="Jy@php.cn".split("@");//(2) ["Jy", "php.cn"]
栈方法;栈:先进后出;对:先进先出;对和栈是仅允许在一端进行增删
let arr=[];
arr.push(1,2,3);//[ 1, 2, 3 ]
arr.pop();//[ 1, 2 ]
5.2 unshift() shift() 在数组的头部进行增删
arr.unshift(4,5,6);//[ 4, 5, 6, 1, 2 ]
arr.shift();//[ 5, 6, 1, 2 ]
push()+shift() 模拟队列,尾部进入,头部出去 ; pop()+unshift() 模拟队列:头部进入,尾部出去
5.3 join() 将数组转为字符串,与split()功能相反
arr=['a','b','c'];
let res=arr.join('---');//a---b---c 分隔符默认为“,”
5.4 concat() 数组合并
[1,2,3].concat(4,[5,6]);//[ 1, 2, 3, 4, 5, 6 ]
5.5 slice() 返回数组部分成员 支持负数
arr=[1,2,3,4,5,6];
res=arr.slice(0,2);//[ 1, 2 ] 从第一位数开始返回两个成员
5.6 splice(开始索引,删除的数量,插入的数据) 数组的增删改;它的本质工作是删除元素
5.6.1 删除
arr.splice(2);//[ 1, 2 ] 从第三个成员开始,后面全部删除
arr=[1,2,3,4,5,6];
arr.splice(3,2);//[ 1, 2, 3, 6 ] 从第四个成员开始,删除两个成员
5.6.2 更新
arr=[1,2,3,4,5,6];
arr.splice(1,2,8,9);//[ 1, 8, 9, 4, 5, 6 ] 从第二个成员开始删除两个,并从第一个位置之后插入成员
// arr.splice(1,2,...[8,9]);//上面的可以修改为这种
5.6.3 新增,方法的第二个参数写为0就可以了
arr=[1,2,3,4,5,6];
arr.splice(2,0,...[11,22,33]);//[ 1, 2, 11, 22, 33, 3, 4, 5, 6 ] 从第二个成员之后添加新成员,
5.7 sort() 数组排序 按照字母表顺序
arr=['p','t','c'];
arr.sort();//[ "c", "p", "t" ]
arr=[10,5,6,77,23];//[ 10, 23, 5, 6, 77 ]
arr.sort();
// 上面排序非正确排序,因为把数字当成字符串来进行比较了,可以用下面的方法
arr.sort((a,b)=>a-b);//[ 5, 6, 10, 23, 77 ]
// 倒序
arr.sort((a,b)=>b-a);//[ 77, 23, 10, 6, 5 ]
5.8 遍历
arr=[1,2,3,4,5,6];
res=arr.forEach(item=>item);//undefined 没有返回值,只要在方法内返回元素才有值,那也是方法的值
// map() 对数组每个成员都调用回调进行处理并返回这个数组
res=arr.map(item=>item);//[ 1, 2, 3, 4, 5, 6 ]
5.9 filter() 过滤
arr=[1,2,3,4,5,6];
res=arr.filter(item=>item%2);//[ 1, 3, 5 ] 取奇数
arr=[1,2,3,4,5,6];
res=arr.filter(item=>!(item%2));//[ 2, 4, 6 ] 取偶数
5.10 reduce(callback(prev,curr)) 归内 第二个参数是累加的初始值,不设置默认为0
arr=[1,2,3,4,5,6];
res=arr.reduce((prev,curr)=>{
// console.log(prev,curr);//可以看出来归内的过程
return prev+curr;
},1000)
// 简写为:
// res=arr.reduce((prev,curr)=>prev+curr,1000);