1. 事件监听
为 HTML 页面指定标签绑定指定事件,可以通过以下三种方式实现:
- HTML 标签的事件属性: 这种方式 HTML 代码和 JavaScript 逻辑不能很好地分离,所以不建议使用。
- DOM 标准的事件: 这种方式只能为指定的一个标签绑定一个事件,并且只能具有一个事件处理函数。
- 事件监听器: 这种方式是目前最受欢迎的一种方式。**但 IE 8 及之前的版本不支持!**
1.1 事件监听器
DOM 提供了事件监听器,可以同时绑定多个事件,并且具有多个事件处理函数。具体监听器语法如下:
element.addEventListener(eventName, functionName, boolean);
该方法的参数说明如下:
参数 | 说明 |
---|---|
eventName | 为元素指定具体的事件名称(例如单击事件是 click 等) |
functionName | 绑定事件的处理函数 |
boolean | 设置事件是捕获阶段还是冒泡阶段。为 false 时为冒泡阶段,一般都是这个值 //此参数可省略 |
我们可以通过以下代码进行学习:(addEventListener() 方法可以为指定一个元素绑定一个事件同时具有多个处理函数。)
var btn=document.getElementById('btn');
function alertTest(){
alert("哒哒哒")
};
function alertTest2(){
alert("哒哒哒2")
};
btn.addEventListener("click",alertTest,false)
btn.addEventListener("click",alertTest2);
1.2 IE 8 及之前的监听器
IE 8 及之前的版本浏览器并不支持 addEventListener() 方法,而提供了如下方法实现:
element.attachEvent(eventName, functionName)
该方法的参数说明如下:
参数 | 说明 |
---|---|
eventName | 为元素指定具体的事件名称(例如单击事件是 onclick 等) |
functionName | 绑定事件的处理函数 |
值得注意的是: attachEvent() 方法的 eventName 参数与 addEventListener() 方法的 eventName 参数不同。
var btn = document.getElementById('btn');
btn.attachEvent('onclick',function(){
console.log('你终于点中了我...');
});
1.3 监听器的兼容方案
我们可以封装一个函数专门来解决事件监听器的浏览器之间兼容问题。具体代码示例如下:
function bind(elem, event, functionName){
// 判断是否存在 addEventListener
if (elem.addEventListener){
elem.addEventListener(event, functionName, false);
}else{
elem.attachEvent('on' + event, functionName);
}
}
1.4 事件中的 this
在事件的处理函数中,可以通过 this 关键字来指代绑定该事件的标签。
var btn=document.getElementById('btn');
btn.addEventListener("click",function () {
console.log(this);
// <button id="btn" class="btn btn-primary">事件监听器</button>
console.log(btn.textContent); // 事件监听器
},false)
上述代码可以使用 this 关键字进行改写:
btn.addEventListener("click",function () {
console.log(this.textContent); // 事件监听器
},false)
通过 attachEvent() 方法为 HTML 页面的标签绑定事件时,this 关键字指代绑定 window 对象。
var btn=document.getElementById('btn');
btn.attachEvent("onclick",function () {
console.log(btn);
console.log(this);// window对象
});
由于在 addEventListener() 方法中的 this 和在 attachEvent() 方法中的 this 指代不同,我们需要进一步优化我们的兼容方案。
var btn=document.getElementById('btn');
function callBack() {
console.log("bind");
console.log(this);
}
bind2(btn,"click",callBack);
function bind(elem,eventName,functionName) {
if (elem.addEventListener) {
elem.addEventListener(eventName,functionName,false);
}else{
elem.attachEvent("on"+eventName,function () {
functionName.call(elem);
// call(this)函数有一个形参this,传递实参是什么,this就代指什么
},false);
}
}
2. 事件对象
HTML 页面的标签绑定事件的处理函数中,提供了一个事件对象(event)。这个事件对象会返回关于该事件的信息,以及该事件绑定在哪个元素中。事件对象是以事件的处理函数中的参数形式出现,并不需要我们自己创建,直接使用即可。
<button id="btn" class="btn btn-primary">事件对象</button>
<script type="text/javascript">
var btn=document.getElementById("btn");
function fn(event){
console.log(event);
}
btn.addEventListener("click",fn,false);
输出的时间对象event:
2.1 兼容的事件对象
使用 DOM 标准的事件绑定时,Event 事件对象在 IE 8 及之前的版本浏览器情况有所不同。
- IE 9 及之后的版本和其他浏览器: 通过事件的处理函数的形参直接得到 Event 对象。
var btn = document.getElementById('btn');
btn.onclick = function(event){
console.log(event)
}
- IE 8 及之前的版本浏览器: Event 事件对象被提供在 window 对象中。
var btn = document.getElementById('btn');
btn.onclick = function(event){
console.log(window.event)
}
想要实现 Event 事件对象的兼容,我们可以在事件的处理函数中添加以下代码:
event = event || window.event;
2.2 事件的目标元素
Event 事件对象提供了 target 属性用于获取触发事件的目标元素(标签)。
我们可以通过以下案例进行学习 target 属性:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>事件的目标元素</title>
<style type="text/css">
body {
padding: 100px;
}
.list-group {
padding: 30px;
background-color: lightblue;
}
</style>
</head>
<body>
<ul id="ul" class="list-group">
<li class="list-group-item">
<a href="#">链接</a>
</li>
</ul>
<script type="text/javascript">
var ul=document.getElementById('ul');
ul.addEventListener('click',function (event) {
console.log(event.target);
})
</script>
</body>
</html>
如果点击 <a>
标签,target 属性则打印 <a>
标签:
<a href="#">链接</a>
如果点击 <li>
标签,target 属性则打印 <li>
标签:
<li class="list-group-item">
<a href="#">链接</a>
</li>
如果点击 <ul>
标签,target 属性则打印 <ul>
标签:
<ul id="ul" class="list-group">
<li class="list-group-item">
<a href="#">链接</a>
</li>
</ul>
IE 8 及之前的目标元素
IE 8 及之前的版本浏览器不支持 target 属性,而是提供了 srcElement 属性进行替换。所以,上述示例代码在 IE 8 及之前的版本浏览器中,应该是如下代码:
var ul = document.getElementById('ul');
ul.attachEvent('onclick',function(event){
console.log(event.srcElement)
});
2.3 阻止默认行为
HTML 页面的一些标签具有默认行为。所谓默认行为,就是不用编写 JavaScript 代码就可以实现的动态效果。例如下标签:
<a>
标签: 用户点击<a>
标签,会发生页面跳转行为。<form>
标签: 用户点击表单的提交按钮,表单会发生提交行为。
阻止默认行为,就是不让 HTML 页面这些标签的默认行为发生。想要阻止默认行为可以通过 Event 事件对象提供的属性实现:
- IE 9 及之后版本和其他浏览器: preventDefault() 方法
- IE 8 及之前版本的浏览器: returnValue 属性
使用方法:
IE 9 及之后版本和其他浏览器: preventDefault() 方法
<a class="btn btn-link" id="a" href="test.html">链接</a>
<script type="text/javascript">
var a=document.getElementById('a');
a.addEventListener("click",function (event) {
console.log("aa")// aa
event.preventDefault();
console.log("bb")// bb
// 默认阻止行为不影响处理函数中的逻辑
})
</script>
addEventListener方法中使用“return false”,不能阻止默认跳转
<a class="btn btn-link" id="a" href="test.html">链接</a>
<script type="text/javascript">
var a=document.getElementById('a');
a.addEventListener("click",function (event) {
alert("aa");// 执行
return false;
alert("bb");// 不执行
})
</script>
“return false”只有在 onclick 方式绑定事件有效
<a class="btn btn-link" id="a" href="test.html">链接</a>
<script type="text/javascript">
var a=document.getElementById('a');
a.onclick=function () {
alert("aa");//代码执行
return false;// 成功阻止默认行为
alert("bb");//代码不执行
}
</script>
IE 8 及之前版本的浏览器: returnValue 属性
a.onclick=function (event) {
alert("aa1");//代码执行
event.returnValue=false;// 成功阻止默认行为
alert("bb2");//代码执行
}
2.4 获取鼠标坐标
当 HTML 页面中标签绑定的事件被触发时,我们还可以通过 Event 事件对象获取鼠标当前的坐标值。
- pageX 和 pageY: 表示鼠标在整个页面(HTML)中的位置。如果页面过大(存在滚动条),部分页面可能存在可视区域之外。
- clientX 和 clientY: 表示鼠标在整个可视区域中的位置。
- screenX 和 screenY: 表示鼠标在整个屏幕中的位置。从屏幕(不是浏览器)的左上角开始计算。
- offsetX 和 offsetY: 表示鼠标相对于当前元素的(相对)位置。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>获取鼠标坐标</title>
<link rel="stylesheet" href="css/06.css">
<style>
body {
height: 1000px;
}
</style>
</head>
<body id="body">
<div id="stats">
screenX: <input type="text" id="sx" />
screenY: <input type="text" id="sy" /><span class="divider">|</span>
pageX: <input type="text" id="px" />
pageY: <input type="text" id="py" /><span class="divider">|</span>
clientX: <input type="text" id="cx" />
clientY: <input type="text" id="cy" />
</div>
<div>
<img src="" alt="">
</div>
<script>
var sx = document.getElementById('sx');
var sy = document.getElementById('sy');
var px = document.getElementById('px');
var py = document.getElementById('py');
var cx = document.getElementById('cx');
var cy = document.getElementById('cy');
function showPosition(event) {
sx.value = event.screenX;
sy.value = event.screenY;
px.value = event.pageX;
py.value = event.pageY;
cx.value = event.clientX;
cy.value = event.clientY;
}
var el = document.getElementById('body');
el.addEventListener('mousemove', showPosition, false);
</script>
</body>
</html>
offsetX 和 offsetY