您的位置:首页 > Web前端 > JavaScript

Javascript事件详解

2016-04-06 22:44 525 查看
想要清楚的对javascript的事件有一个详细的了解,我们必须搞明白以下几件事情:

首先,必须明白以下几个概念

什么是事件? 什么是事件处理程序? 事件类型有哪些?事件流?事件冒泡?事件捕获?事件对象? 常见浏览器兼容问题怎么解决?

事件的概念

javas使我们有能力创建动态页面,事件是可以被浏览器侦测到的行为,比方说,我们可以在用户点击某一个按钮的时候产生一个onclick来触发某个函数,常见的事件有click,load,unload等

事件处理程序

响应某个事件的函数则称为事件处理程序,或者叫做事件侦听器。

click、mousemove、load等都是事件的名称,事件处理程序就是在事件的前面加上“on”,click事件的事件处理程序为onclick。

事件类型

1.鼠标事件

- click:单击

- dbclick:双击

- mousedown:当用户鼠标还未弹起触发

- mouseup:当用户释放按钮时触发

- mouseover:当鼠标移到某个元素上方时触发

- mouseout:当离开元素上方时触发

- mousemove:当鼠标指针元素时触发

2.键盘事件

- keydown:当用户按键盘上任意键触发

- keypress:当用户按键盘上的字符键触发

- keyup:当用户释放键盘上的键触发

3.HTML事件

- load:当整个页面加载完成

- unload:当页面完全卸载后在window上面触发,或在框架集卸载后在框架集上触发

- select:当用户选择文本框(input/textarea)中的一个或多个字符事触发

- change:当文本框(input/textarea)内容且焦点后触发

- focus:当页面或元素焦点后在window及相关元素上触发

- blur:当页面或元素失去焦点时在window及相关元素上触发

- submit:当用户点击提交按钮时在form上触发

- reset:当用户点击重置按钮时在form上触发

- resize:当窗口或框架的大小发生变化时在window或框架上触发

- scroll:当用户滚动带滚动条的元素时触发

4.滚轮事件:mousewheel(IE6+均支持)、DOMMouseScroll(Firefox支持的,与mousewheel效果一样)。是使用鼠标滚轮时触发的。

事件流

事件流描述的是从页面中接收事件的顺序,对于事件流,IE与NetScape提出了完全相反的顺序,IE提出的是事件冒泡流,即事件开始的时候由最具体的接收,逐级向上传播较为不具体节点;网提出的时间捕获流,即事件由最不具体的开始接收,然后逐级向下传播到最具体的节点

window.onload= function(){
document.onclick=function(){
alert('document');
}
document.documentElement.onclick = function(){    //documentElement 属性可返回文档的根节点。
alert('html');
}
document.body.onclick=function  () {
alert('body');
}
document.getElementById('box').onclick= function(){
alert('div');
}
document.getElementsByTagName('input')[0].onclick= function(evt){
alert('input');
//var e=evt||window.event;
//e.stopPropagation();  //W3C取消事件冒泡
//e.cancleBubble=true;    //IE取消事件冒泡
//alert(typeof  e.stopPropagation);
stop(evt);
}
}
//兼容(取消事件冒泡)
function stop(evt){
var e=evt||window.event;
if (typeof e.stopPropagation=='function') {
e.stopPropagation();
}else{
e.cancleBubble=true;
}

}


事件对象

在触发DOM上的某个事件的时候,会产生一个事件对象event,而在这个对象中包含着所有与事件有关的信息,其中有两个信息是我们最常用,分别是type和target,type表示的被触发事件的类型,target表示的是事件的目标

//支持的DOM的浏览器可以直接获取event;IE通过window.event获取
document.onclick = function(evt){
//var e=event||window.event;   //跨浏览器获取event
// alert(e.type) //click
alert(getTarget(evt));
}

//跨浏览器获取event目标
function getTarget(evt){
var e = event||window.event;
return e.target||e.srcElement;
}


事件绑定

1.传统事件绑定(包括内联模型和脚本模型)

脚本模型

//问题一:会覆盖
window.onload = function(){
alert('li');  //被覆盖了
}
window.onload=function(){
alert('lii');    //前者被覆盖了 打印出lii
}

----------

解决覆盖问题
//alert(typeof window.onload);  //一开始没有注册window.onload  那么就是null
window.onload = function(){
alert('li');  //被覆盖了
}
if (typeof window.onload=='function') { //判断是否存在上一个事件
var saved=null;
saved = window.onload;    //保存上一个事件对象
};
//alert(typeof window.onload);  //如果已经有window.onload 那么返回的就是一个函数 所以可以进行判断
window.onload=function(){
if(saved)saved();    //执行上一个事件window.onload=function(){};
alert('meiling');  //执行本事件
}


