javascript事件(二)

一.事件函数的取消
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();
}

这样也可以达到和阻止默认事件一样的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值