JS基础知识(十):事件

本文详细介绍了JavaScript中的事件绑定方式,包括内联模式和外联模式,并讲解了事件处理函数,如鼠标事件、键盘事件和HTML事件。重点讨论了事件对象的属性,如坐标、修改键和触发元素,以及事件冒泡和事件捕获的概念。此外,还涵盖了阻止右键菜单、超链接默认行为、拖拽原理和事件监听器的使用,以及事件委托的实现。
摘要由CSDN通过智能技术生成

一、事件绑定方式

1.1 内联模式

在内联模型中,事件处理函数是 HTML 标签的一个属性,用于处理指定事件。虽然内联在早期使用较多,但它是和 HTML 混写的, 并没有与 HTML 分离。

//在 HTML 中把事件处理函数作为属性执行 JS 代码
<input type="button" value="按钮" onclick="alert('Lee');" />//注意单双引号
//在 HTML 中把事件处理函数作为属性执行 JS 函数
<input type="button" value="按钮"onclick="box();" />//执行 JS 的函数
PS:函数不得放到 window.onload 里面,这样就看不见了。

1.2 外联模式(脚本模式)

由于内联模型违反了 HTML 与 JavaScript 代码层次分离的原则。为了解决这个问题,我们可以在 JavaScript 中处理事件。这种处理方式就是脚本模型。

var input=document.getElementsByTagName('input')[0];//得到 input 对象
input.onclick=function(){//匿名函数执行
	alert('Lee');
};
PS:通过匿名函数,可以直接触发对应的代码。也可以通过指定的函数名赋值的方式来执行函数(赋值的函数名不要跟着括号)。
input.onclick=box;   //把函数名赋值给事件处理函数

二、事件处理函数

JavaScript 可以处理的事件类型为:鼠标事件、键盘事件、HTML 事件
PS:所有的事件处理函数都会都有两个部分组成,on+ 事件名称,例如 click 事件的事件处理函数就是:onclick。在这里,我们主要谈论脚本模型的方式来构建事件,违反分离原则的内联模式,我们忽略掉。

2.1 鼠标事件,页面所有元素都可触发

click:当用户单击鼠标按钮或按下回车键时触发
dblclick:当用户双击主鼠标按钮时触发。
mousedown:当用户按下了鼠标还未弹起时触发。
mouseup:当用户释放鼠标按钮时触发。
mouseover:当鼠标移到某个元素上方时触发。
mouseout:当鼠标移出某个元素上方时触发。
mousemove:当鼠标指针在元素上移动时触发。
mouseenter:当鼠标移到某个元素上方时触发。
mouseleave:当鼠标移出某个元素上方时触发。
PS: mouseover的子节点会重复触发,mouseenter则不会,mouseenter在IE8以后才有

2.2 键盘事件,表单元素或window触发

keydown:当用户按下键盘上任意键触发,如果按住不放,会重复触发。
οnkeydοwn=function(){
alert(‘Lee’);
};
keypress:当用户按下键盘上的字符键触发,如果按住不放,会重复触发
οnkeypress= function(){
alert(‘Lee’);
};
keyup:当用户释放键盘上的键触发。
οnkeyup=function() {
alert(‘Lee’);
};

2.3 HTML事件,表单元素或window触发

