事件的概念
日常生活中事件: 发生并得到处理的操作(即事情来了, 然后处理)
在JS中的事件是: 用户在页面上操作, 然后我们要调用函数来处理。
js属于事件驱动编程。
事件的模式
JavaScript有两种事件实现模式: 内联模式、脚本模式。
1.内联模式
直接在HTML标签中添加事件。这种模型是最传统简单的一种处理事件的方法。但是这种模式中事件和HTML是混写的,并没有将JS与HTML分离,当代码量多了以后,对后期代码维护和扩展很不利。
<body>
<button onclick="fn('内联模式')">点击</button>
<script>
//内联模式
// fn必须是全局函数
function fn(str){
console.log(str);//控制台打印:内联模式
}
</script>
</body>
【注】内联模式调用的函数不能放到window.onload里面, 否则会找不到该函数
2.脚本模式
脚本模式能将JS代码和HTML代码分离,符合代码规范。
<body>
<button>点击</button>
<script>
//脚本模式
//【注】当一个元素上绑定了内联与脚本,脚本模式优先
</script>
<script src="js/03.index.js"></script>
</body>
03.index.js
var btn=document.querySelector("button")
btn.onclick=function(){
console.log("脚本模式");
}
事件的分类
1.鼠标事件
<body>
<div class="box">
<div class="box2"></div>
</div>
</body>
.box{
width: 200px;
height: 200px;
background-color: green;
display: flex;
justify-content: center;
align-items: center;
}
.box2{
width: 80px;
height: 80px;
background-color: pink;
}
onclick
当单击鼠标按钮并在松开时触发
var box=document.querySelector(".box");
box.onclick=function(){
console.log("onclick 鼠标单击");
}
ondblclick
当双击鼠标按钮时触发
var box=document.querySelector(".box");
box.ondblclick=function(){
console.log("ondblclick 鼠标双击");
}
onmousedown
当按下了鼠标还未松开时触发
var box=document.querySelector(".box");
box.onmousedown=function(){
console.log("onmousedown 鼠标按下");
}
onmouseup
释放鼠标按钮时触发
var box=document.querySelector(".box");
box.onmouseup=function(){
console.log("onmouseup 鼠标抬起");
}
onmouseenter
当鼠标移入某个元素的那一刻触发
var box=document.querySelector(".box");
box.onmouseenter=function(){
console.log("onmouseenter 鼠标移入");
}
onmouseleave
当鼠标刚移出某个元素的那一刻触发
var box=document.querySelector(".box");
box.onmouseleave=function(){
console.log("onmouseleave 鼠标移出");
}
onmouseover
当鼠标移入某个元素的那一刻触发
var box=document.querySelector(".box");
box.onmouseover=function(){
console.log("onmouseover 鼠标移入");
}
onmouseout
当鼠标刚移出某个元素的那一刻触发
var box=document.querySelector(".box");
box.onmouseout=function(){
console.log("onmouseout 鼠标移出");
}
mouseover/mouseout和mouseenter/mouseleave的区别是:
区别一:
mouseover/mouseout: 元素的子元素移入/移出也会触发事件
mouseenter/mouseleave: 元素的子元素移入/移出不会触发事件
区别二:
代码中同时存在时
mouseover 优先于 mouseenter
mouseout 优先于 mouseleave
onmousemove
当鼠标指针在某个元素上移动时触发
var box=document.querySelector(".box");
box.onmousemove=function(){
console.log("onmousemove 鼠标移动");
}
onmousewheel
当鼠标在某个元素上滚轮滚动时触发
var box=document.querySelector(".box");
box.onmousewheel=function(){
console.log("onmousewheel 鼠标移入滚轮滚动");
}
2.键盘事件
<input type="text">
onkeydown
当用户按下键盘上某个键触发,如果按住不放,会重复触发
var txt=document.querySelector("input");
txt.onkeydown=function(){
console.log(this.value);
}
onkeyUp
当用户释放键盘上的某个键触发
var txt=document.querySelector("input");
txt.onkeyup=function(){
console.log(this.value);
}
onkeypress
当用户按下键盘上的字符键触发,如果按住不放,会重复触发
var txt=document.querySelector("input");
txt.onkeypress=function(){
console.log(this.value);
}
3.html事件
onload
1)dom结构加载完成,并且外部所有的资源加载完成才触发。
2)凡是带有src属性的标签都有一个onload事件(img,script...)
window.onload = function () {
console.log("页面加载完成");
}
unonload
当页面完全卸载后触发。关闭浏览器会触发一次,刷新页面也会触发一次。
window.onunload = function () {
console.log("卸载事件……");
}
onresize
当页面大小发生改变的时候就会触发。
//改变窗口大小的时候才会触发,刷新不会自动触发
window.onresize=function(){
var w=document.documentElement.clientWidth;
if(w>0&&w<360){
document.body.style.backgroundColor="green"
}else if(w>=360&&w<780){
document.body.style.backgroundColor="yellow"
}else if(w>=780&&w<960){
document.body.style.backgroundColor="red"
}else{
document.body.style.backgroundColor="pink"
}
}
//事件触发 注意要先绑定函数,再触发事件
window.onresize()
onwheel
在页面中滚动滚动条时触发,不一定要有滚动条元素。
document.onwheel=function(){
console.log("onwheel");
}
onscroll
当用户滚动带滚动条的元素时触发。
document.onscroll=function(){
console.log("onscroll");
}
oninput
用户在输入时立即触发。
document.onscroll=function(){
console.log("onscroll");
}
onchange
内容改变且失去焦点后触发。
var userName=document.querySelector("#username")
userName.onchange=function(){
console.log(this.value);
}
oninput和onchange的区别
- oninput 事件在元素值发生变化是立即触发,而onchange是在元素失去焦点时触发。
- 另外一点不同是 onchange 事件也可以作用于 <keygen> 和 <select> 元素。
onselect
当用户选择文本框(input 或 textarea)中的内容触发。
var userName=document.querySelector("#username")
userName.onselect=function(){
console.log(this.value);
}
onblur
当页面或元素失去焦点时触发。
var userName=document.querySelector("#username")
userName.onblur=function(){
console.log(this.value);
onfocus
当页面或者元素获得焦点时触发。
var userName=document.querySelector("#username")
userName.onfocus=function(){
console.log(this.value);
}
onsubmit
当用户点击提交按钮在<form>元素节点上触发。
//获取表单对象
var myForm=document.forms[0];
myForm.onsubmit=function(){
return false;
//false 阻止表单的默认行为,不让表单提交
//true 会触发html的表单提交行为
}
onreset
当用户点击重置按钮在<form>元素节点上触发。
//获取表单对象
var myForm=document.forms[0];
myForm.onreset=function(){
return true;
}
oncontextmenu
当用户右击鼠标时触发并打开上下文菜单。
document.oncontextmenu=function(e){
console.log("右击鼠标时打开上下文菜单");
}
事件对象(event对象)
event对象是在触发事件时, 浏览器会通过函数把事件对象作为参数传递过来, 在事件触发执行函数时一般会得到一个隐藏的参数, 该参数也是放在arguments数组中
获取事件对象
通过给函数添加一个参数获取事件对象
var box=document.querySelector(".box")
box.onclick=function(evt){
//ie6+ window.event
// console.log(window.event);
//google
// console.log(evt);
//兼容写法
var e=evt||window.event
console.log(e);
}
事件对象的属性
button
鼠标按下了哪个键
window.onmousedown=function(evt){
var e=evt||window.event;
console.log(e.button);//0左键点击 1滚轮点击 2右键点击
}
type
事件类型
var box = document.querySelector(".box")
box.onclick = function (evt) {
var e = evt || window.event;
console.log(e.type);//click
}
target 和 srcElement
目标对象,存放绑定事件的元素节点对象
var box = document.querySelector(".box")
box.onclick = function (evt) {
var e = evt || window.event;
console.log(e.target);//<div class="box"> </div>
console.log(e.srcElement);//<div class="box"> </div>
//e.target: Ie9+ 火狐、谷歌;
//e.srcElement:ie 678;
}
charCode
字符按键的字符编码
//charCode只能在onkeypress事件中生效在onkeydown中没有作用
window.onkeypress=function(evt){
var e=evt||window.event
console.log(e.charCode);
}
keyCode
按键的字符编码
window.onkeydown=function(evt){
var e=evt||window.event
console.log(e.keyCode);
}
key
按键的字符
window.onkeydown=function(evt){
var e=evt||window.event
console.log(e.key);
}
altKey
按下alt键返回true,否则返回false
window.onkeydown=function(evt){
var e=evt||window.event
console.log(e.altKey);
}
shiftKey
按下shift键返回true,否则返回false
window.onkeydown=function(evt){
var e=evt||window.event
console.log(e.shiftKey);
}
ctrlKey
按下ctrl键返回true,否则返回false
window.onkeydown=function(evt){
var e=evt||window.event
console.log(e.ctrlKey);
}
metaKey
按下win键返回true,否则返回false
window.onkeydown=function(evt){
var e=evt||window.event
console.log(e.mateKey);
}
clientX , clientY
浏览器可视区域的x坐标,以及浏览器可视区域的y坐标
var box = document.querySelector(".box")
box.onclick = function (evt) {
var e = evt || window.event;
console.log(e.clientX, e.clientY);//点击的位置到浏览器的左上角的x轴和y轴距离
}
pageX , pageY
浏览器内容区域的x坐标,以及浏览器内容区域的y坐标
var box = document.querySelector(".box")
box.onclick = function (evt) {
var e = evt || window.event;
console.log(e.pageX, e.pageY);//点击的位置到内容区域的左上角的x轴和y轴距离
}
screenX , screenY
显示器屏幕的x坐标,以及显示器屏幕的y坐标
var box = document.querySelector(".box")
box.onclick = function (evt) {
var e = evt || window.event;
console.log(e.screenX, e.screenY);//点击的位置到屏幕的左上角的x轴和y轴距离
}
offsetX , offsetY
鼠标点击的元素位置距离元素左边界的x坐标及y坐标
var box = document.querySelector(".box")
box.onclick = function (evt) {
var e = evt || window.event;
console.log(e.offsetX, e.offsetY);
}
stopPropagation() 和 cancelbubble=true
作用:停止冒泡
div{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.box1{
width: 500px;
height: 500px;
background: yellowgreen;
.box2{
width: 350px;
height: 350px;
background-color: skyblue;
.box3{
width: 200px;
height: 200px;
background-color: pink;
}
}
}
<div class="box1">box1
<div class="box2">box2
<div class="box3">box3</div>
</div>
</div>
1.没有停止冒泡时,事件会从内往外传递:
var box1=document.querySelector(".box1")
var box2=document.querySelector(".box2")
var box3=document.querySelector(".box3")
box3.onclick=function(){
console.log("box3");
}
box2.onclick=function(){
console.log("box2");
}
box1.onclick=function(){
console.log("box1");
}
document.body.onclick=function(){
console.log("body");
}
document.onclick=function(){
console.log("document");
}
window.onclick=function(){
console.log("window");
}
点击box3元素,运行结果:
2.停止冒泡:
box3.onclick=function(evt){
console.log("box3");
var e=evt||window.event;
//停止冒泡
// e.cancelBubble=true;//ie 了解即可
e.stopPropagation(); //重点
//兼容写法 了解即可
// if(e.cancelBubble){
// e.cancelBubble=true;
// }else{
// e.stopPropagation();
// }
}
点击box3元素,运行结果:
preventDefault() 和 returnValue=false
作用:阻止默认行为
可阻止的默认行为:
- 表单,提交,重置的行为
- a标签,跳转的行为
- 图片 拖拽的行为
- 右击菜单,显示菜单行为
...
<body>
<!-- 默认会跳转到百度页面 -->
<a href="http://www.baidu.com">跳转</a>
<script>
var oA=document.querySelector("a");
oA.onclick=function(evt){
//阻止默认行为 让a链接无法跳转到百度页面
// 方式1 重点
// return false;
var e=evt||window.event;
//方式2 ie 了解
// e.returnValue=false
//方式3 重点
e.preventDefault()
//方式4 兼容写法 了解
// if(e.preventDefault){
// e.preventDefault()
// }else{
// e.returnValue=false
// }
}
</script>
</body>
事件流
事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候, 那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获。
事件冒泡是从里往外逐个触发。事件捕获是从外往里逐个触发。现代的浏览器默认情况下都是事件冒泡的模式。
事件监听
当我们需要对一个元素设置多种点击事件时,如果写两个onclick那么后写的会覆盖先写的那个。无法达到想要的效果,这时就可以设置事件监听。
var box=document.querySelector(".box")
box.onclick=function(){
console.log("1111");
}
//还想添加一个点击事件,直接写
// box.onclick=function(){//这样的话后写的会覆盖先写的
// console.log("2222");
// }
//可以添加事件监听
//addEventListener("事件类型",函数,true/false)
//addEventListener("事件类型",函数,{once:true,capture:true})
// capture 捕获
// once 1次
box.addEventListener("click",function(){//这样就不会被覆盖了
console.log("2222");
})
绑定与移除事件监听
addEventListener()添加事件监听,有三个参数:事件类型、要执行的回调函数、和一个可选的布尔值参数,用于指定事件是否在捕获阶段触发(默认为false表示冒泡,true表示捕获)。
removeEventListener()移除事件监听,有三个参数:要移除的事件类型、要移除的事件监听函数、和一个布尔值参数(与要移除的事件监听一致)。
<body>
<button>绑定事件</button>
<button>移除事件</button>
<div class="box"></div>
<script>
//addEventListener 添加事件监听
//removeEventListener 移除事件监听
var btns=document.querySelectorAll("button");
var box=document.querySelector(".box")
box.onclick=function(){
console.log("1111");
}
btns[0].onclick=function(){
//绑定多个事件监听
box.addEventListener("click",fn1)
box.addEventListener("click",fn2)
}
function fn1(){
console.log("2222");
}
function fn2(){
console.log("3333");
}
//移除监听事件
btns[1].onclick=function(){
box.removeEventListener("click",fn1)
}
</script>
</body>