JS 事件高级(包括DOM事件流,阻止事件冒泡,阻止事件默认行为,,,以及对我来说,很好用的 事件代理)

 事件对象概念

  • 事件处理函数:事件发生时调用的函数

  • 事件对象:window.event,内置的对象,事件发生的时候会将所有和事件相关的信息都存储在事件对象中,鼠标位置,事件类型,事件目标。。。

    //事件对象:事件发生的时候,会将所有和事件相关的信息,存储在事件对象中window.event  
    //标准、ie : window.event  /  event
    //ff: event必须加window,不然会报错,加window不会报错,但是获取到的是undefind
    //     火狐的事件对象需要通过事件处理函数的第一个参数传入
    document.onclick = function(eve){ //事件处理函数
        console.log(window.event);
    ​
        //兼容: 标准、ie      || ff
        var ev = window.event || eve;
        console.log(ev);
    }

事件对象的属性

  • type:事件类型

  • target:事件目标

  • clientX,clientY:鼠标位置,相对于窗口可视区

  • shiftKey,ctrlKey,altKey:事件发生的时候有没有按住这个键,按了true,没按false

     //事件对象属性
    console.log(ev.type); //事件类型  click
    console.log(ev.target); //事件目标  
    console.log(ev.clientX + "======" + ev.clientY); //鼠标的位置 相对于当前可视窗口
    console.log(ev.pageX + "======" + ev.pageY); //鼠标的位置 相对于当前body页面  ie8不兼容
    console.log(ev.shiftKey,ev.ctrlKey,ev.altKey); //事件发生的时候有没有按住这个按键,按了true  没按就是false

事件绑定与取消

为什么需要事件绑定

  • 之前添加事件:标签.事件名 = function(){}

    //1.添加  标签.事件名 = function(){} : 给同一个标签添加相同事件后面的会覆盖前面
    oDiv.onclick = function(){
        console.log("你是一个小可爱");
    }
    oDiv.onclick = function(){
        console.log("我是一个小可爱");
    } 

  • 存在问题: 给同一个标签添加相同事件后面的会覆盖前面,不利于合作开发

事件绑定

  • 事件绑定:可以给同一个标签添加相同事件不会覆盖,会叠加执行

  • 语法

    标准:标签.addEventListener(事件类型,事件处理函数,是否捕获)  事件类型不加on,是否捕获默认是false
    IE:标签.attachEvent(事件类型,事件处理函数) 事件类型加on
  • 例:

    /*
        标准浏览器:标签.addEventListener(事件类型,事件处理函数,是否捕获)   事件类型不加on  是否捕
        获:false
        IE浏览器: 标签.attachEvent(事件类型,事件处理函数)    事件类型加on
    */
    ​
    //2.1 标准浏览器:标签.addEventListener(事件类型,事件处理函数,是否捕获)   事件类型不加on  是否捕获:false
    oDiv.addEventListener("click",fun1);
    oDiv.addEventListener("click",fun2);
    ​
    ​
    //2.2 IE浏览器: 标签.attachEvent(事件类型,事件处理函数)    事件类型加on
    //ie低版本倒序执行,this--window
    oDiv.attachEvent("onclick",fun1);
    oDiv.attachEvent("onclick",fun2);
    ​
    function fun1(){
        alert(this);
    }
    function fun2(){
        alert(2);
    }

  • 兼容

    两个方法的兼容,用判断,拿其中一个方法做判断条件

    //2.3 兼容  方法的兼容:判断,拿其中任意一个方法作为判断条件,有就用,没有就用另一个 xx.xx
    if(oDiv.attachEvent){
        oDiv.attachEvent("onclick",fun1);
    }else{
        oDiv.addEventListener("click",fun1);
    }

事件取消

  • 不同的添加方式需要有不同的取消方式

    事件添加事件取消
    标签.事件标签.事件 = null
    标签.addEventListener(事件类型,事件处理函数)标签.removeEventListener(事件类型,事件处理函数)
    标签.attachEvent(事件类型(加on),事件处理函数)标签.detachEvent(事件类型(加on),事件处理函数)
  • 普通添加事件的方式取消:标签.事件

    //1.获取元素
    var oBtn = document.getElementsByTagName("button")[0];
    var arr = ["5遍起", "0遍", "10遍", "20遍", "再来一次"];
    ​
    //2.取消事件 
    oBtn.onclick = function(){
        console.log(arr[Math.floor(Math.random()*arr.length)]);
        oBtn.onclick = null; //取消事件
    }

  • 绑定添加事件取消

    function fun() {
        console.log(arr[Math.floor(Math.random() * arr.length)]);
        //标准取消
        // oBtn.removeEventListener("click",fun);
        //IE取消
        // oBtn.detachEvent("onclick",fun);
        if (oBtn.detachEvent) {
            oBtn.detachEvent("onclick", fun);
        } else {
            oBtn.removeEventListener("click", fun);
        }
    }