//load:当页面完全加载后在 window 上面触发,或当框架集加载完毕后在框架集上触发。
window.onload=function() { alert('Lee'); };
//unload:当页面完全卸载后在 window 上面触发,或当框架集卸载后在框架集上触发。
//只有IE浏览器兼容,当页面解构时触发(刷新页面或者关闭当前页面)
window.onunload= function(){ alert('Lee'); };
//resize:当窗口或框架的大小变化时在 window 或框架上触发。 
window.onresize=function(){ alert('Lee'); };
//scroll:当用户滚动带滚动条的元素时触发。
window.onscroll=function() { alert('Lee'); };
//select:当用户选择文本框(input 或 textarea)中的一个或多个字符触发。
//当我们在输入框中选中文本的时候触发(光标选中input中的value值)
input.onselect=function(){ alert('Lee'); };
//change:当文本框(input 或 textarea)内容改变且失去焦点后触发。
//当我们修改了文本并且失去焦点时触发
input.onchange=function(){ alert('Lee'); };
//focus:当页面或者元素获得焦点时在 window 及相关元素上面触发。
input.onfocus= function(){ alert('Lee'); };
//blur:当页面或元素失去焦点时在 window 及相关元素上触发。 
input.onblur=function(){ alert('Lee'); };
//submit:当用户点击提交type=submit按钮在<form>元素上触发。必须是form元素
form.onsubmit=function(){ alert('Lee'); };
//reset:当用户点击重置type=reset按钮在<form>元素上触发。必须是form元素
form.onreset=function(){ alert('Lee'); };

三、事件对象

3.1 事件对象

事件对象三部分组成:对象.事件处理函数=函数

//例如:单击文档任意处。
document.onclick=function(){
	alert('Lee');
};

PS:以上程序的名词解释:click 表示一个事件类型,单击。onclick 表示一个事件处理 函数或绑定对象的属性(或者叫事件监听器、侦听器)。document 表示一个绑定的对象,用于触发某个元素区域。function()匿名函数是被执行的函数,用于触发后执行。

function box() {//普通空参函数
	alert(arguments.length); //0,没有得到任何传递的参数
}
input.onclick=function(){//事件绑定的执行函数
	alert(arguments.length); //1,得到一个隐藏参数
};
【注】通过上面两组函数中,我们发现,通过事件绑定的执行函数是可以得到一个隐藏参数的。 
说明,浏览器会自动分配一个参数,这个参数其实就是 event 对象。
当我们点击按钮时,系统会自动调用事件绑定的函数,将事件对象当作函数的第一个参数传入。

input.onclick=function(){
	alert(arguments[0]); //MouseEvent,鼠标事件对象
};//这种做法比较累,那么比较简单的做法是,直接通过接收参数来得到即可。
input.onclick=function(evt){
	//接受 event 对象,名称不一定非要 event
	alert(evt); //MouseEvent,鼠标事件对象
};
//事件对象的兼容性写法, 低版本IE(IE8)下使用 window.event。
input.onclick=function(evt){
	var e = evt || window.event;
	alert(); 
};

3.2 事件对象的属性

3.2.1 button属性

在这里插入图片描述

3.2.2 鼠标事件(可视区域及屏幕坐标)

可视区及屏幕坐标,事件对象提供了两组来获取浏览器坐标的属性,一组是页面可视区坐标,另一组是屏幕坐标
clientX clientY 可视窗口左上角为原点
screenX screenY 屏幕左上角为原点
pageX pageY 整个页面的左上角,包含滚出去的滚动距离

document.onclick=function(evt) {
    alert(evt.clientX +','+evt.clientY);
    alert(evt.screenX+','+evt.screenY);
};

区别
screenX: 鼠标位置相对于用户屏幕水平偏移量,而screenY也就是垂直方向的,此时的参照点也就是原点是屏幕的左上角。
clientX: 跟screenX相比就是将参照点改成了浏览器内容区域的左上角,该参照点会随之滚动条的移动而移动。
pageX:参照点也是浏览器内容区域的左上角,但它不会随着滚动条而变动。

3.2.3 鼠标事件(修改键)

有时,我们需要通过键盘上的某些键来配合鼠标来触发一些特殊的事件。这些键为: Shfit、Ctrl、Alt 和 Meat(Windows 中就是 Windows 键,苹果机中是 Cmd 键),它们经常被用 来修改鼠标事件和行为,所以叫修改键。
在这里插入图片描述

3.3 键盘事件

3.3.1 keyCode键码

在发生 keydown 和 keyup 事件时,event 对象的 keyCode 属性中会包含一个代码,与键盘上一个特定的键对应。对数字字母字符集,keyCode 属性的值与 ASCII 码中对应大写字母或数字的编码相同。字母中大小写不影响。

