美文网首页
js进阶三:event(鼠标滚动,键盘事件,拖拽,手机触屏)

js进阶三:event(鼠标滚动,键盘事件,拖拽,手机触屏)

作者: 蘭小木 | 来源:发表于2020-01-16 18:29 被阅读0次

    事件

    当浏览器调用事件的响应函数时,每次都会传递一个事件对象作为参数

    在事件对象封装了当前事件相关的信息,比如:鼠标的坐标 键盘哪个按键被按下。。。

    我们可以通过该对象来获取事件相关的信息

    event = event || window.event 
    
    • 在IE8及以下的浏览器中,没有将事件对象作为参数传递进函数,所以我们就不能以参数的形式来使用事件对象。
    • 在IE8中,是将事件对象作为window对象的属性保存的,需要使用window.event来使用

    事件的传播

    1. 捕获阶段
    • 事件从最外层的元素(document),向目标元素进行事件的捕获
    • 此阶段默认不会触发事件
    1. 目标阶段
    • 目标指的是触发事件的元素,捕获到目标元素则捕获阶段停止
    1. 冒泡阶段
    • 事件从目标元素向祖先元素中冒泡,此时开始触发事件
    • 默认事件都是在冒泡阶段执行的

    事件都是默认在冒泡阶段执行的,一般不需要在捕获阶段触发事件

    如果希望在捕获阶段执行事件,则需要将addEventListener()的第三个参数修改为true

    IE8及以下的浏览器没有捕获阶段,也不能设置在捕获阶段触发事件

    捕获和释放事件

    当选择多个元素,但是只想拖拽选中中的一个元素就可以给这个元素设定捕获事件,这样事件就只传给这一个元素。

    捕获完之后,事件结束时一定要释放。

    在chrome中没有setCapture()和releaseCapture()方法
    所以调用会导致浏览器报错

    捕获事件
    box1.setCapture || box1.setCapture();
    
    释放事件
    box1.releaseCapture || box1.releaseCapture();
    

    事件冒泡

    • 冒泡简单来说就是事件的向上传导,当后代元素上的事件被触发时,将会导致祖先元素上的相同事件也被触发

    • 大部分情况下冒泡都是对开发有利的,可以简化我们的开发

    • 如果不希望发生事件的冒泡,则可以通过事件对象来取消冒泡

    • 将事件对象的cancelBubble属性设置true,即可取消冒泡

       event.cancelBubble = true;取消冒泡
      

    事件的委派

    • 指统一将多个元素上的事件绑定到他们共同的祖先元素上,

    • 这样只需要绑定一次即可同时处理多个元素上的相同的事件,

    • 这样简化了代码的开发,也可以确保新添加的元素上也可以有事件响应函数

    属性

    //获取出发事件的对象
    event.target
    

    事件的绑定

    使用 对象.事件 的形式不能同时为一个元素的同一个事件绑定多个处理函数
    如果绑定了多个,则后边的会将前边的覆盖掉

    readFileDom.onclick = function (event) {}
    

    如果需要同时为一个事件绑定多个响应函数,则在正常浏览器中使用addEventListener()来绑定,响应函数按照绑定的顺序执行,它的响应函数中的this就是绑定事件的对象

    参数

    • 要绑定的事件(字符串 不要on)

    • 回调函数(事件触发时,该函数将会执行)

    • 是否在捕获阶段触发事件(都传false)

        readFileDom.addEventListener("click", function (event) {},false);
      

    在IE中,使用的是attachEvent()来绑定的事件,而它的响应函数中的this是window

    • 可以同时为一个事件绑定多个响应函数,但是它的执行顺序不一定
    • ie9 ie10 先绑定先执行

    • ie8 后绑定先执行

        readFileDom.attachEvent("onclick",function (event) {}); 
      
    自定义兼容所有浏览器的事件绑定
    /*
    * 参数:
    * obj  要绑定事件的对象
    * eventStr 事件的字符串,不要on
    * callback 回调函数,事件触发时调用的函数
    */
    function bind(obj , eventStr , callback){
    
    if(obj.addEventListener){
    //如果是正常浏览器
    obj.addEventListener(eventStr , callback , false);
    }else{
    //IE8
    /*
    * attachEvent()中的回调函数的this是window,需要修改为obj
    * this是谁由函数的调用方式决定
    * 1.以函数的形式调用,this是window
    * 2.以方法的形式调用,this是调用方法的对象
    * 3.以构造函数的形式调用,this是新创建的对象
    * 4.使用call和apply调用时,this是第一个参数
    */
    obj.attachEvent("on"+eventStr , function(){
    /*
    *在attchEvent()中不传递callback而是传递一个匿名函数
    *这样在事件触发时,浏览器不会调用callback而是调用匿名函数
    *在匿名函数中来调用回调函数
    */
    callback.call(obj);
    
    });
    }
    }
    

    取消浏览器的默认行为

    * 当我们在浏览器中选中一个文字或一个内容并拖动时,浏览器会自动去搜索引擎中搜索该内容
    * 但是这个行为的出现会导致拖拽功能出现异常,这一行为是浏览器的默认行为
    * 如果不希望发生该行为,则可以在事件中取消默认行为
    
    方法一
    直接在事件的函数中返回false。 
    `return false;`
    
    方法二
    使用addEventListener()绑定的事件,不能通过return false来取消默认行为
    需要调用事件对象 preventDefault()方法来取消默认行为
    但是在IE8中没有该方法
    `event.preventDefault || event.preventDefault();`
    

    鼠标滚轮事件

    • Firefox的滚轮事件使用 DOMMouseScroll

        elem.addEventListener(‘DOMMouseScroll’, func, false);
      
    • 其他浏览器的滚轮事件使用 mousewheel

        window.onmousewheel=document.onmousewheel=func;     //IE/Opera/Chrome
      

    判断滚轮向上或向下,Firefox 使用detail,其余浏览器使用wheelDelta

    滚动值的区别
    IE 鼠标滚轮向上滚动是120,向下滚动是-120
    Opera 鼠标滚轮向上滚动是120,向下滚动是-120
    Chrome 鼠标滚轮向上滚动是120,向下滚动是-120
    Safari 鼠标滚轮向上滚动是360,向下滚动是-360
    Firefox 鼠标滚轮向上滚动是-3,向下滚动是3
    
    兼容写法
    //判断鼠标滚轮滚动方向
    if (window.addEventListener){//火狐浏览器会识别该方法
        window.addEventListener('DOMMouseScroll', wheel, false);
    }
    window.onmousewheel = document.onmousewheel = wheel;//W3C
    //统一处理滚轮滚动事件
    function wheel(event){
        var delta = 0;
        if (!event) event = window.event;
        if (event.wheelDelta) {//获取事件对象中wheelDelta的值,这里表示向上滑动
            //IE、chrome浏览器使用的是wheelDelta,并且值为“正负120”
            delta = event.wheelDelta/120; 
            if (window.opera) delta = -delta;//因为IE、chrome等向下滚动是负值,FF是正值,为了处理一致性,在此取反处理
        } else if (event.detail) {
            //火狐浏览器使用的是detail,其值为“正负3”
            delta = -event.detail/3;
        }
        if (delta)
            handle(delta);
    }
    //上下滚动时的具体处理函数
    function handle(delta) {
            if (delta <0){//向下滚动
                
            }else{//向上滚动
                
            }
        }
    

    键盘事件

    键盘事件一般都要绑定给可以获取焦点的元素(一般指表单项),或者是document

    onkeydown
    • 当按下键盘上的一个按键一直不松开时,会连续的触发onkeydown事件,
    • 但是第一次触发和第二次触发的间隔会比较长,而第二次以后会一直连续触发
    • 这种设计是为了防止误操作
    onkeyup
    事件属性
    keycode

    可以用来获取当前按键的编码

    altKey

    判断是否按下alt键

    ctrlKey

    判断是否按下ctrl键

    shiftKey

    判断是否按下shift键


    拖拽事件

    需要给被拖拽元素设置dragable = "true";否则无法实现拖拽效果
    <div class="box" draggable="true"></div>
    
    释放区元素事件
    ondragend

    进入拖拽区

    ondragover

    在拖拽区中

    在里面添加event.preventDefault();用来阻止默认拖拽样式
    
    ondragleave

    离开拖拽区

    ondrop

    在拖拽区中释放鼠标

    监听拖拽外部文件
    var fileList = ev.dataTransfer.files; //所有被拖拽的网页外的文件
    
    拖拽元素事件
    ondragstart

    拖拽开始

    在这里可以设置鼠标拖拽样式
    even.dataTransfer.dropEffect = "uninitialized";
    even.dataTransfer.effectAllowed = "uninitialized";
    
    上述两个属性可设置的值包括,none, copy, copyLink, copyMove(默认), 
    link, linkMove, move, all 和 uninitialized。
    
    //使用图片设置鼠标样式
    even.dataTransfer.setDragImage(imgdom,0,0)
    img:  图片的DOM,
    xOffset : 水平偏移量
    yOffset : 垂直偏移量
    
    ondrag

    拖拽中

    ondragend

    拖拽结束


    手机触屏事件

    touchstart
    touchmove
    touchend

    手机事件需要使用addeventlistener()添加事件

    bodyDom.addEventListener("touchstart", function (event) {
        var touchArr = event.targetTouches;//获取元素上触摸手机的列表
        var touch = touchArr[0];
        touchArr[0].identifier;返回被触摸对象的唯一标识符。手指在屏幕表面滑动的过程中,触点具有相同标识符,这能让你一直的追踪的相同的触摸事件。
        touch.target :   被触摸的DOM元素。
        touch.screenX , 返回距离设备屏幕左边缘的X轴坐标  
        touch.screenY , 返回距离设备屏幕上边缘的Y轴坐标 
        touch.clientX ,返回距离浏览器视窗左边缘X轴坐标,不包括滚动条( scroll offset )。
        touch.clientY ,返回距离浏览器视窗上边缘Y轴坐标,不包括滚动条( scroll offset )。
        touch.pageX , 返回距离HTML文档左边缘的的X轴坐标,与Touch.clientX不同,它包括滚动条。
        touch.pageY ,返回距离HTML文档左边缘的的Y轴坐标,与Touch.clientY不同,它包括滚动条。
        radiusX/radiusY/rotationAngle:画出大约相当于手指形状的椭圆形,分别为椭圆形的两个半径和旋转角度。该属性暂时处于试验阶段。
    }, false);
    

    点透

    原因
    • touchstart 和 click (PC端的事件) 会依次执行,click 会在touchstart执行后 300ms 执行。
    • 如果当touchstart 调用了 display: none; 后续的 click 就会点击到 a 链接元素,造成页面跳转
    解决方法
    • touchstart 中添加 ev.preventDefault(); 阻止后续 click 执行。
    点透产生的条件:
        1.被点击事件设置浮动
        2.点击浮层,让浮层 display: none;
        3.点击处的下方有 a 连接
        4.移动端
    

    相关文章

      网友评论

          本文标题:js进阶三:event(鼠标滚动,键盘事件,拖拽,手机触屏)

          本文链接:https://www.haomeiwen.com/subject/eofqzctx.html