JS-事件对象

本文详细介绍了JavaScript中的事件对象,包括如何获取鼠标坐标和处理兼容性问题。此外,讲解了事件冒泡的概念及其在事件委派中的应用,减少了事件绑定的次数以提升性能。还讨论了事件的绑定方式,如addEventListener和attachEvent,以及事件的传播阶段。最后,提到了鼠标滚轮和键盘事件的处理方法,以及如何实现拖拽功能并处理浏览器默认行为。
摘要由CSDN通过智能技术生成

JS-事件对象

  1. 事件对象简介

    事件对象

    —当事件响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递给响应函数

    —在事件对象中封装了当前事件的一切信息,比如鼠标坐标、键盘哪个按键被按下、鼠标滚轮滚动方向等;

    —具体可以查看事件对象中相关属性,比如鼠标/键盘相关属性,例如button属性,返回事件被触发时,哪个鼠标按钮被点击;

    —在IE8中,响应函数被触发时,浏览器不会传递事件对象这个参数,在IE8及以下的浏览器中,将事件对象作为window对象的属性保存的;因此为了兼容IE8浏览器,可以通过 window.event 访问事件对象

    onmousemove事件,该事件将会在鼠标在元素移动时触发事件

    <script>
    	window.onload = function(){
         //实现鼠标在areaDiv移动时,在showMsg显示鼠标坐标
         var areaDiv = document.getElementById("areaDiv");
         var showMsg = document.getElementById("showMsg");
         areaDiv.onmousemove = function(event){
             //为了解决事件对象兼容性问题,可以增加一个判断
             event = event || window.event;
             //事件对象的相关属性:
                     //——clientX:可以获取鼠标指针的水平坐标
                     //——clientY:可以获取鼠标指针的垂直坐标
             var x = event.clientX;
             var y = event.clientY;
             showMsg.innerHTML = "x="+x+",y="+y;
         };
     };
    </script>
    

    clientXclientY是用于获取鼠标在当前可见窗口的坐标,其偏移是相对于可见窗口绝对定位的偏移量是相对于整个页面的

    pageXpageY可以获取鼠标相对于当前页面的坐标;但是两个属性在IE8中不兼容;所以如果需要兼容IE8,不能使用这两个属性;

    —为了兼容浏览器,我们可以使用clientXclientY,可以将此时div的偏移量设置为滚动条滚动距离+事件对象的偏移量,这样就实现了事件对象和div重合;

    —chrome浏览器认为滚动条是body的,可以通过body.scrollTop获取;

    —火狐等浏览器认为浏览器的滚动条是html的;

    <script>
    	window.onload = function(){
         var box1 = document.getELementById("box1");
         document.onmousemove = function(event){
             event = event || window.event;
             //为了解决兼容性问题,获取滚动条距离
             var st = document.body.scrollTop || document.documentElement.scrollTop;
             var sl = document.body.scrollLeft || document.documentElement.scrollLeft;
         };
         var left = event.clientX;
         var top = event.clientY;
         //设置div的偏移量
         box1.style.top = top + st +"px";
         box1.style.left = left + sl +"px";
     };
    </script>
    
  2. 事件的冒泡

    事件的冒泡(Bubble)

    —所谓的冒泡指的是事件的向上传导,当后代元素上的事件被触发,其祖先元素的相同事件也会被触发;

    —在开发中,冒泡是十分有用的;

    —如果不希望事件冒泡,可以通过事件对象来取消冒泡;可以将事件对象的cancelBubble属性设置为true即可取消冒泡:var event.cancelBubble = true;

  3. 事件的委派

    <script>
    	//事件冒泡举例—事件的委派
     var btn = document.getElementById("btn");
     btn.onclick = function(){
         //创建li
         var li = document.createElement("li");
         var u1 = document.getElementById("u1");
         li.innerHTML = "<a class = 'link' href='javascript:;'>新建超链接</a>";
         u1.appendChild(li);
     };
     //这里为现有的每一个超链接绑定一个单击响应函数,循环遍历比较麻烦,并且只能为已有的超链接添加单击响应函数,而新添加的超链接必须重新绑定,比较麻烦;
     //我们希望只绑定一次事件,即可应用到多个元素上,即使元素是后添加的;
     //我们可以尝试将其绑定给元素的共同的祖先元素;
     u1.onclick = function(event){
         event = event || window.event;
         if(event.target.className == "link"){
             alert("我是超链接");
         }
     };
    </script>
    

    事件的委派

    —将事件统一绑定给元素共同的祖先元素,这样当后代元素被触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件;

    事件的委派是利用了冒泡,通过事件的委派可以减少事件绑定的次数,提高程序的性能;

    —另外,我们可以进行判断,如果触发事件的对象是我们期望的元素,则执行否则不执行;这里需要事件对象,可以通过target属性,返回触发事件的对象

  4. 事件的绑定

    —使用对象.事件 = 函数的形式绑定响应函数,只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定多个,则后边的会覆盖掉前边的响应函数;

    —可以通过 addEventListener()方法为元素绑定响应函数,需要参数:

    1. 事件的字符串,不要on,比如onclick写作"click"

    2. 回调函数,当事件触发时,函数会被调用;

    3. 是否在捕获阶段触发事件,需要一个布尔值,一般都传递false

    —使用该种方式可以同时为一个元素的相同事件绑定多个响应函数,这样当事件被触发时,响应函数会按照函数的绑定顺序执行;

    —该方法中this指向的是绑定事件的对象;

    —这个方法在Ie8及以下的浏览器不支持

    attachEvent()方法可以在IE8中支持,需要参数:

    1. 事件的字符串,需要on

    2. 回调函数

    —这个方法可以同时为一个元素的相同事件绑定多个响应函数,不同的是当事件被触发时,响应函数是后绑定的先执行,执行顺序和addEventListener相反

    —该方法的this指向的是window

    <script>
    	//定义函数,解决兼容性问题
        //参数:
        //1.obj:要绑定事件的对象
        //2.eventStr:事件的字符串
        //3.callback:回调函数
        function bind(obj,eventStr,callback){
            if(obj.addEventListener){
                obj.addEventListener(eventStr,callback,false);
            }else{
                //可以通过callback.call(obj)修改this的值为绑定事件的对象;
                //回调函数不传递callback,传递一个匿名函数,在匿名函数调用回调函数;
                //在匿名函数中调用的回调函数修改this的指定对象;
                obj.attachEvent("on"+eventStr,function(){
                    callback.call(obj);
                });
            }
        }
    </script>
    
  5. 事件的传播

    —关于事件的传播,网警公司和微软公司有不同的理解;

    —微软公司,认为事件应该由内向外传播的,当事件触发时,应该先触发当前元素上的事件然后在向当前元素的祖先元素传播;事件应该在冒泡阶段执行;(事件的冒泡)

    —网警公司,认为事件应该是由外向内传播的,当事件触发时,应该先触发当前元素的最外层的祖先元素事件,然后在向内传播给后代元素(事件的捕获阶段)

    —W3C综合了两个公司的方案,将事件的传播分为三个阶段(适用于IE9及以上的浏览器):

    1. 捕获阶段

    —在捕获阶段时,由最外层的祖先元素向目标元素进行事件捕获;但是默认此时不会触发事件

    1. 目标阶段

    —事件捕获到目标元素,捕获阶段结束,开始在目标元素上触发执行事件

    1. 冒泡阶段

    —事件从目标元素向其祖先元素传递,依次触发祖先元素上的事件

    —如果希望在捕获阶段就触发执行事件,可以在addEventListener()的第三个参数中改为true;一般情况不会再捕获阶段触发执行事件;

    IE8及以下的浏览器无捕获阶段

  6. 滚轮事件

    onmousewheel为鼠标滚轮滚动事件;

    —在火狐中使用DOMMouseScroll实现滚轮事件,该事件需要通过addEventListener()函数实现;

    event.wheelDelta可以获取鼠标滚轮方向向上滚动是正值,向下滚动是负值

    wheelDelta属性在火狐中不支持,火狐中使用event.detail向上滚动为负值,向下滚动为正值

    —当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动;这是浏览器的默认行为,如果不希望发生,则可以取消这个默认行为;

    —注意,使用addEventListener()方法绑定响应函数时,取消浏览器默认行为时,不能使用return false;需要使用event取消默认行为:event.preventDefault();但是IE8不支持该方法,如果直接调用会报错;所以使用时需要判断:event.preventDefault && event.preventDefault();

  7. 键盘事件

    onkeydown事件:

    按键被按下

    —对于onkeydown来说,当某个按键一直按下,它会连续触发事件;

    —当onkeydown连续触发时,第一次和第二次之间触发响应间隔会相对较长,其他的会非常快;

    —这种设计是为了防止错误操作;

    onkeyup事件

    按键被松开

    —键盘事件一般都绑定给可以获取焦点的对象(表单对象)或者是document对象

    —可以通过event.keyCode来获取按键编码;(已弃用,使用key);

    —通过它可以判断哪个按键被按下;

    altKey:返回事件被触发时,ALT键是否被按下;

    ctrlKey:返回事件被触发时,Ctrl键是否被按下;

    shiftKey:返回事件被触发时,Shift键是否被按下;

    以上按键如果按下,则返回true,否则返回false

    —在表单对象中文本框中输入内容属于onkeydown的默认行为,如果onkeydown通过return false取消了默认行为,则输入的内容不会出现在文本框中;

    <script>
    	//拖拽函数
     //需要传递一个参数,即需要开启拖拽的元素
     function drag(obj){
         //为对象绑定鼠标按下事件
         obj.onmousedown = function(event){
             //解决IE8浏览器兼容问题,设置捕获
             //setCapture()方法只有IE支持,但是在火狐中调用不会报错;
             //但是在chrome中使用会报错,因此可以加一个判断
             obj.setCapture && obj.setCapture();
             event = event || window.event;
             //为了使得鼠标按下时就固定在按下的位置,需要计算偏移量
             //求出obj水平偏移量:鼠标.clientX - 元素.offsetLeft
             var ol = event.clientX - obj.offsetLeft;
             //求出obj垂直偏移量:鼠标.clientY - 元素.offsetTop
             var ot = event.clientY - obj.offsetTop;
             //绑定鼠标移动事件,这里绑定给document
             document.onmousemove = function(event){
                 event = event || window.event;
                 //获取鼠标坐标
                 var x = event.clientX - ol;
                 var y = event.clientY - ot;
                 //修改被拖拽元素的位置
                 obj.style.left = x + "px";
                 obj.style.top = y +"px";
             };
             //为obj绑定时,当鼠标移动到其他对象区域时,触发事件无效,因此要为document绑定
             document.onmouseup = function(){
                 //当鼠标松开时,被拖拽元素固定在当前位置
               	//取消document的onmousemove事件
               	document.onmousemove = null;
                 //需要取消onmouseup事件,相当于只会响应一次,一次性事件;
                 document.onmouseup = null;
                 //当调用一个元素的setCapture()方法以后,这个元素会把下一次所有鼠标按下的相关事件捕获的自身身上;
                 //当鼠标松开时,取消obj的捕获
                 obj.releaseCapture && obj.releaseCapture();
             };
             //当我们去拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容此时会导致拖拽功能异常;
             //这个是浏览器提供的默认行为,如果不希望发生这个行为,可以通过return false取消这个行为,但是IE8浏览器不起作用;
             //在IE8浏览器中可以使用setCapture()方法进行事件捕获;
             return false;
         };
     }
    </script>
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值