document.onkeydown=function(evt) {
	alert(evt.keyCode); //按任意键,得到相应的 keyCode
};

3.3.2 charCode字符编码

Firefox、Chrome 和 Safari 的 event 对象都支持一个 charCode 属性,这个属性只有在发 生 keypress 事件时才包含值,而且这个值是按下的那个键所代表字符的 ASCII 编码。此时 的 keyCode 通常等于 0 或者也可能等于所按键的编码。

function getCharCode(evt) {
     if(typeof evt.charCode== 'number') {
         return evt.charCode; 
     }else{
         return evt.keyCode;
     }
}
PS:可以使用 String.fromCharCode()ASCII 编码转换成实际的字符。

3.4 触发事件的元素节点(target)

document.onclick=function(evt) {
     alert(evt.target || window.event.srcElement);
};

四、事件冒泡和事件捕获

4.1 事件流

事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候, 那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围 的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获。

4.2 事件冒泡

是从里往外逐个触发

4.3 事件捕获

是从外往里逐个触发。那么现代的浏览器默认情况下都是冒泡模式

4.4 阻止事件冒泡

事件冒泡会给我们的实际开发带来很多困扰,所以我们要阻止事件冒泡。

//阻止冒泡
cancelBubble=true        stopPropagation()

五、阻止右键菜单

document.oncontextmenu = function(){
    alert("右键被按下");
    return false;
}//阻止官方的右键菜单

5.1 自定义右键菜单

//自定义右键菜单(HTML)
<body >
<div id="divId" style="width:300px;height:200px;background-color:red">
</div>
<div id="menuDiv" style="position:absolute;width:100px;height:80px;background-color:gray; ">
	<ul >
		<li>菜单1</li>
		<li>菜单2</li>
		<li>菜单3</li>
	</ul>
</div>
</body>

//自定义右键菜单(JS)
document.oncontextmenu=function(){
	return false;
}
document.getElementById("divId").onmousedown=function(){
	if(event.button==2){
		var menuDiv = document.getElementById("menuDiv");
		menuDiv.style.left = event.clientX+"px";
		menuDiv.style.top = event.clientY+"px";
		menuDiv.style.display = "block";
	}
}
document.body.onclick=function(){
	document.getElementById("menuDiv").style.display = "none";
}

六、阻止超链接的默认行为

有时需要在a标签上添加click事件,并且跳转前处理一些事务,故需要做一些处理

function test(){
	if(window.confirm("你确定要走么?")){
		return true;
	}else{
		return false;
	}
}
<body >
	<a href="test.html" onclick="test()"></a>
</body>

有时我们需要阻止事件的默认行为,比如:一个超链接的默认行为就点击然后跳转到指定的页面。那么阻止默认行为就可以屏蔽跳转的这种操作,而实现自定义操作。
取消事件默认行为还有一种不规范的做法,就是返回 false。

link.onclick = function () {
	alert('Lee'); 
	return false; //直接给个假,就不会跳转了。
};

PS:虽然 return false;可以实现这个功能,但有漏洞;
第一:必须写在最后,这样导致中间的代码执行后,有可能执行不到 return false;
第二:return false 写到最前那么之后的自定义操作就失效了。
所以,最好的方法应该是在最前面就阻止默认行为,并且后面还能执行代码。
在这里插入图片描述
在这里插入图片描述

七、拖拽原理

拖拽三剑客:相关的事件(onmousedown\onmousemove\onmouseup)
拖拽思路:

  1. 给目标元素添加onmousedown事件,拖拽的前提是在目标元素按下鼠标左键
    记录鼠标按下的位置与目标元素的相对距离
  2. 当onmousedown发生以后,此刻给document添加onmousemove事件,意味着此刻鼠标在网页的移动都将改变目标元素的位置
    在onmousemove事件中,设定目标元素的left和top,公式。
    目标元素的left = 鼠标的clientX – (鼠标和元素的横坐标差,即offsetX)
    目标元素的top = 鼠标的clientY – (鼠标和元素的纵坐标差,即offsetY)
  3. 当onmousedown发生以后,此刻给document添加onmouseup事件,意味着此刻鼠标在网页的任意位置松开鼠标,都会放弃拖拽的效果
  4. 获得浏览器的宽高:
    windowWidth = document.documentElement.clientWidth || document.body.clientWidth