2.现代事件绑定(DOM2级模型)

//W3C自带的两个添加事件和删除事件
//1.解决覆盖问题
window.addEventListener('load',function(){
alert('lee');
},false)  //lee

window.addEventListener('load',function(){
alert('le');  //le
},false)


//解决相同函数屏蔽的问题
window.addEventListener('load',init,false);
window.addEventListener('load',init,false);
window.addEventListener('load',init,false);
function init(){
alert('lee');     //只会弹出一个lee
}


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="script.js"></script>
<style type="text/css">
.red{
width: 100px;
height: 100px;
background-color: red;
}

.blue{
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="box" class="red">测试</div>
</body>
</html>
//3.是否可以传递this(可以传递)
//js部分
window.addEventListener('load',function(){
var box = document.getElementById('box');
box.addEventListener('click',toBlue,false);
},false);

function toRed(){
this.className='red';
this.removeEventListener('click',toRed,false)
this.addEventListener('click',toBlue,false);
}
function toBlue(){
this.className='blue';
this.removeEventListener('click',toBlue,false)
this.addEventListener('click',toRed,false);
}


//4.添加一个额外的方法会不会被覆盖,或者只能执行一次
window.addEventListener('load',function(){
var box = document.getElementById('box');
box.addEventListener('click',function(){
alert('lee');
},false);
box.addEventListener('click',toBlue,false);
},false);

function toRed(){
this.className='red';
this.removeEventListener('click',toRed,false)
this.addEventListener('click',toBlue,false);
}
function toBlue(){
this.className='blue';
this.removeEventListener('click',toBlue,false)
this.addEventListener('click',toRed,false);
}


IE事件处理函数

//IE事件处理函数 attachEvent() detachEvent()
//ie不支持捕获,只支持冒泡, ie添加事件不能屏蔽重复的函数, ie中的this指向的是window而不是DOM对象
//1.覆盖问题 ,解决了 但有不同 ,顺序不同 倒过来的
window.attachEvent('onload',function(){
alert('leee');
})
window.attachEvent('onload',function(){
alert('lee');
})
window.attachEvent('onload',function(){
alert('le');
})

//2.相同函数屏蔽的问题  未解决 无法屏蔽
window.attachEvent('onload',init);
window.attachEvent('onload',init);
function init(){
alert('lee');   //弹出两个lee
}

//3.是否可以传递this
window.attachEvent('onload',function(){
var box = document.getElementById('box');
box.attachEvent('onclick',function(){
// alert(this===box);  //false
alert(this===window);  //不能传递this   true
})
})

// 4.添加一个额外的方法会不会被覆盖,或者只能执行一次   解决了
window.attachEvent('onload',function(){
var box = document.getElementById('box');
box.attachEvent('onclick',function(){
alert('lee');
});
box.attachEvent('onclick',function(){
alert('le');
});
})


IE和w3c兼容事件切换器

//跨浏览器添加事件
function addEvent(obj,type,fn){
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);
}
}

//跨浏览器获取目标对象
function getTarget(evt){
if (evt.target) {    //w3c
return evt.target;
}else if(window.event.srcElement){  //IE
return window.event.srcElement;
}
}

addEvent(window,'load',function(){
var box  = document.getElementById('box');
addEvent(box,'click',toBlue);
})

function toRed(evt){
var that = getTarget(evt);
that.className='red';
removeEvent(that,'click',toRed);
addEvent(that,'click',toBlue);
}
function toBlue(evt){
var that = getTarget(evt);
that.className='blue';
removeEvent(that,'click',toBlue);
addEvent(that,'click',toRed);
}


其它

//跨浏览器添加事件
function addEvent(obj,type,fn){
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);
}
}

//兼容 阻止默认行为
function preDef(evt){
var e =evt||window.event;
if (e.preventDefault) {

e.preventDefault();
}else {
e.returnValue = false;
}
}
//上下文菜单事件:contextmenu(很常用) ,当我们右击网页的时候会出现windows自带的菜单
//那么我们可以使用contextmenu事件来修改我们指定的菜单,但前提是把右击的默认行为取消掉
addEvent(window,'load',function(){
var text =  document.getElementById('text');
addEvent(text,'contextmenu',function(evt){
preDef(evt);
var menu = document.getElementById('menu');
var e =evt||window.event;
menu.style.left=e.clientX+'px';   //得到鼠标的坐标
menu.style.top=e.clientY+'px';
menu.style.display='block';

addEvent(document,'click',function(){
menu.style.display='none';
})
})
})


//卸载前事件beforeunload,这个事件可以在帮助离开本页时给出相应的提示,‘离开’或‘返回’操作
addEvent(window,'beforeunload',function(evt){
preDef(evt);
})
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: