JavaScript-Dom入门笔记-事件篇

事件

事件(Event)对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!

例如onload
onload这个事件会在页面加载完成后触发
当脚本写在标签里,可能会因为没有加载完成而无法获取对象,可以用window.onlock解决。
我们不提倡将后执行的代码写在上面,在网络不通畅时可能影响加载速度。

事件对象

当事件的响应函数触发时,浏览器会将严格事件对象作为实参传给响应函数。事件对象封装了事件的一切属性。
这是一个鼠标定位的例子。

<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
	
<head>
	<style type="text/css">
		#box{
            height: 100px;
            width: 100px;
            background-color: blue;
        }
	</style>
</head>
<body>
	<div id="box">
	</div>
    <script>
    window.onload = function ( ) {
        var box = document.getElementById("box");
        var body = document.getElementsByTagName("body")[0];
        var div =document.createElement("div");
        body.appendChild(div);
        box.onmousemove = function(event){//这里传入了事件
    	    	//var x =event.clientX;
    	    	//var y =event.clientY;
    	    	var x =window.event.clientX;
    	    	var y =window.event.clientY;
    	    	div.innerHTML="x"+x+"y"+y;
    	    	//鼠标在盒子里移动可以输出其坐标
    	  }
    }
</script>
</body>
    

</body>
</html>

:坏消息是ie8又双叒不兼容一般写法,event在ie8中被作为全局属性应写为window.event,比较好的消息是现在Chrome和FF现在也支持这种写法了我们不用再写event=event||window.event来解决兼容问题了。

事件流

在学会了事件后我为自己想了一个例子:点击拖动一个元素,松开鼠标放下元素。但因为涉及多个事件造成了混乱,那么事件的发生顺序是怎样的?
那我们来观察点击不同位置,下面五个事件的发生顺序,在实际运行前,不妨先猜测一下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box{
            background: yellow;
        }
        #box span{
            background: greenyellow;
        }
    </style>
</head>
<body>
<p>点击这里,这里是body</p>
    <div id="box">
        点击这里,这里是div
        <span>点击这里,这里是span</span>
    </div>
<script>
    var body = document.getElementsByTagName("body")[0];
    var box = document.getElementById("box");
    var span = box.getElementsByTagName("span")[0];
    window.onload = function () {
        body.onclick=function () {
            alert("body0");
        }//body的点击事件
        body.onclick=function () {
            alert("body1");
        }//body的点击事件,与上一个平级
        
        box.onclick = function () {
            alert("box");
        }//div的点击事件,div为body的子元素
        span.onclick = function() {
            alert("span");//span的点击事件,span是div的子元素
            span.onclick = function() {
                alert("span0");
            }//嵌套在第一个点击事件的点击事件
            
        }
    }
</script>
</body>
</html>

事件的传播

事件流是为解决事件的发生顺序而生,上古时期ie与网景(已经凉了)两家公司分别提出了冒泡捕获,后来w3c组织整合两者(虽说如此,ie8以下仍然不支持捕获)就是我们正在使用的事件流。
我在大佬那里找到了一张比较清晰的图,来表示事件流的阶段
1. 捕获阶段 由外向内
2.目标阶段 事件到达目标,触发,逆向回流
3. 冒泡阶段 由内向外
事件流

事件的等级level也影响事件的顺序,事件分为三个等级即:level 0 level 2 level 3
默认等级为level 0,这个等级不支持捕获,而且因为ie8以下不支持捕获,所以level 0是我们主要使用的等级。

在上面的例子中,我们点击最内侧的span。事件的发生顺序为:span》box》body1 。点击事件由span传递给div,然后向上传递给body,同样冒泡是可以取消的。

event.cancelBubble=ture;
//取消冒泡,取消冒泡不是仅针对当前事件,而是让泡泡在当前位置消失
//当然这个事件本身还是能产泡泡的

让我们再重复一下level 0的特点:
1.不支持捕获,只支持冒泡
2.一个元素只能绑定一个事件(最后一个事件)
3.事件可以解除绑定

 box.onmousemove=null;
//将事件设置为空就可以解除事件

冒泡的特点: 相同事件的发生是由内而外的

现在来完成我们的例子

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">

    <head>
        <style type="text/css">
            #box{
                height: 100px;
                width: 100px;
                background-color: blue;
                        position: absolute;
            }
        </style>

    </head>
    <body>
        <p>拖动方块</p>
        <div id="box"></div>

        <script>
        window.onload = function ( ) {

            var body = document.getElementsByTagName("body")[0];
            var div =document.createElement("div");
            body.appendChild(div);
            var box = document.getElementById("box");

            box.onmousemove = function(event){
                var x =window.event.clientX;
                var y =window.event.clientY;
                div.innerHTML="当前坐标:x="+x+"y="+y;
            }

            box.onmousedown=function(){//鼠标按下,mousedown是瞬时的行为,你不能仅靠她来完成拖动,只能点一下动一动
                document.onmousemove= function (event) {//绑定移动
                    move(event);//我们把移动事件给全局防止鼠标跑的太快事件脱离
                }
            }

            box.onmouseup=function () {//鼠标弹起
                document.onmousemove=null;//解除move的绑定
            }
            function  move(event) {//方法--用于移动方块
                var x =window.event.clientX;
                var y =window.event.clientY;

                box.style.left = x-box.scrollHeight/2+"px";
                box.style.top = y-box.scrollWidth/2+"px";


            }


        }
        </script>
    </body>
</html>

事件委派

之前我们对一系列于单击相应函数采用遍历的方法绑定,这种方法麻烦而且效率低下; 当事件的祖先被绑定单击相应函数,他的子元素会不触发这个函数?会的,因为冒泡的存在。
利用冒泡将事件绑定给祖先元素,减少绑定次数叫做事件的委派。
但先别高兴太早,如果单纯的将事件绑定给祖先元素那么范围是不是太大了?所以我们要让我们所期望的事件触发事件,那什么可以帮助我们呢?Event手册
target 返回触发此事件的元素(事件的目标节点)。

if(window.event.target.className=="link"){//只有class为link的元素才能触发事件
            del();
        }

监听器

我们之前说过,事件等级level 0只支持绑定一个事件,但有的时候一个事件确实不够用。这时候我们就要用到level 2 (但请不要忘记ie 8不兼容)
我们先来认识一下监听器
addEventListener("事件字符串",function(){},false);
1.参数一为字符串;内容为零级响应事件去掉on前缀,比如onclick写为click
2.参数二为回调函数,就是事件触发时调用的
3.参数三是否在捕获阶段触发?我们一般不要这样做,所以写false
监听器的绑定不受数量限制,我们可以为相同事件绑定多个响应函数,同级事件按顺序执行。

对于ie 8 的兼容
attachEvent("onclick",function(){});
1.参数一,正常书写响应事件
2.参数二,回调函数
3.没有参数三,ie 8 不支持捕获
4.事件的执行顺序是自下向上
兼容性的解决思路与之前一样

window.onload=function () {
   bind(span,"click",log);
}
   function bind(obj,eventStr,callback) {
       if(obj.addEventListener){
           obj.addEventListener(eventStr,callback,false);
       }else {
           obj.attachEvent("on"+eventStr,callback);
       }
   }
   function log(){
       alert("span");
   }

为什么我们默认没有on呢?显然加on比删除要容易。

常用事件

滚轮

.onmousewheel//滑动滚轮
/*
火狐不兼容这个事件,应使用DOMMouseScroll,而且只能由监听器触发
*/
 box.onmousewheel = function () {
           alert(eve);
       }
       box.addEventListener("DOMMouseScroll",box.onmousewheel,false);


之前我们解决兼容性问题通常是使用if判断,
但在Chrome中if( box.onmousewheel)会返回false,内存中onmousewheel=null
火狐中没有 box.onmousewheel但把他当做了函数名不会报错
chrom中没有DOMMouseScroll事件但同样不会报错也不会触发
于是我们在火狐中将这个事件当做函数名使用解决兼容性问题

但实际上这种解决问题的方式稍微进一步就会失效,比如:我想要进一步判断滚轮滑动方向就完蛋了。

   function up(){
      var he = getComputedStyle(box,null).height;
      var str =he.split("px")[0];
      str = Number(str);
      box.style.height = str +100+"px";
  }
  function down(){
      var he = getComputedStyle(box,null).height;
      var str =he.split("px")[0];
      str = Number(str);
      if(str>100){
          box.style.height = str -100+"px";
      }else{
          box.style.height ="0px";
      }
  }

  box.onmousewheel = function () {//chrome
      if(event.wheelDelta>0){
          up();
      }else{
          down();
      }
  }
  box.addEventListener("DOMMouseScroll",function () {//火狐
      if(event.detail<0){
          up();
      }else{
          down();
      }
  },false);

event.whellDelta//用于判断滚轮滑动方向;
向上为正,向下为负;我们只需要正负因为……每个浏览器都不一样
event.detail//火狐专用;向上为,向下为

按键

键盘事件一般绑定给可以获取焦点的对象或者document。(获取不了焦点怎么获取键盘事件?)

onkeydown;//当按键按下持续发生(第一次和第二次间隔略长是正常的防误触操作)

onkeyup;//当按键松开
通过eventkeycode或者event.which获取按键编码,
String.fromCharCode(event.which);可以直接转换编码为字符
           

组合按键
我们想要确定ctrl按下需要event.keycode ==17;
我们想要确定c按下需要event.keycode ==67;
那么判断两个键同时按下呢?event.keycod不能同时等于两个值啊?

属性事件
altkey返回当事件被触发时,“ALT” 是否被按下。
ctrlkey返回当事件被触发时,“CTRL” 键是否被按下。
meta返回当事件被触发时,“meta” 键是否被按下。
shiftkey返回当事件被触发时,“SHIFT” 键是否被按下。
if(event.keyCode ==67 && event.ctrlkey)
//这样就可以判断一对组合键
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值