事件处理模型——事件冒泡、捕获

    1. 事件冒泡(不绑定事件处理函数一样会发生冒泡事件)
      1. 结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一个事件,自子元素冒泡向父元素(自底向上)
        1.             <div class="first" style="width: 300px; height: 300px; background-color: red;">
                          <div class="secend" style="width: 200px; height: 200px; background-color: yellow;">
                              <div class="end" style="width: 100px; height: 100px; background-color: green;"></div>
                          </div>
                      </div>
                  <script>
                      var first = document.getElementsByClassName("first")[0];
                      var secend = document.getElementsByClassName("secend")[0];
                      var end = document.getElementsByClassName("end")[0];
                      first.onclick=function(){
                          console.log("123");
                      };
                      secend.onclick=function(){
                          console.log("456");
                      };
                      end.onclick=function(){
                          console.log("789");
                      }
                    </script>   我们同时在三个div上绑定了事件,现在三个div存在嵌套的关系,当我们点击最里层的div的时候,就会触发相关的事件冒泡,外边的两个父类div的事件都会被触发,这就是事件冒泡(先触发自己的事件,然后依次向父级)

    2.事件捕获 

    1. 结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一个事件,自复父元素捕获至子元素(事件源元素)(自顶向下)
    2.             <div class="first" style="width: 300px; height: 300px; background-color: red;">
                      <div class="secend" style="width: 200px; height: 200px; background-color: yellow;">
                          <div class="end" style="width: 100px; height: 100px; background-color: green;"></div>
                      </div>
                  </div>
              <script>
                  var first = document.getElementsByClassName("first")[0];
                  var secend = document.getElementsByClassName("secend")[0];
                  var end = document.getElementsByClassName("end")[0];
                  first.addEventListener('click',function(){
                      console.log("123");
                  },true);                //当这个true为false时就不会触发事件捕获,但是会触发事件冒泡
                  secend.addEventListener('click',function(){
                      console.log("456");
                  },true);
                  end.addEventListener('click',function(){
                      console.log("789");
                  },true)
              </script>

        我们同时也在三个div上绑定了事件,它们存在嵌套关系,现在我们点击最里边的事件,就会触发捕获事件(先触发被点击的事件的最外层的父级元素的事件,依次向里),这就是事件捕获

  1. 触发顺序:先捕获,后冒泡
  2. focus      blur     change      submit    reset    select  等事件不冒泡
  3. 取消冒泡
    1. W3C标准event.stopPropagation();  但不支持ie9以下版本
    2.             end.onclick=function(e){
                      e.stopPropagation();   //这就会组织冒泡事件的发生    e代表这个是事件的本身
                      console.log("789");
                  }
    3. IE独有event.cancelBubble=true;(这个上边的功能是一样的,写法也是一样的)
  4. 阻止默认事件
    1. 首先我们先说说什么是默认事件
      1. 默认事件——表单提交      a标签跳转        右键菜单
    2. 我们如何来阻止这些默认事件呢?
    3. return false ;以对象属性的方式注册的事件才生效
      1.             document.oncontextmenu=function(){    //阻止鼠标右键菜单的默认事件
                        console.log("123");
                        return false;
                    }
    4. event.preventDefault();    W3C标准,IE9以下不兼容
      1.             document.oncontextmenu=function(e){
                        console.log("123");
                        e.preventDefault();
                    }
    5. event.returnValue=false;   兼容IE
      1.             document.oncontextmenu=function(e){
                        console.log("123");
                        e.returnValue=false;
                    }
  5. 事件对象
    1. event  ||   window.event  用于IE  
  6. 事件源对象:(虽然我们前边说过事件存在冒泡,但是我们可以通过下边的方法找到我们所触发的事件源对象)
    1. event.target   火狐只有这个
    2. event.srcElement    IE只有这个
    3. 这俩Chrome都有
    4. 我们来使用事件源实现一个很使用的编程题
    5. <!-- 现在我们有这样的需求,我们需要在ul下的li中给每一个里都绑定事件,当点击某一个li时,展示li中的内容 -->
                   <ul>
                      <li>1</li>
                      <li>2</li>
                      <li>3</li>
                      <li>4</li>
                      <li>5</li>
                      <li>6</li>
                      <li>7</li>
                      <li>8</li>
                      <li>9</li>
                      <li>10</li>
                  </ul>
               <script>
                   var ul = document.getElementsByTagName("ul")[0];
                   ul.onclick = function(e){
                       var event = e || window.event;
                       if(event.target){
                           console.log(event.target.innerText);  //获取事件源元素的文本内容
                       }else{
                           console.log(event.srcElement.innerText);
                       }
                   }
                  //这个例子就没有用到for循环,大大减少了运行的事件,把事件绑定在父元素上,点击子元素时,父元素去找事件源,再处理先关的事件源
           
      </script>
       
  7. 学到这里,相信大家对事件都有差不多的了解了,那我们现在来实现一个鼠标拖动事件:
    1.             <div style="width: 50px; height: 50px; background-color: red; position: absolute; left: 0px; top: 0px; "></div>
                  <!-- 现在我想实现鼠标的拖动事件 -->
              <script>
                   var div = document.getElementsByTagName("div")[0];
                   div.onmousedown = function(ev){  //鼠标按下执行的函数
                       //event的兼容性
                       var ev = ev||window.event;
                       //获取鼠标按下的坐标
                       var x1 = ev.clientX;
                       var y1 = ev.clientY;
                       //获取元素的left,top值
                       var l = div.offsetLeft;   //直接返回的数字,没有px
                       var t = div.offsetTop;
                       //给可视区域添加鼠标的移动事件
                       document.onmousemove = function(ev){   //鼠标移动执行的函数
                           //event的兼容性
                           var ev = ev||window.event;
                           //获取鼠标移动时的坐标
                           var x2 = ev.clientX;
                           var y2 = ev.clientY;
                           //计算出鼠标的移动距离
                           var x = x2-x1;
                           var y = y2-y1;
                           //移动的数值与元素的left,top相加,得出元素的移动的距离
                           var lt = y+t;
                           var ls = x+l;
                           //更改元素的left,top值
                           div.style.top = lt+'px';
                           div.style.left = ls+'px';
                       }
                       //清除
                       document.onmouseup = function(ev){  //鼠标按键抬起执行的函数
                           document.onmousemove = null;
                       }
                   }
              </script>
posted @ 2019-12-01 18:05  杨超(yc)  阅读(302)  评论(0编辑  收藏  举报