第九周第三天笔记

事件

1 事件流

  • 冒泡:从该元素开始由里向外触发一类事件,事件对象中的事件源为该元素,触发同一类事件,在子级父级祖级中拿到的事件源一样,均为被触发元素;

    • 阻止冒泡:e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
    • 关于冒泡的运用:典型的是事件委托
      • 事件委托:将事件添加到最高级元素上,事件中获取事件源的属性,当触发某元素上的事件时,就会在最高级中获取事件源,也就是该元素;
    • 实例1:在多层嵌套的div中,点击哪个元素,就弹出哪个元素的class名;
      • 方法:
        • 1)遍历div,给每个元素添加点击事件,然后弹出class名,但是会出现冒泡事件,所以必须阻止冒泡事件
        • 2)事件委托
       
       
       
           
           冒泡与阻止冒泡
           
       
       
       
      div1
      div2
      div3
    • 实例2:在body元素中有多个div元素,在点击里面的a链接后,就删除该a元素的父级div;
      • 方法:事件委托给最高级body元素,给body添加点击事件,然后在事件匿名函数中获取事件源,然后删除事件源的父级div;
       
       
       
           
           事件委托
           
       
       
       
       
       
       
      
    • 注:某个元素事件发生,不用给其添加代码,只要在它身上触发该事件就行,添加代码,只不过给其设置一个能够显现出来的动作而已,不添加,也会触发;
  • onmouseenter、onmouseleave、onmouseover、onmouseout四者关系解读

    • 相同点:都是添加鼠标移入移出事件
    • 不同点:onmouseover和onmouseout中会存在冒泡事件;onmouseenter和onmouseleave中不存在冒泡事件;
    • 实例解读:
      • 需求:当鼠标移动到div元素身上时,p元素显示,显示的时候,移动到p元素身上,仍然显示,移动到div和p元素之外的位置,p元素再隐藏;
      • 方法:
        • 使用onmouseenter与onmouseleave设置:当光标从div上移出到p元素上时,没有打印out,也没有再次打印in,意思是两个事件都没有被触发,指的就是当移动到子级身上时,根本不算移出;所以给oDiv元素添加onmouseenter事件,指的是当光标移入到它或者是它的子级,都会触发事件;不是冒泡事件,而是将oDiv和它的子级作为了一个整体;
        • 使用onmouseover与onmouseout设置:使用onmouseover和onmouseout也会实现需求,但是实现的过程不同,当光标移入div会触发onmouseover事件,然后打印in,当光标从div元素上移出并立刻进入p元素时,此时发生了两个过程,移出div时,会触发div的onmouseout事件,打印out,并使p隐藏;然后迅速进入p元素,此时触发p元素的onmouseover事件,但是没有动作,会通过冒泡事件,连带父级div触发onmouseover事件,所以再次打印in,然后p显示;所以肉眼没有发现p被隐藏,又被显示。当移出p元素时也是通过冒泡事件,将父级onmouseout事件触发,进而打印out,使p隐藏;
       
       
       
           
           onmouseenter与onmouseleave解读
           
       
       
       

  • 冒泡的问题:给父级添加事件后,在子级上触发,还会触发父级的事件,会重复触发,造成性能不好,还会造成代码混乱;

    • 解决方法:在子级中添加相同事件,并在事件中阻止冒泡;代码:e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
    • 通过关联元素获取到子级,然后判断阻止,此方法只能解决代码混乱问题,不会进行性能优化,父级事件还会因子级事件触发而触发,只不过是在父级事件中阻断了一些代码的执行,避免重复设置,造成混乱;
    • 在父级事件函数中,通过事件对象获取事件源,通过事件源来筛选触发元素,不能阻止冒泡事件发生,但是可以阻止,当从子级触发时,不会再执行父级函数体内的代码;
  • 冒泡的问题及解决问题的实例:

    • 实例1:当鼠标滑到div上时,新建一个p元素,让其跟随光标移动,当光标移出div后,p元素消失;
      • 问题:当鼠标移动到子级p身上的时候,会触发鼠标事件,通过冒泡触发父级身上的鼠标事件,进而再新建一个p元素,进而出错;
      • 解决方法:1)将子级p元素中的冒泡事件阻止,这样父级就不会被关联触发;2)利用对象事件上的属性获取添加事件元素的关联元素,判断当包含时,则阻止程序执行,进而不会被影响;3)利用onmouseenter和onmouseleave添加事件;
      • 注意:鼠标移动事件太灵敏,所以需要在定位数值设置时使光标与定位元素有一段距离;
      • 代码:
       
       
       
           
           实例2
           
       
       
       
    • 实例2:当鼠标移动到div元素身上时,p元素显示,显示的时候,移动到p元素身上,仍然显示,移动到div和p元素之外的位置,p元素再隐藏;
      • 问题:当鼠标移动到子级p元素身上时,会触发p元素的鼠标事件,进而再次触发父级div的鼠标事件,这样就会重复触发,性能不好,所以要阻止子级的冒泡事件
      • 解决方法:1)在子级中阻止冒泡事件,但是需要在子级中添加显示隐藏;2)通过对象事件获取关联元素;3)设置onmouseenter和onmouseleave事件,能够解决性能问题,事件只触发一次
      • 注意:关联元素的方法可取,但是没有解决性能问题,因为滑到子级上,还是会触发父级的鼠标事件,没有完成性能优化,此处要注意的是,显示隐藏代码一定要设置在判断元素之后;在父级事件中代码执行前,判断关联元素的目的:是阻止父级事件中代码的执行,不会阻止冒泡事件的发生;
      • 代码:
       
       
       
           
           冒泡问题解读
           
       
       
       

    • 实例3:当鼠标移上div元素身上时,p显示;移出div元素后,p隐藏;强调:移出到任何位置,p都隐藏,移动p元素身上,也必须隐藏;
      • 问题:当鼠标移动到子级p元素身上时,会触发p元素的鼠标事件,进而再次触发父级div的鼠标事件,这样就会重复触发,性能不好,同时当鼠标移动到子级p元素身上的时候,子级不会隐藏,所以要阻止子级的冒泡事件;
      • 解决方法:1)在子级元素身上绑定同行为事件,然后在事件函数中阻止冒泡发生;2)在父级元素中,通过事件对象获取事件源,然后判断事件源的nodeName来获取元素TagName名,判断是否为父级元素标签,若不是,则阻止代码执行;
      • 代码:
       
       
       
           
           需求2
           
       
       
       

  • 购物车点击版实例

    • 需求:当点击div元素及p元素时,p元素显示,点击除二者以外的任何区域都让p隐藏
    • 思路:如果一个父级容器下添加多个事件,那么就将事件委托给父级容器,通过判断事件源来进行相应的操作;
    • 方法:1)通过开关思想,控制隐藏与显示,但是会存在一个问题,在第二个判断中如果不设置bOk=true,就会出现,第一次点击div后,p显示,然后点击外面,p消失,但此时的bOk为false,再次点击div时,会走else语句,不会显示;所以必须设置bOk=true; 2)通过判断p的行间样式是否为block来控制显示和隐藏;3)通过给父级容器添加点击事件,然后通过事件对象来获取事件源,判断事件源的nodeName是否为div和p的tagName名,若是二者之一,则设置p为显示,若都不是,则设置p为隐藏;
    • 知识点:事件委托的应用环境及行间样式的获取
    • 代码:
     
     
     
         
         购物车点击版实例
         
     
     
     

  • 购物车点击版实例2

    • 需求:当点击div时,p显示,当移出div后,p隐藏,但是保证从div移出到p元素身上时,p不隐藏,从p上移出后,p隐藏;
    • 方法:1)用onclick和onmouseleave事件设置;2)用onclick和onmouseout事件设置,但是用onmouseout事件设置,会存在问题:当移出div到p元素身上后,p会隐藏;所以需要获取关联元素,阻断隐藏代码;
    • 知识点:onmouseout与onmouseleave的区别,以及关联元素的获取及阻断代码执行;
    • 代码:
     
     
     
         
         购物车实例
         
     
     
     

知识点扩充

  • 定位:
    • 页面结构中元素A包含着B元素,A为父级元素,B为子级元素,B相对于A定位
    • B的盒子模型是包含margin在内的大盒子,然后相对于A的边框内边缘定位,即若B的margin设置为0,并且定位中left也设置为0,则B的左边框外边缘与A的左边框内边缘贴合,当添加margin之后,二者之间会存在相应间隔;
    • 总结:子级元素盒子模型(包含margin)相对于定位父级的边框内边缘进行定位;

你可能感兴趣的:(第九周第三天笔记)