初识JavaScript (十五)事件
1 表单事件-focus-blur
重点:
表单事件:
onfocus:表单元素获得焦点事件。
当表单元素获得焦点的时候被触发。
onblur:表单元素失去焦点事件。
当表单元素失去焦点的时候被触发。
注意:当当前的焦点从一个元素移动到另外一个元素,那么上一个获得焦点的元素会先触发失去焦点事件,然后下一个元素才触发获得焦点事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
用户名:<input type="text" id="ipt1"><span></span>
<br>
<input type="button" id="btn" value="点我">
<script>
var ipt1 = document.getElementById("ipt1");
//获得焦点,输出输入框中的内容
ipt1.onfocus = function () {
console.log ("input 获得焦点了")
}
ipt1.onblur = function () {
console.log ("input 失去焦点了")
}
var btn = document.getElementById("btn");
btn.onfocus = function () {
console.log ("btn 获得焦点了");
}
btn.onblur = function () {
console.log ("btn 失去焦点了");
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
用户名:<input type="text"><span></span>
<!--
输入用户名,在input获得焦点的时候,提示用户名的长度[8-12].
输入完毕,失去焦点的时候,判断是否合法。如果合法,显式绿色√
不合法:显式红色的×
-->
<script>
(function () {
//获得元素
var uname = document.querySelector ("input");
var notice = document.querySelector("span");
uname.onfocus = function () {
//显示用户名的提示信息
notice.innerHTML = "用户名的长度[8-12]";
notice.style.color = "black";
};
uname.onblur = function () {
//测试用户名是否合法
var length = uname.value.length;
if(length < 8 || length > 12){//不合法
notice.innerHTML = "×";
notice.style.color = "red";
}else{
notice.innerHTML = "√";
notice.style.color = "green";
}
}
}) ();
</script>
</body>
</html>
2 表单事件-input-change
重点:
input:表单元素输入框的输入内容改变事件。
在输入的过程中,一旦内容发生了增加或者减少,都会触发该事件。
change: 是当表单元素的内容确定发生改变了。触发change事件。
对于输入框来说,确定输入结束,那么触发该事件。
注意:先触发change事件,然后再出发失去焦点事件。
对于输入框来说,输入的过程中,回车键,那么会触发change事件。并且不触发失去焦点事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
用户名:<input type="text"><span></span>
<script>
(function () {
//获得元素
var uname = document.querySelector ("input");
var notice = document.querySelector ("span");
uname.onfocus = function () {
//显示用户名的提示信息
notice.innerHTML = "用户名的长度[8-12]";
notice.style.color = "black";
};
//输入的过程中,动态的判断输入的内容是否合法
uname.oninput = function () {
//测试用户名是否合法
var length = uname.value.length;
if (length < 8 || length > 12) {//不合法
notice.innerHTML = "×";
notice.style.color = "red";
} else {
notice.innerHTML = "√";
notice.style.color = "green";
}
};
uname.onblur = function(){
console.log ("失去焦点了");
}
uname.onchange = function () {
console.log ("change事件触发了");
}
}) ();
</script>
</body>
</html>
3 单选-复选-下拉列表的change事件
单选按钮:鼠标点击:先触发focus事件,然后触发change事件。不需要再失去焦点。
复选按钮:鼠标点击:先触发focus事件,然后触发change事件,如果不停的多次点击。后面只触发
change事件。
下拉列表:当鼠标点击的时候,触发focus事件。然后选择其他的下拉项,触发change事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
性别
<input type="radio" name="gender">男
<input type="radio" name="gender">女
<br>
<input type="checkbox" name="hobby">跑步<br>
<input type="checkbox" name="hobby">单杠<br>
<input type="checkbox" name="hobby">哑铃<br>
<select id="cities">
<option value="">北京</option>
<option value="">上海</option>
<option value="">天津</option>
<option value="">重庆</option>
</select>
<script>
/*var genders = document.getElementsByName("gender");
genders[0].onfocus = function (e) {
e = e || window.event;
console.log (e.type);
console.log ("男获得焦点");
console.log (this);
}
genders[0].onchange = function (e) {
e = e || window.event;
console.log (e.type);
console.log (this);
}
genders[0].onblur = function (e) {
e = e || window.event;
console.log (e.type);
console.log ("男失去焦点");
console.log (this);
}*/
/*var hobbies = document.getElementsByName("hobby");
hobbies[0].onfocus = function (e) {
e = e || window.event;
console.log (e.type);
console.log (this);
}
hobbies[0].onchange = function (e) {
e = e || window.event;
console.log (e.type);
console.log (this);
}*/
var sel = document.querySelector("select");
sel.onfocus = function () {
console.log ("sel 获得焦点");
}
sel.onchange = function () {
console.log ("sel change");
}
</script>
</body>
</html>
4 表单事件-submit-reset
重点:
表单事件:
submit:提交表单事件。
1:该事件需要给form元素添加。
2:当点击提交按钮的时候触发该事件。
3:如果不希望表单提交,可以在事件处理函数中,通过return false。来阻断提交。
可以通过return ture,或者什么都不返回,来实现提交表单。
reset:重置表单事件 不建议使用reset
给form添加
点击重置按钮触发
通过return false 阻断重置。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="ok.html">
用户名:<input type="text" name="uname">
<br>
密码:<input type="password" name="pwd">
<br>
<button type="submit">提交</button>
<br>
<button type="reset">重置</button>
</form
<script>
var form = document.querySelector("form");
inps = document.querySelectorAll("input");
form.onsubmit = function () {
//如果用户名密码有空的就阻断提交
if(inps[0].value.length === 0 || inps[1].value.length === 0){
alert("户名密码有空的");
return false;
}
return true;
}
form.onreset = function () {
console.log ("重置了");
return false;
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
span{
color: red;
font-size: 10px;
font-style: italic;
}
</style>
</head>
<body>
<h2>表单校验</h2>
<form action="ok.html">
用户名:<input type="text" name="uname"><span></span>
<br>
密码:<input type="password" name="pwd"><span></span>
<br>
<button type="submit">提交</button>
</form>
<script>
var form = document.querySelector("form");
form.onsubmit = function () {
if(inputs[0].value != "amdin")
return false;
if(inputs[1].value != "123456")
return false;
return true;
}
var inputs = document.querySelectorAll("input");
var spans = document.querySelectorAll("span");
inputs[0].onfocus = function () {
this.value = "";
spans[0].innerHTML = "用户名必须是admin";
};
inputs[0].onblur = function () {
if(this.value == ""){
spans[0].innerHTML = "用户名不能为空";
return;
}
if(this.value == "admin"){
spans[0].innerHTML = "√";
}else{
spans[0].innerHTML = "×";
}
};
inputs[1].onfocus = function () {
this.value = "";
spans[1].innerHTML = "密码必须是123456";
};
inputs[1].onblur = function () {
if(this.value == ""){
spans[1].innerHTML = "密码不能为空";
return;
}
if(this.value == "123456"){
spans[1].innerHTML = "√";
}else{
spans[1].innerHTML = "×";
}
};
</script>
</body>
</html>
5 键盘事件总结
键盘的按键事件
1:三个事件都支持冒泡特性。
2:keydown:所有的键盘的按键按下的时候都会触发该事件。如果按住按键,该事件会持续触发。字符键的键码值从65开始。
3: keypress: 功能键不响应,一般用它来响应字符键+数字键。如果按住按键,该事件会持续触发。字符键的键码值从97开始。
4: keyup: 任意键松开释放,都会触发该事件。松开一次。只能触发一次。
补充:对于按键事件一般是给document对象或者是body添加。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
document.onkeydown = function (e) {
e = e || window.event;
console.log (e.type);
console.log (e.keyCode);
}
document.onkeypress = function (e) {
e = e || window.event;
console.log (e.type);
console.log (e.keyCode);
}
document.onkeyup = function (e) {
e = e || window.event;
console.log (e.type);
console.log (e.keyCode);
}
</script>
</body>
</html>
6 滚动事件
滚动事件:scroll
1:该事件可以发生在具有滚动条的页面元素中,或者是整个浏览器窗口中。在滚动的过程中会持续触发。
2: 针对滚动事件,带有滚动条的元素有两个针对滚动的属性:
scrollLeft:卷入元素左侧不可见区域的宽度。
scrollTop:卷入元素上面不可见区域的高度。
可以通过设置元素的这两个属性实现对滚动条滚动的控制。
3: 对于整个浏览器窗口的滚动的事件,一般给window对象添加。
但是window对象没有scrollLeft 和 scrollTop属性。
一般使用 body对象或者是documentElement 对象的scrollLeft 和 scrollTop属性
使用如下的写法:
var obj = document.documentElement || document.body;
obj.scrollLeft obj.scrollTop
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
width: 200px;
height: 200px;
border: solid 1px;
background-color: orange;
font-size: 30px;
overflow: scroll;
}
</style>
</head>
<body>
<div id="box">
今天我家的羊妈妈,好像要准备生小羊的样子。因为它不停的咩咩咩的叫,而且还卧在地上,我妈妈就准备了接生的工具,有剪刀、绳子...
今天我家的羊妈妈,好像要准备生小羊的样子。因为它不停的咩咩咩的叫,而且还卧在地上,我妈妈就准备了接生的工具,有剪刀、绳子...
今天我家的羊妈妈,好像要准备生小羊的样子。因为它不停的咩咩咩的叫,而且还卧在地上,我妈妈就准备了接生的工具,有剪刀、绳子...
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<script>
//给div添加滚动事件。
var box = document.getElementById("box");
box.onscroll = function (e) {
e = e || window.event;
// console.log (e.type);
console.log (this.scrollTop);
console.log (this.scrollLeft);
if(this.scrollTop >1000)
this.scrollTop = 0;
}
//window对象的滚动事件处理
window.onscroll =function () {
var obj = document.documentElement || document.body;
console.log (obj.scrollTop);
console.log (obj.scrollLeft);
if(obj.scrollTop >2000)
obj.scrollTop = 0;
}
</script>
</body>
</html>
无缝滚动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#box {
width: 500px;
height: 300px; /*做无缝滚动效果时容器要给高度,而且这个高度要小于内容的高度*/
border: 1px solid;
margin: 100px auto;
line-height: 2em;
padding: 0 10px;
overflow: hidden;
}
ul {
list-style: none;
}
span {
margin-right: 10px;
}
a {
color: #000;
text-decoration: none;
}
a:hover {
color: red;
text-decoration: underline;
}
</style>
</head>
<body>
<div id="box">
<ul id="list">
<li><span>1.</span><a href="">新闻1</a></li>
<li><span>2.</span><a href="">新闻2</a></li>
<li><span>3.</span><a href="">新闻3</a></li>
<li><span>4.</span><a href="">新闻4</a></li>
<li><span>5.</span><a href="">新闻5</a></li>
<li><span>6.</span><a href="">新闻6</a></li>
<li><span>7.</span><a href="">新闻7</a></li>
<li><span>8.</span><a href="">新闻8</a></li>
<li><span>9.</span><a href="">新闻9</a></li>
<li><span>10.</span><a href="">新闻10</a></li>
<li><span>11.</span><a href="">新闻11</a></li>
</ul>
</div>
<script>
//将ul中的内容翻倍。
//当ul中的内容有一半的高度滚出了div的窗口。重置整个ul中的内容。从头滚。设置scrollTop 0
(function () {
//内容翻倍
var ul = document.querySelector ("ul");
ul.innerHTML += ul.innerHTML;
//获得ul元素的高度。
var height = ul.offsetHeight;
const SPEED = 1;
const INTERVAL = 15;
var scrollSpeed = SPEED;
//使用定时器来执行
var timer = setInterval (scrollUp, INTERVAL);
var box = document.getElementById ("box");
function scrollUp() {
box.scrollTop += scrollSpeed;
//当 box.scrollTop 值大于等于ul的高度的一半,重置。
if (box.scrollTop >= height >> 1) {
box.scrollTop = 0;
}
};
//鼠标进入停止滚动
box.onmouseover = function () {
scrollSpeed = 0;
// clearInterval(timer);
}
//鼠标移出,继续滚动
box.onmouseout = function () {
scrollSpeed = SPEED;
// timer = setInterval (scrollUp, INTERVAL);
}
}) ();
</script>
</body>
</html>
7 鼠标滚轮事件
鼠标滚轮事件:
谷歌+IE:事件名称:mousewheel
一般添加鼠标滚轮事件给document对象添加。
事件对象有一个属性:wheelDelta。鼠标滚轮滚动一格,页面移动的距离。
向下:-120
向上:120
火狐的滚轮事件:DOMMouseScroll. 必须使用DOM2添加。
对应的事件对象的属性:detail
向下:3
向上:-3
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
height: 3000px;
}
</style>
</head>
<body>
<script>
//谷歌+IE
/* document.onmousewheel = function (e) {
e = e || window.event;
console.log (e.wheelDelta);
}*/
//火狐
/*document.addEventListener("DOMMouseScroll",function (e) {
console.log (e.detail);
})*/
//兼容实现
function mouseWheel() {
//火狐的写法
if(document.addEventListener){
document.addEventListener("DOMMouseScroll",scroll);
}
//IE + 谷歌
document.onmousewheel = scroll;
};
//e 事件对象
function scroll(e) {
e = e || window.event;
if (e.wheelDelta) {//谷歌+IE
console.log (e.wheelDelta < 0 ? "向下滚动" :"向上滚动");
}else{//火狐
console.log (e.detail < 0 ? "向上滚动" :"向下滚动");
}
}
mouseWheel();
</script>
</body>
</html>
8 文档事件-load
文档事件:load 事件。
load:装载。
触发该事件的条件:当页面中绑定该事件的元素的所有的资源全部加载完毕只有触发该事件。
如果load给window对象添加,那么就是整个文档加载完毕(包括外部的资源)之后触发该事件。
load还可以给文档中的元素添加。当元素对应的资源全部加载完毕,触发执行。
使用:当需要在某些元素或者是外部的资源,或者是整个文档加载完毕之后执行某些内容,需要使用load事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315782029&di=4fa6ebfa82f167493b8214cb966373aa&imgtype=0&src=http%3A%2F%2Fphotocdn.sohu.com%2F20130221%2FImg366640763.jpg" alt="">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315809552&di=202cb2739f29948b68cfc02d6634d942&imgtype=0&src=http%3A%2F%2Fimg4.imgtn.bdimg.com%2Fit%2Fu%3D524593429%2C4253628266%26fm%3D214%26gp%3D0.jpg" alt="">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315872359&di=054c6cfb33a39dec02172c409f8cad07&imgtype=0&src=http%3A%2F%2Fy1.ifengimg.com%2Ff04c9b92453d105f%2F2015%2F0209%2Fxes_803949ab4b84020a46e26f8ca3b15553.jpg" alt="">
<script>
//整个文档加载完毕之后自动执行。
window.onload = function () {
var div = document.querySelector("div");
console.log (div.innerHTML);
console.log ("页面加载完毕!");
}
var imgs = document.querySelectorAll("img");
//第一张图片加载完毕之后执行。
imgs[0].onload = function () {
console.log ("第一章图片加载完毕");
}
</script>
<div>
盗墓笔记-十年人间
</div>
</body>
</html>
9 文档事件-error
文档事件:error:
error:可以给页面的元素添加该事件,如果该元素加载失败,那么会触发执行该事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="xxx.jpg" alt="">
<script>
var img = document.querySelector ("img");
//当图片加载失败,执行
img.onerror = function () {
console.log ("图片加载失败!");
}
</script>
</body>
</html>
10 文档事件-DOMContentLoaded
文档事件:DOMContentLoaded
DOMContentLoaded:DOM树【结构】内容加载完毕事件。
1: DOMContentLoaded 事件 早于 load 事件.
2: DOMContentLoaded 事件给 document添加。
3:DOMContentLoaded 事件只能使用DOM2级事件处理方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315782029&di=4fa6ebfa82f167493b8214cb966373aa&imgtype=0&src=http%3A%2F%2Fphotocdn.sohu.com%2F20130221%2FImg366640763.jpg" alt="">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315809552&di=202cb2739f29948b68cfc02d6634d942&imgtype=0&src=http%3A%2F%2Fimg4.imgtn.bdimg.com%2Fit%2Fu%3D524593429%2C4253628266%26fm%3D214%26gp%3D0.jpg" alt="">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315872359&di=054c6cfb33a39dec02172c409f8cad07&imgtype=0&src=http%3A%2F%2Fy1.ifengimg.com%2Ff04c9b92453d105f%2F2015%2F0209%2Fxes_803949ab4b84020a46e26f8ca3b15553.jpg" alt="">
<script>
//整个文档加载完毕之后自动执行。
window.onload = function () {
console.log ("页面加载完毕!");
}
document.addEventListener("DOMContentLoaded",function () {
console.log ("DOM树加载完毕!");
});
</script>
</body>
</html>
11 文档事件-readystatechange
文档事件:readystatechange
document.readyState: 代表了当前文档加载的状态。只能取三个值。
loading : 文档正在加载中。
interactive:加载外部资源文件。
complete:加载完毕
readystatechange :事件会在上述的三个状态进行状态切换的时候自动触发。
会触发两次该事件。
1:loading–interactive
输出:interactive
2:interactive—complete
输出:complete
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315782029&di=4fa6ebfa82f167493b8214cb966373aa&imgtype=0&src=http%3A%2F%2Fphotocdn.sohu.com%2F20130221%2FImg366640763.jpg" alt="">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315809552&di=202cb2739f29948b68cfc02d6634d942&imgtype=0&src=http%3A%2F%2Fimg4.imgtn.bdimg.com%2Fit%2Fu%3D524593429%2C4253628266%26fm%3D214%26gp%3D0.jpg" alt="">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597315872359&di=054c6cfb33a39dec02172c409f8cad07&imgtype=0&src=http%3A%2F%2Fy1.ifengimg.com%2Ff04c9b92453d105f%2F2015%2F0209%2Fxes_803949ab4b84020a46e26f8ca3b15553.jpg" alt="">
<script>
document.onreadystatechange = function () {
console.log (document.readyState);
}
setInterval(function () {
console.log (document.readyState)
},10);
</script>
</body>
</html>
12 文档加载过程练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1426452382,2822824432&fm=26&gp=0.jpg" alt="">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597318946301&di=54b77f8a9e50baab08e674a549edf3c5&imgtype=0&src=http%3A%2F%2Fy2.ifengimg.com%2F11bc3d0677642853%2F2012%2F1225%2Frdn_50d95b2a3edd9.jpg" alt="">
<script>
var imgs = document.querySelectorAll("img");
//3: 加载第一个图片
imgs[0].onload = function () {
console.log ("第一张图片加载完毕");
}
//4: 加载第2个图片
imgs[1].onload = function () {
console.log ("第二张图片加载完毕");
}
//6: 整个文档加载完毕
window.onload = function () {
console.log ("整个文档加载完毕");
}
//1: 输出 interactive:准备加载外部资源
//5: 输出 complete :资源加载完毕。
document.onreadystatechange = function () {
console.log (document.readyState);
}
//2: 解析分析完毕
document.addEventListener("DOMContentLoaded",function () {
console.log ("DOM树加载完毕!");
});
</script>
</body>
</html>
13 事件委托-重点
在如下的示例中,使用以前的方式,动态的给ul添加子元素。如果希望子元素也有绑定事件,那么需要单独添加。
以前的方式的问题:
1:程序的扩展性比较差。维护成本比较高。
2:如果子元素很多,那么每个子元素都绑定事件,那么对整个文档的性能会造成一定的影响。
事件委托:如果有事件需要作用到元素的所有的子元素上,那么可以将该事件直接只绑定给父元素对象。
因为有事件冒泡的存在,第一个被事件作用到的对象是子元素。然后再冒泡给底层的父元素。
事件处理函数整体来处理当前元素的子元素需要处理的任务。通过target对象来代表子元素。
相当于把子元素需要处理的任务,委托给父元素执行了。
通过事件委托,可以将之前存在的两个问题完美的解决掉。
通过事件委托机制,可以提升页面的事件的响应的效率。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li>钢铁是怎样炼成的</li>
<li>鲁滨逊漂流记</li>
<li>围城</li>
<li>三重门</li>
<li>白鹿原</li>
</ul>
<script>
//点击每个li 打印里面的内容。
/* var lis = document.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
console.log (this.innerHTML);
}
}*/
//动态的给ul中添加li
/* var newLi = document.createElement("li");
newLi.innerHTML = "战争与和平";
var ul = document.querySelector("ul");
ul.appendChild(newLi);
//单独添加事件
newLi.onclick = function () {
console.log (this.innerHTML);
}*/
//使用事件委托的方式解决上述的问题
//事件给父元素添加
var ul = document.querySelector("ul");
ul.onclick = function (e) {
e = e || window.event;
console.log (e.target.innerHTML);
}
//动态的添加子元素
var newLi = document.createElement("li");
newLi.innerHTML = "战争与和平";
var ul = document.querySelector("ul");
ul.appendChild(newLi);
</script>
</body>
</html>