一、事件的添加方式
on的方式:此方法给同一元素绑定两次事件,前面的事件会被覆盖,事件处理机制为事件冒泡。
如:div.onclick = function(){};
addEventListener('click', function(){}, true):此方法不会发生覆盖的情况,不兼容IE/6/7/8。
第一个参数为事件,第二个参数为函数,第三个参数false为冒泡的方式,true为下沉的方式。
事件移除:
div.onclick = null;
div.removeEventListener("click", function(){});
二、事件处理机制
1、事件冒泡:一个标签处理完事件之后,它的父元素、父元素的父元素也会处理该事件。如下面代码我们点击紫色区域时,控制台会依次打印1、2、3、4也就是说该事件,从紫色到蓝色、青色、黄色区域依次处理该事件,这种事件处理方式就叫事件冒泡。
2、事件下沉:一个标签处理完事件之后,它的子元素、子元素的子元素也会处理该事件,如下面代码我们点击黄色区域时,控制台会依次打印4、3、2、1也就是说该事件,从黄色到青色、蓝色、紫色区域依次处理该事件,这种事件处理方式就叫事件下沉,也称事件捕获。
3、阻止事件冒泡和下沉:
- event.cancelBubble = true;
只能阻止on的方式和addEventListener()冒泡的方式。 - event.stopPropagation();
两种方式冒泡和下沉的方式都能阻止。
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].index = divs.length - i;
// on的方式绑定事件
// divs[i].onclick = function (e) {
//
// var ev = e || window.event;
// // ev.stopPropagation(); // 阻止事件冒泡
// // ev.cancelBubble = true;
//
// console.log(this.index);
// };
// addEventListener()绑定事件
divs[i].addEventListener('click', function (e) {
var ev = e || window.event;
// ev.stopPropagation(); // 阻止事件传递
ev.cancelBubble = true; // 阻止冒泡。不阻止下沉
console.log(this.index);
}, false);
}
三、事件代理(委托)
事件代理在JS世界中一个非常有用也很有趣的功能。当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。这主要得益于浏览器的事件冒泡机制。
假设有一个 UL 的父节点,包含了很多个 Li 的子节点:
<ul id="container">
<li>列表 1 <span>我是span <i>iiiiiii</i></span></li>
<li>列表 2</li>
<li>列表 3</li>
<li>列表 4</li>
<li>列表 5</li>
</ul>
当我们的鼠标移到Li上的时候,需要获取此Li的相关信息并飘出悬浮窗以显示详细信息,或者当某个Li被点击的时候需要触发相应的处理事件。我们通常的写法,是为每个Li都添加一些类似onMouseOver或者onClick之类的事件监听。
如果这个UL中的Li子元素会频繁地添加或者删除,我们就需要在每次都给新建的子节点添加事件处理函数。这就添加的复杂度和出错的可能性。
更简单的方法是使用事件代理机制,当事件被抛到更上层的父节点的时候,我们通过检查事件的目标对象(target)来判断并获取事件源Li。下面的代码可以完成我们想要的效果:
var container = document.getElementById("container");;
var lis = container.querySelectorAll("li");
container.onclick = function (e) {
var ev = e || window.event;
var eventSource = ev.target; // target代表事件源
if (eventSource.tagName == "LI") { // tagName可以获取标签名,大写
var newLi = document.createElement("li");
newLi.innerHTML = ev.target.innerHTML;
container.appendChild(newLi);
}
};
上面的代码我们实现的效果就是,我们点击任意li都会在列表末尾创建一个完全一样的li,我们将事件委托给container,那么不管我们对li做何种操作,都将由container来执行。故事件委托我们也可以简单的理解为,应该自己做的事,我们交给别人去做。
四、事件对象
1、获取对象:
Chrome和IE 直接写event;
Firefox 需要填写参数名称,任意参数皆可;
一般我们传参数e,并做以下判断 var ev = e || window.event;
2、获取点击的位置:
ev.clientX 获取相对于浏览器窗口的x轴坐标;
ev.clientY 获取相对于浏览器窗口的y轴坐标;
document.onclick = function(e) {
var ev = e || window.event;
// 获取相对于浏览器窗口的坐标
console.log(ev.clientX, ev.clientY);
}
ev.offsetX 相对于自身的x轴坐标;
ev.offsetY 想对与自身的y轴坐标;
注意这两种属性是非标准属性。
screenX相对于屏幕的x轴坐标;
screenY相对于屏幕的y轴坐标;
建议在移动端使用。
五、表单事件
1、onsubmit提交事件
注意:提交事件是给表单的,而不是给表单元素的。
2、阻止默认事件
通过return false;只能阻止on的方式添加的事件。
ev.preventDefault(); 阻止默认事件,不兼容IE6/7/8,也可以阻止on的方式。
如下代码:
我们如果不阻止默认事件,点击提交按钮会直接跳转百度首页,阻止默认事件后只能在控制台打印一排a。我们用两种方式来绑定事件,注意这两种阻止默认事件方法的区别。
<body>
<form class="" action="http://www.baidu.com" method="get">
<input type="submit" value="提交">
</form>
</body>
<script type="text/javascript">
//获取元素
var form = document.querySelector('form');
//绑定提交事件
form.onsubmit = function (e) {
var ev = e || window.event;
ev.preventDefault(); // 阻止默认事件
console.log('aaaaaaaaaaaa');
// return false;
};
// addEventListener()的方式绑定事件
//绑定提交事件
// form.addEventListener('submit', function (e) {
// var ev = e || window.event;
// ev.preventDefault(); // 阻止默认事件
//
// console.log('aaaaaaaaaaa');
//
// }, false);
</script>
3、onfocus 当输入获取焦点时触发事件。
4、onblur 失去焦点时触发事件。
<body>
<p>请输入信息完成注册</p>
<span>昵称</span>
<input type="text" name="keyWord" value="请输入昵称" >
</body>
<script type="text/javascript">
window.onload = function() {
//获取元素
var keyWord = document.getElementsByName('keyWord')[0];
var p = document.querySelector('p');
// onfocus当输入获得焦点时触发该事件
keyWord.onfocus = function() {
keyWord.value = '';
p.style.color = '#000';
p.innerHTML = '请输入信息完成注册';
};
// onblur失去焦点时触发该事件
keyWord.onblur = function() {
keyWord.value = ' 请输入昵称';
p.innerHTML = '请将信息补充完整';
p.style.color = 'red';
};
}
</script>
5、onchange 输内容发生变化时触发事件。
6、onselect 输入内容被选中时触发事件。
7、onreset 表单中的重置按钮被点击时触发事件。
注意:onreset也是给表单的,而不是给表单元素。
当表单被清空时,div会被隐藏。
<body>
<form class="" action="" method="get">
<input type="text" name="name" value="">
<input type="reset" name="name" value="重置">
</form>
<div class=""></div>
</body>
<script type="text/javascript">
var form = document.querySelector("form");
var div = document.querySelector("div");
// onreset表单内容被清空时触发事件
form.onreset = function(e) {
var ev = e || window.event;
div.style.display = 'none';
}
div.style.display = 'block';
</script>
六、键盘事件
1、onkeypress 键盘按下并抬起
2、onkeydown 键盘按下
3、onkeyup 键盘抬起
属性
4、keyCode 获取唯一标识码
5、altKey 属性返回一个布尔值。指示在指定的事件发生时,检测Alt 键是否被按下并保持住了。
6、ctrlKey 属性返回一个布尔值。指示在指定的事件发生时,检测Ctrl 键是否被按下并保持住了。
7、shiftKey 属性返回一个布尔值。指示在指定的事件发生时,检测Shift键是否被按下并保持住了。
document.onclick = function (e) {
var ev = e || window.event;
if (ev.shiftKey) {
console.log('Shift键已被按下');
} else {
console.log('键盘没有按下');
}
}
七、鼠标事件
1、onclick 按下并抬起
2、ondblclick 双击事件
3、onmousedown 鼠标按下
4、onmouseup 鼠标抬起
5、onmousemove 鼠标移动
6、oncontextmenu 右击事件
7、onmouseover 鼠标划入
8、onmouseout 鼠标划出
9、onwheel 鼠标滚轮事件
10、DOMMouseScroll 鼠标滚轮事件,兼容火狐浏览器。
ev.wheelDelta 判断滚动方向,取值±120,正值向上,负值向下。
ev.detail 判断滚动方向,兼容火狐浏览器,正值向下负值向上。
// 判断当前浏览器
var ff = navigator.userAgent.indexOf("Firefox");
if (ff != -1) {
document.addEventListener("DOMMouseScroll", function (e) {
var ev = e || window.event;
if (ev.detail < 0) {
console.log('鼠标向上滚动');
} else {
console.log('鼠标向下滚动');
}
});
} else {
document.onwheel = function(e) {
var ev = e || window.event;
if (ev.wheelDelta > 0) {
console.log('鼠标向上滚动');
} else {
console.log('鼠标向下滚动');
}
}
}
八、window事件
1、onload 文档和图像视频等多媒体文件全部加载完成后调用
2、onresize 窗口大小发生变化时调用
3、onscroll 滚动条滚动时调用
九、移动端事件(touch)
只支持addEventListener()的方式绑定事件
1、touchstart 手指放到屏幕上的时候触发
2、touchmove 手指在屏幕上移动的时候触发
3、touchend 手指从屏幕上拿起的时候触发
touch事件的属性
1、clientX / clientY 触摸点相对于浏览器窗口viewport的位置
2、pageX / pageY 触摸点相对于页面的位置
3、screenX /screenY 触摸点相对于屏幕的位置
4、touches 当前位于屏幕上的所有手指的一个数组
5、targetTouches 位于当前DOM元素上的手指的一个数组
6、changedTouches 涉及当前事件的手指的一个数组
// 绑定手指按下事件
document.addEventListener('touchstart',function(e) {
var ev = e || window.event;
//获取第一个触点
var touch = ev.touches[0];
// 获取第一个触点的坐标
var start = {
x: touch.pageX,
y: touch.pageY
};
console.log(start.x, start.y);
});
以上内容,纯属个人理解,由于本人水平有限,若有错漏之处敬请指出斧正,小弟不胜感激。