一.事件函数的取消
1.第一种事件绑定形式的取消,如:
function fn1(){
alert(1);
}
document.onclick = fn1;
document.onclick = null; //取消点击事件
2.第二种事件绑定形式的取消:
IE浏览器下:
obj.detachEvent(事件名称,事件函数);
标准浏览器下:
obj.removeEventListener(事件名称,事件函数,是否捕获);
综上,类似于事件绑定,事件取消也存在浏览器兼容性问题。下面将事件绑定和事件取消的函数封装如下:
<script>
function fn1(){
alert(1);
}
function fn2(){
alert(2);
}
function bind(obj,evname,fn,bl){
if(obj.addEventListener){
obj.addEventListener(evname,fn,bl)
}else{obj.attachEvent('on'+evname,fn,function(){
fn.call(obj);
})
}
}
function removBind(obj,evname,fn,bl){
if(obj.removeEventListener){
obj.removeEventListener(evname,fn,bl)
}else{obj.detachEvent('on'+evname,fn,function(){
fn.call(obj);
})
}
}
bind(document,'click',fn1,true);
bind(document,'click',fn1,false);
removBind(document,'click',fn1,false);
</script>
注意:如果分别有捕获和冒泡,也需要分别取消。
二.键盘事件
1.onkeydown
:当键盘按键按下时触发;
2.onkeyup
:当键盘按键抬起时触发;
注:不是所有按键按下时都执行同一事件,这时需要用到:event.keyCode,可以通过以下方法来判断一下当前按键的按值
document.onkeydown = function(ev){
var ev = ev||event;
alert(ev.keyCode);
}
3.event下还有ctrlKey,shiftKey,altKey,分别表示是否按下CTRL、SHIFT或ALT键,是布尔值
练习1 :做一个输入框和ul,每次输入完内容后,点击ctrl+回车变成留言
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
ul,li{list-style:none;}
</style>
</head>
<body>
<input id="input1" />
<ul id="ul1"></ul>
<script>
var oInput1=document.getElementById("input1");
var oUl1=document.getElementById("ul1");
oInput1.onkeyup=function(ev){
var ev=ev||event;
if(ev.keyCode==13&&oInput1.value!=''&&ev.ctrlKey){
var oLi=document.createElement("li");
oLi.innerHTML+=oInput1.value;
oUl1.appendChild(oLi);
}
}
</script>
</body>
</html>
注意:
(1)只有能接受焦点的元素才能接收键盘事件,特殊document可以接收,不能直接给div加;
(2)按键事件在按下不抬起时会连续触发,但是连续触发前会有一个停顿。因此在做按住连续触发并且不想要停顿效果时,需要自己用计时器写连续方法。
练习3:写一个上下左右键盘控制div块移动的代码,可以实现按住连续触发且开始之前无停顿。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#box{width:100px; height:100px; background-color:red; position:absolute; left:100px; top:100px; z-index:5;}
#box1{width:500px; height:500px; background-color:green; position:absolute; left:100px; top:100px; z-index:3;}
</style>
</head>
<body>
<div id="box"></div>
<div id="box1"></div>
<script>
var oDiv=document.getElementById("box");
var oDiv1=document.getElementById("box1");
var timer=null;
var dire={left:false,top:false,right:false,bottom:false};
timer=setInterval(function(){
if(dire.left){
doMove(oDiv,'left',10,oDiv1.offsetLeft);
}
if(dire.top){
doMove(oDiv,'top',10,oDiv1.offsetTop);
}
if(dire.right){
doMove(oDiv,'left',10,oDiv1.offsetLeft+oDiv1.offsetWidth-oDiv.offsetWidth);
}
if(dire.bottom){
doMove(oDiv,'top',10,oDiv1.offsetTop+oDiv1.offsetHeight-oDiv.offsetHeight);
}
},50);
document.onkeydown=function(ev){
var ev = ev||event;
switch(ev.keyCode){
case 37:dire.left=true;break;
case 38:dire.top=true;break;
case 39:dire.right=true;break;
case 40:dire.bottom=true;break;
}
}
function doMove(id,derection,speed,subjectPosition){
if(derection=='left'){
speed=id.offsetLeft> subjectPosition? -speed : speed;
}
if(derection=='top'){
speed=id.offsetTop> subjectPosition? -speed : speed;
}
var nowPosition;
if(derection=='left'){
nowPosition =id.offsetLeft;
}
if(derection=='top'){
nowPosition =id.offsetTop;
}
var thisPosition=nowPosition+speed;
if(thisPosition>=subjectPosition&&speed>0||thisPosition<=subjectPosition&&speed<0){
thisPosition=subjectPosition;
clearInterval(id.timer);
}
id.style[derection]=thisPosition+'px';
}
document.onkeyup=function(){
dire={left:false,top:false,right:false,bottom:false};
}
</script>
</body>
</html>
三.事件默认行为
1.事件默认行为指的是:当一个事件发生时,浏览器默认会做的事情。比如在页面上单击右键时会有个菜单(oncontextmenu)默认显示出来;再比如鼠标按下时,如果有文字被选中,拖拽会变成复制;以及当键盘按下不抬起时想让按键事件连续触发,浏览器总是会停顿一下再紧接着持续执行事件,这时候就要用计时器来解决这一问题。
2.有些时候我们不想让浏览器执行默认行为,那么就需要阻止默认行为。但是阻止默认行为时应该搞清楚两件事情:
A.当前这个行为是什么事件触发;
B.在这个事件处理函数中使用 return false来组织默认事件的发生。
练习4:做一个自定义的默认菜单(把原本右键的默认事件取消),这个菜单要求和原本右键菜单一样(内容是个框)
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
body{margin:0; height:2000px;}
</style>
</head>
<body>
<script>
var oDiv=document.createElement("div");
document.body.appendChild(oDiv);
document.oncontextmenu = function(ev){
var ev = ev || event;
var x=document.body.scrollLeft ||document.documentElement.scrollLeft;
var y=document.body.scrollTop ||document.documentElement.scrollTop
oDiv.style.cssText="width:200px;height:400px;border:1px #000 solid; position:absolute;";
oDiv.style.left=ev.clientX+x +'px';
oDiv.style.top=ev.clientY+y +'px';
return false;
}
document.onclick=function(){
oDiv.style.display='none';
}
</script>
</body>
</html>
练习5:鼠标按下时,如果有文字被选中,拖拽会变成复制(浏览器默认行为),这时就会出现冲突,请避免该冲突:
A.标准浏览器下:
需要在onmousedown阻止默认行为来防止(非标准浏览器下无效)。
B.IE下:
IE浏览器里有个全局捕获(和事件流里面的捕获不同)。全局捕获的意思是当有其他元素执行一个事件时劫持该事件,在释放元素时需要把全局捕获也释放。
//全局捕获劫持事件
if(元素.setCapture){
元素.setCapture();
}
...
//释放元素时释放全局捕获
if(元素.releaseCapture){
元素.releaseCapture();
}
这样也可以达到和阻止默认事件一样的效果。