事件注册:
js事件常用的注册方式
一、 dom.onxxxx=function(){},给dom队形的onxxxx属性绑定句柄,这种方式只能绑定一种方法,如果绑定多个则采用第二种
二、 dom.addEventListener(type,listener,userCapture),参数type:“click”,“dbclick”等事件 ;listener是function函数或者EventListener接口,capture参数是否使用捕捉,一般设置false (ie11,ff,chrome均支持,据说ie678不支持这种写法,而是dom.attachEvent(type,listener)种写法,type则是“onclick”这种写法,删除用dom.detachEvent(type,listener),可能是低版本的不支持,待测试 ),删除则用dom.removeEventListener(type,listener,userCapture)
window.onload=function(){
var img = document.getElementById("source");
// img.attachEvent("onclick",click); ie11 ff chorme均不支持
// img.attachEvent("onmouseover",mouseover);
img.addEventListener("click",click,false);
img.addEventListener("click",mouseover,false);
}
执行顺序先执行click方法,再执行mouseover方法 ,如果是attacheEvent,则执行顺序相反。实际中可以先dom.addEventListener去判断。
js获取事件对象和事件源
获取事件对象:除了ff之外,均可以使用window.event/event,ff使用arguments[0],所以使用的时候传递一个参数
获取事件源:用获取的事件对象.target/srcElement ff下是target ,srcElement是其他浏览器下,target在其他浏览器下也能用
function tt(){
//console.log("click");
//alert(arguments.callee);
var e = arguments[0] || window.event; //本例中没有参数传递,如果写成<div onclick="tt()">test</div> ff会出错,但是如果用addEventListener("click",tt,false);不传参这种形式注册不会报错 这种注册方式是建议的
//需要用到此参数的最好传递一形参 如:function tt(e)
var target = e.target || e.srcElement; //只用target也可以,其他浏览器都支持
alert(target);
}
function click(){
//console.log("click");
//alert(arguments.callee);
alert(event.type);//弹出click
}
ff可以用arguments[0]获取,ie和chrome同样可以如此获取
注意:当把js代码写在html中例如<div onclick="alert(event.type);">Div1 Element</div> 这时发现ff中居然可以弹出提示框了
但是这种把js代码直接写在html标签中,已经很少人会用了。
那么看下面的写法:onxxx=方法名()
function tt(){
//console.log("click");
//alert(arguments.callee);
alert(event.type);//event不可用
}
<img src="dir.jpg" style="width:50px;height:50px;" id="source" onclick="tt();" draggable="true" ondragstart="dragstart(event)"/>
发现ff下event依然不可用。如果习惯这样注册函数,可以通过参数传入event onclick=”tt(event)“,这样在函数中就可以用了。
那么通过这行代码调用事件的原函数
<img src="dir.jpg" style="width:50px;height:50px;" id="source" onclick="alert(arguments.callee);" />
ie,ff,chrome打印结果如下:
function onclick(event){
alert(arguments.callee);
}
发现onclick是有参数event传入的,但是ff仍然不能用此参数,原因不详。
总结下:
1,IE6/7/8支持通过window.event获取对象,通过attachEvent方式添加事件时也支持事件对象作为句柄第一个参数传入
2,Firefox只支持事件对象作为句柄第一个参数传入
3,IE9/Opera/Safari/Chrome两种方式都支持
取消默认行为
function eventHandler(e) {
e = e || window.event;
var target = e.srcElement || e.target;
// 防止默认行为
if (e.preventDefault) {
e.preventDefault();//IE以外
} else {
e.returnValue = false;//IE
//注意:这个地方是无法用return false代替的
//return false只能取消元素
}
}
获取事件对象需传参,获取事件源用target,阻止默认行为preventDefault,当然为了更好兼容性,写成上面的例子形式更好
阻止事件冒泡
function myParagraphEventHandler(e) {
e = e || window.event;
if (e.stopPropagation) {
e.stopPropagation();//IE以外
} else {
e.cancelBubble = true;//IE
}
}
事件委托
依赖于事件冒泡,如果事件冒泡被阻止,下面代码将无法工作
myTable.onclick = function () {
e = e || window.event;
var targetNode = e.target || e.srcElement;
// 测试如果点击的是TR就触发
if (targetNode.nodeName.toLowerCase() === 'tr') {
alert('You clicked a table row!');
}
}