DOM事件流

 DOM事件流

  • DOM事件流概念

    DOM事件流:事件发生时的传递过程
    事件捕获机制:当事件发生的时候,事件会从window-document-body-子元素依次传递,一直到事件目标
    事件冒泡机制:当前事件目标开始处理事件,然后依次将事件传递给父元素,一直到window,如果父元素也有对应的事件,也会触发
    ​
    注意:冒泡是从结构上出发,默认就是事件冒泡机制
  • //点击box3,box3先处理事件,然后将事件传递给box2,box1,body,,,,,依次往父级传递
    //2.添加点击事件
    oDivs[0].onclick = fun;
    oDivs[1].onclick = fun;
    oDivs[2].onclick = fun;
    document.onclick = fun;
    ​
    //3.绑定添加
    //oDivs[0].addEventListener("click",fun,是否捕获)
    //默认是false:冒泡    true:捕获(捕获阶段处理事件)
    oDivs[0].addEventListener("click",fun,true);
    oDivs[1].addEventListener("click",fun,true);
    oDivs[2].addEventListener("click",fun,true);
    ​
    function fun(){
        alert(this.id);
    }

阻止事件冒泡

  • 为什么需要阻止事件冒泡:事件流的正常处理就是事件冒泡,但是有时候事件冒泡会影响到代码的正常效果,这个时候就需要阻止事件冒泡

  • 标准浏览器:event.stopPropagation()

  • IE浏览器:event.cancelBubble = true;

  • 兼容:event.stopPropagation ?event.stopPropagation():event.cancelBubble = true;

    oDiv.onclick = function(ev){
        var ev = window.event || ev;
        //ev.stopPropagation();  标准浏览器
        //ev.cancelBubble = true;  iE浏览器
    ​
        //兼容
        ev.stopPropagation ? ev.stopPropagation(): ev.cancelBubble = true;
        console.log("我是div的事件");
    }
    ​
    document.onclick = function(){
        console.log("我是窗口的事件");
    }

阻止事件默认行为

  • 默认行为

    • 默认行为:浏览器赋予某个标签,某个操作的默认的功能

    • 例如:a的跳转,form中button默认提交,右击显示菜单,拖拽图片保存,双击默认选中文字

      <a href="http://www.baidu.com">百度</a>
      <form action="">
          <input type="text" name="user">
          <button>按钮</button>
      </form>
      <p>fdsfdsf</p>

  • 阻止默认行为

    添加事件的方式阻止默认行为的方式
    标签.事件return false
    标签.addEventListenerevent.preventDefault()
    标签.attachEventevent.returnValue = false
    • 标签.事件 阻止默认行为

      var oA = document.getElementsByTagName("a")[0];
      //1.普通事件阻止
      oA.onclick = function(){
          return false;
      }

    • 事件绑定阻止默认行为

      //2.绑定事件阻止
      bind(oA,"click",function(eve){
          var ev = window.event || eve;
          //阻止默认行为:
          ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;            
      })

事件代理(事件委托)

  • 事件代理:把事件添加给父元素(通过事件冒泡,子元素触发事件也能触发父元素),找到具体发生事件子元素,由子元素去处理事件

  • 优点:提高性能,事件可以发生在未来

    var oUl = document.getElementsByTagName("ul")[0];
    //1.将事件添加给父元素
    oUl.onclick = function(ev){
        var ev = window.event || ev;
        
        //2.找到具体的子元素
        var target = ev.target || ev.srcElement;
        
        //3.
        if(target.nodeName == "LI"){
            //4.处理事件
        }
    }
     //事件可以发生在未来
    oUl.

6.键盘事件

  • onkeydown:按键按下

  • onkeyup : 按键抬起

  • onkeypress:按键按下

    document.onkeydown = function (eve) {
        var ev = window.event || ev;
        console.log(ev.key); //IE获取不到值
        console.log(ev.keyCode);//不区分大小写,获取到的大写编码   "0" -- 48  "A"--65  "a"--97    
        console.log(ev.shiftKey, ev.ctrlKey, ev.altKey); //是否按住了这个键,按了true  
    ​
        //按ctrl+c打印复制
        if (ev.ctrlKey ==  true && ev.keyCode == 67) { 
            console.log("复制");
        }
    }

  • 获取按键编码:ev.keyCode

滚轮事件

  • 语法

    标准、IE: onmousewheel
        获取滚动方向  event.wheelDelta    120:上   -120:下
    ff:必须是用事件绑定   标签.addEventListener("DOMMouseScroll")
        获取滚动方法 event.detail     -3:上   3:下

  • 添加

     var oDiv = document.querySelector("div");
    ​
    //1.标准、IE: onmousewheel
    oDiv.onmousewheel = scroll;
    ​
    //2. ff:必须是用事件绑定   标签.addEventListener("DOMMouseScroll")
    if (oDiv.addEventListener) {
        oDiv.addEventListener("DOMMouseScroll",scroll);
    }
    ​
    ​
    //3.滚动函数
    function scroll(ev){
        var ev = window.event || ev;
    ​
        //4.获取滚动方向
        // console.log(ev.wheelDelta);  //标准、IE   120:上   -120:下
        // console.log(ev.detail); //ff   -3:上   3:下
    ​
        var tag = true; //true---上  false:下
        if(ev.wheelDelta){
            tag = ev.wheelDelta > 0 ? true : false;
        }else{
            tag = ev.detail > 0 ? false : true;
        }
    ​
        if(tag == true){
            console.log("上");
        }else{
            console.log("下");
        }
    ​
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值