八、事件监听器

8.1 添加事件监听器

事件监听器:addEventListener() 方法用于向指定元素添加事件句柄,IE8及其以下不支持,火狐和谷歌支持。

事件监听器target.addEventListener(“click”, fun, false)

  1. “click” :是事件名;注意,要去掉事件名的on
  2. fun:是函数名; 注意,函数名上没有双引号
  3. 第三个参数是否使用捕捉(反向冒泡),默认false,为冒泡。

可以绑定多个函数在一个对象上,执行顺序按照绑定的顺序来

document.getElementById("myBtn1").addEventListener("click",myfun1,false);

当绑定的函数有参数时,当传递参数值时,使用"匿名函数"调用带参数的函数:

document.getElementById("myBtn").addEventListener("click", function() {
    myFunction(p1, p2);
});

8.2 移除事件监听器

removeEventListener() 方法移除由 addEventListener() 方法添加的事件函数:

document.getElementById("myBtn1").removeEventListener("click",myfun1);

(1)如果对一个按钮重复添加点击事件,会进行覆盖,使用事件监听器不会覆盖,并且如果点击事件后又写了100行代码,想要给该按钮该事件继续添加功能,无需找到按钮对应的函数位置,直接添加事件监听器即可(因为事件监听器不会被覆盖,都可以执行)。
(2)如果一个事件上有多个函数,要删除某一事件的函数,传统事件绑定只会将事件由原来的函数设置为null,按钮上原本的点击事件也会被设置为null。使用事件监听器,可以移除指定的事件的函数。
(3)事件捕获:从外向里触发,事件冒泡:从里向外出发

1、传统事件绑定
	<1>重复添加,覆盖
	<2>不能精确的删除事件上的某一个函数
2、事件监听器(低版本IE浏览器下不兼容)
	addEventListener()
		格式:node.addEventListener("click")
		参数:
			 第一个参数  事件类型
			 第二个参数  绑定函数
			 第三个参数  布尔值  true  事件捕获
					     		 false 事件冒泡  默认
	removeEventListener()
		格式:node.removeEventListener
		参数:
			第一个参数  事件类型
			第二个参数  删除函数名字

8.3 事件监听器兼容

IE 实现了与 DOM 中类似的两个方法:attachEvent()和 detachEvent()。这两个方法接受相同的参数:事件名称和函数

//跨浏览器添加事件
function addEvent(obj, type, fn) {//btn,click,show
	if (obj.addEventListener) {
		obj.addEventListener(type, fn, false);
	} else if (obj.attachEvent) {
		obj.attachEvent('on' + type, fn);
	}
}
//跨浏览器移除事件
function removeEvent(obj, type, fn) {
	if (obj.removeEventListener) {
		obj.removeEventListener(type, fn, false);
	} else if (obj.detachEvent) {
		obj.detachEvent('on' + type, fn);
	}
}

九、事件委托

onclick,onmouseover,onmouseout等是事件,委托就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。
也就是:利用冒泡的原理,把事件加到父级上,触发执行效果。

事件委托最强王者法则:

  1. 找到当前要添加事件的元素节点的父级或者祖父节点
  2. 将事件绑定在父一级的标签
  3. 找出触发该事件的对象(target,不能用this),进行判断
var oUl = document.getElementById("ul1");
	oUl.onclick = function(ev){
		var e = ev || window.event;
		var target = e.target || window.event.srcElement;
		if(target.nodeName.toLowerCase() == "li"){
			target.style.backgroundColor = 'red';
		}
	}
	var obtn = document.getElementById("btn1");
	var i = 6;
	obtn.onclick = function(){
		var newNode = document.createElement("li");
		newNode.innerHTML = i++ * 1111;
		oUl.appendChild(newNode);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值