外观
事件
事件可以用于处理表单验证、用户输入、用户行为、浏览器动作。
它和Web页面连接到一起,使用户可以和用户进行交互、以响应用户的操作,如浏览器载入文档或用户动作如敲击键盘、
滚动鼠标等触发,而事件处理程序则说明一个对象如何响应事件。
事件的调用方式:
在script标签中调用(在下方代码有演示)
在元素中调用
document.getElementById('myButton1').onclick = function () {
alert('通过script标签调用事件')
}
function event1() {
alert('通过元素本身调用事件');
}为元素的onclick属性赋值以添加事件的方式已被弃用,可以使用addEventListener函数来添加事件。它的第一个参数是事件类型,比如click为点击事件,keyup为键盘松开的事件,第二个参数为一个函数,它是回调函数,在事件被触发后执行。
const el = document.querySelector("#object");
el.addEventListener("click", function() {
console.log(el + '的click事件被触发')
})若使用onclick属性添加事件,然后想要移除事件,可以将onclick设为null。
若使用第二种方式添加实现,则需要调用removeEventListener函数移除事件,该方法接收一个参数,就是对应的回调函数本身。所以若有移除事件的需求,则不能像上方示例中将回调函数表达为匿名函数。
const el = document.querySelector("#object");
const func = function() {
console.log(el + '的click事件被触发')
}
el.addEventListener('click', func); //添加事件
el.removeEventListener('click', func); //移除事件现将常用事件写在下面。
- 鼠标键盘事件:
- onkeydown:某个键盘的键被按下时触发此案件
- onkeypress:某个键盘的按键被按下或按住时触发此案件
- onkeyup:某个键盘的按键被松开时触发事件
- onclick:鼠标单击某个对象时触发此事件
- ondblclick:鼠标双击某个对象时触发此事件
- onmousedown:某个鼠标按键被按下时触发此事件
- onmousemove:鼠标被移动时触发此事件
- onmouseout:鼠标从某元素移开时触发此事件
- onmouseover:鼠标移动到某元素上方时触发此事件
- onmouseup:某个鼠标按键被松开时触发此事件
- onmouseleave:当鼠标指针移出元素时触发此事件
- onmouseenter:当鼠标指针移动到某元素上方时触发此事件
- oncontextmenu:在用户单击鼠标右键打开上下文菜单时触发此事件
- 页面相关事件
- onload:某个页面或图像被完成加载时触发此事件
- onabort:图像加载被中断时触发此事件
- onerror:当加载文档或图像发生错误时触发此事件
- onresize:当浏览器的窗口大小发生改变时触发此事件
- onbeforeunload:当前页面的内容将要被改变时触发此事件
- onunload:当前页面将被改变时触发此事件
- Onhashchange:该事件在当前URL的锚部分发生修改时被触发
- Onpageshow:该事件在用户访问该页面时被触发
- Onpagehide:该事件在用户离开当前网页跳转到另外一个网页时触发
- Onscroll:当文档被滚动时触发此事件
- 表单相关事件
- onreset:当重置按钮被单击时触发此事件
- onblur:当元素失去焦点时触发此事件
- onchange:当元素失去焦点并且元素的内容发生改变时触发此事件
- onsubmit:当提交按钮被单击时触发此事件
- onfocus:当元素获得焦点时触发此事件
- onfocusin:元素即将获得焦点时触发此事件
- onfocusout:元素即将失去焦点时触发此事件
- oninput:元素获取用户输入时触发此事件
- onsearch:用户向搜索域输入文本时触发此事件(<input='research'>)
- onselect:用户选取文本时触发此事件
- 拖动相关事件
- ondrag:元素正在被拖动时触发此事件
- ondragend:元素被拖动完成后触发此事件
- ondragenter:被拖动的元素到达放置目标后触发此事件
- ondragleave:被拖动的元素离开放置目标后触发此事件
- ondragover:被拖动的元素在放置目标上时触发此事件
- ondrop:该事件在拖动元素放置在目标区域时触发 5. 编辑相关事件
- onselect:当文本内容被选择时触发此事件
- onselectstart:当文本内容的选择即将发生后触发此事件
- oncopy:当页面的被选择内容被复制时触发此事件
- oncut:当页面的被选择内容被剪切时触发此事件
- onpaste:当页面被被粘贴时触发此事件
- onafterprint:该事件在页面已经开始打印、或打印窗口被关闭时触发
- onbeforeprint:该事件在页面即将被打印时触发
事件对象属性
下面列举了Event对象的属性:
- type:返回当前Event对象表示的事件名称
- altLeft:该属性设置或获取左Alt的状态,返回值为true时表示关闭,ctrlLeft和shiftLeft属性类似
- srcElement:该属性设置或获取触发事件的对象
- button:该属性设置或获取触发事件时按下的鼠标按键
- clientX:该属性获取鼠标在浏览器窗口中的X坐标,只读
- clientY:该属性获取鼠标在浏览器窗口中的Y坐标,只读
- offsetX:发生事件的地点在事件源元素的坐标系统中的X坐标
- offsetY:发生事件的地点在事件源元素的坐标系统中的Y坐标
- altKey:返回当事件被触发时Alt键是否被按下
- ctrlKey:返回当事件被触发时ctrl键是否被按下
- shiftKey:返回当事件被触发时shift键是否被按下
- cancelBubble:返回是否不接受上层元素的控制
- Bubble:指示事件是否是气泡事件
- currentTarget:返回其事件监听器触发该事件的元素
- eventPause:返回事件传播的当前阶段
- target:返回触发此事件的元素(事件的目标节点)
- timestamp:返回事件生成的日期和事件
- Location:返回按键在设备上的位置
- charCode:返回onkeypress事件触发键值的字母代码
- key:在按下按键时返回按键的标识符
- keyCode:返回onkeypress事件触发的键值的字母代码,或者是onkeydown或onkeyup的代码
- Which:同上
- metaKey:返回当事件被触发时“meta”键是否被按下
- relatedTarget:返回与该事件的目标节点相关的节点
事件对象Event对象的方法:主要用于创建新的事件对象、初始化新创建对象属性等,主要方法如下:
- createEvent():创建新的事件对象
- initEvent():初始化新创建的Event对象的属性
- preventEvent()通知浏览器不要执行与事件关联的默认动作
- stopPropagation():不再派发事件
- addEventListener():允许在目标事件中注册监听事件
- dispatchEvent():允许发送事件到监听器上
- removeEventListener():运行一次注册在事件目标上的监听事件
- handleEvent():把任意对象注册为事件处理程序
- initMouseEvent():初始化鼠标事件对象的值
- initKeyboardEvent():初始化键盘事件对象的值
文本相关事件
oncopy:在用户复制文本时被触发
onpaste:在用户粘贴文本时被触发
oncut:在用户剪切文本时被触发
onselect:在用户选择文本时被触发
代码:
<!DOCTYPE html>
<html lang="en"
xmlns:input="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>
文本编辑事件</title>
<script>
//1. oncopy:在用户复制文本时被触发
function Copy() {
alert('复制了文本');
}
//2. onpaste:在用户粘贴文本时被触发
function Paste() {
alert('粘贴了文本');
}
//3. oncut:在用户剪切文本时被触发
function Cut() {
alert('剪切了文本');
}
//4. onselect:在用户选择文本时被触发
function Select(){
alert('选择了文本');
}
</script>
</head>
<body>
<table>
<tr>
<td>
<p oncopy="Copy()">
复制此段文本时触发oncopy事件</p>
</td>
<td><input type="text"
onpaste="Paste()">
</td>
</tr>
<tr>
<td><input type="text"
oncut='Cut()'
value="剪切此段文本时触发此事件">
</td>
<td>
<p onselect="Select()">在选择此段文本时触发此事件</p>
</td>
</tr>
</table>
</body>
</html>键盘相关事件
- onkeydown事件:键盘被按下时触发
- onkeypress事件:键盘被按下时被触发,此事件只有字符键被按下时触发,单独按下功能键、shift、alt、ctrl等按键时不触发
- onkeyup事件:键盘按键被松开时触发此事件
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
键盘相关事件</title>
<script>
//1. onkeydown事件:键盘被按下时触发
function keyDown() {
alert('你按下了一个键盘按键');
}
//2. onkeypress事件:键盘被按下时被触发,此事件只有字符键被按下时触发,单独按下功能键、shift、alt、ctrl等按键时不触发
function keyPress() {
alert('你按下了一个键盘按键(在按下非字符键时无效)');
}
//3. onkeyup事件:键盘按键被松开时触发此事件
function keyUp() {
alert('键盘的某个按键被松开');
}
</script>
</head>
<body>
<input type="text"
title="在这里按下键盘按键时弹出对话框"
onkeydown="keyDown()">
<input type="text"
title="在这里按下键盘按键时弹出对话框(在按下非字符键时无效)"
onkeydown="keyPress()">
<input type="text"
title="键盘的某个按键被松开"
onkeydown="keyUp()">
</body>
</html>鼠标相关事件
- 鼠标相关事件
单击事件是鼠标点击时触发的事件,用onclick实现,这里不再演示
- 鼠标按下与松开事件
鼠标按下事件为onmousedown事件,用户在按下鼠标时触发
- 鼠标移入移出事件
鼠标移入事件由onmouseover控制,鼠标移除事件由onmouseout控制
- 鼠标移动事件
鼠标移动事件onmousemove控制
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
鼠标相关事件</title>
<script>
//本文件介绍有关事件的使用
//1. 鼠标相关事件
//单击事件是鼠标点击时触发的使劲按,用onclick实现,这里不再演示
//2. 鼠标按下与松开事件
//鼠标按下事件为onmousedown事件,用户在按下鼠标时触发
function clickEvent1() {
document.getElementById('button').style.backgroundColor = 'black';
document.getElementById('button').style.color = 'white';
}
function clickEvent2() {
document.getElementById('button').style.backgroundColor = 'white';
document.getElementById('button').style.color = 'black';
}
//3. 鼠标移入移出事件
//鼠标移入事件由onmouseover控制,鼠标移除事件由onmouseout控制
function moveEvent1() {
document.getElementById('div').style.backgroundColor = 'black';
document.getElementById('div').style.color = 'white';
document.getElementById('div').innerHTML = '现在鼠标在此div内';
}
function moveEvent2() {
document.getElementById('div').style.backgroundColor = 'white';
document.getElementById('div').style.color = 'black';
document.getElementById('div').innerHTML = '现在鼠标在此div外';
}
//4. 鼠标移动事件
// 鼠标移动事件onmousemove控制
</script>
</head>
<body>
<button id='button'
onmousedown="clickEvent1()"
onmouseup="clickEvent2()">
按下和松开按钮,此按钮会变换两次颜色
</button>
<br>
<br>
<div style="background-color: red; width: 200px; height: 200px"
id="div"
onmouseover="moveEvent1()"
onmouseout="moveEvent2()">
将鼠标移到此div之上然后再移出,此div会变换两次颜色
</div>
</body>
</html>表单相关事件
- 获得焦点和失去焦点事件
onfocus事件在某个元素获取焦点时被触发
onblur事件在某个元素失去焦点时被触发
onchange事件在对象内容被改变且失去焦点时被触发,一般用在下拉列表中
onsubmit事件在表单提交时被触发,该事件可以验证表单输入项的正确性;onreset事件在表单被重置时触发,一般用于清空文本框
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
表单相关事件</title>
<script>
//1. 获得焦点和失去焦点事件
// onfocus事件在某个元素获取焦点时被触发
// onblur事件在某个元素失去焦点时被触发
function onFocus() {
document.getElementById('text').value = '文本框获得焦点'
}
function onBlur() {
document.getElementById('text').value = '文本框失去焦点'
}
//2. onchange事件在对象内容被改变且失去焦点时被触发,一般用在下拉列表中
function onChange() {
let obj = document.getElementById('combobox')
document.getElementById('text').value = '下拉菜单的值为' + obj.options[obj.selectedIndex].innerHTML;
}
//3. onsubmit事件在表单提交时被触发,该事件可以验证表单输入项的正确性;onreset事件在表单被重置时触发,一般用于清空文本框
function submit() {
alert('提交了表单');
}
function reset() {
alert('重置了表单');
}
</script>
</head>
<body>
<form action="#">
<input type="text"
onfocus="onFocus()"
onblur="onBlur()"
id="text">
<select id="combobox"
onchange="onChange()">
<option value="1">
选项一
</option>
<option value="2">
选项二
</option>
<option value="3">
选项三
</option>
</select></form>
<hr>
<form action="#"
onsubmit="submit()"
onreset="reset()">
<table>
<tr>
<td>用户名</td>
<td><input
type="text"
name="用户名"
id="user_name">
</td>
</tr>
<tr>
<td>密码</td>
<td><input
type="password"
name="密码"
id="password">
</td>
</tr>
<tr>
<td>
<input type="submit"
value="提交">
</td>
<td><input
type="reset"
value="重置">
</td>
</tr>
</table>
</form>
</body>
</html>页面相关事件
- onload:在页面加载完成后被触发
- onresize:在浏览器大小被改变后被触发
- onbeforeunload:在浏览器被关闭前被触发
拖动相关事件
- ondragstart事件在用户开始拖动元素时被触发 ondrag事件在元素正在被拖动时被触发 ondragend事件在元素被拖动完后被触发
- ondragenter事件在元素进入某范围内时被触发 ondragover事件在元素在某一范围内拖动时被触发 ondragleave事件在元素离开某一范围后被触发
多媒体相关事件
- onabort事件在视频或音频被终止加载时被触发
- oncanplay事件在用户可以开始播放音乐或视频时被触发、
- oncanplaythrough事件在音乐或视频可以正常播放且无须缓冲或停顿时被触发
- ondurationchange事件的时长发生变化时被出阿飞
- onemptied事件在期播放列表为空时被触发
- onended事件音频或视频结束播放时被触发
- onerror事件在视频或音频加载期间发生错误时被触发
- onloadeddata事件在浏览器加载音频或视频时被触发
- onloadedmetadata事件在浏览器在加载指定音频或视频的元数据时被触发
- onloadstart事件在浏览器开始寻找指定音频或视频时被触发
- onpause事件在音频或视频被暂停时被触发
- onplay事件在视频或音频开始播放时被触发
- onplaying事件在视频或音频暂停或者在缓冲后后准备重新开始播放时被触发
- onprogress事件在浏览器下载指定音频或视频时被触发
- onratechange事件在视频或视频的播放速度被改变时被触发
- onseeked事件在用户重新定位视频或音频的播放位置后被触发
- onseeking事件在用户重新开始定位视频或音频时被触发
- onstalled事件在浏览器获取媒体数据、但媒体数据不可用时被触发
- onsuspend事件在浏览器读取媒体数据终止时被触发
- ontimeupdate事件在当前的播放位置发生改变时被触发
- onvolumechange事件在媒体音量被改变时被触发
- onwaiting事件在视频由于要播放下一帧而需要缓冲时被触发
事件委托
举个例子,有一些li元素被包裹在ul元素内,需求是在点击哪个li时就让这个li元素的字体颜色变为红色。若li子元素很多,则我们不可能单独为每一个li添加事件监听,若使用foreach遍历这些元素,则达不到“点击哪个li时就让这个li元素的字体颜色变为红色”这个要求,因为这时候遍历得到的li元素都是等价的。所以我们可以采用以下方法解决这个问题:
- 为ul元素添加事件监听,在点击li时同样会触发ul的事件监听;
- 查找是哪个子元素触发了ul的事件监听,并改变对应元素的样式。
事件对象有一些属性,和target有关,它们就是获取哪个子元素触发了父元素的事件监听。
const el = document.querySelector("ul");
el.addEventListener('click', function (e) {
console.log(e.target.style.color = 'red')
})e.target就代表触发父元素事件监听的子元素本身,因此可以直接对其操作。
事件循环
JavaScript的一大特点就是单线程,同一时间只能做一件事。单线程就意味着,前一个任务结束才能进行后一个任务,若前面的渲染时长太大,后面的渲染就要等待很久才能进行,造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
为了解决这个问题,H5提出了Web Worker标准,允许JavaScript创建多个线程,于是Javascript出现了同步和异步。
在JavaScript中,事件监听、setTimeout等定时器函数是实现异步的途径,它们是通过执行回调函数实现异步的。JavaScript是顺序执行的脚本语言,在遇到同步执行的语句时会将其加入执行栈并执行,直到它执行完毕再执行下一个语句。若遇到异步执行的语句则将其加入任务队列,并读取下一个语句。当其他同步语句执行完毕后,JavaScript回到任务队列寻找是否有可执行的任务,若有则执行此任务然后再同步执行,否则继续同步执行,以此往复循环。
这里有一个经典问题:下列语句的打印顺序是什么。
console.log(1);
setTimeout(function () {
console.log(4);
}, 3000);
console.log(3);
window.addEventListener("click", function () {
console.log(2)
});答案是1324或1342,是哪个取决于三秒内有没有点击。
JavaScript主线程不断地执行任务和取任务,就称这个过程为事件循环。