第二十七课:滚轮事件,mouseenter与mouseleave事件的修复

滚轮事件

jQuery核心库没有对mousewheel事件的差异性进行处理,但作为一个常用的事件,本文讲解一下。

mousewheel事件只有火狐浏览器不支持。mousewheel用于取得滚动距离的属性名为event.wheelDelta,往上滚一圈是120,往下滚一圈是-120.在IE6-8下,window无法绑定mousewheel事件,Opera,Safari,Chrome可以。

火狐下使用DOMMouseScroll来代替mousewheel事件。用于取得滚动距离的属性名为event.detail。往上滚一圈是-3,往下滚一圈是3.当我们按住ctrl,alt,shift键,再滚动鼠标滚轮时,detail的值就会变成-1和1.而且在按住ctrl键时,滑动滚轮还有缩放页面的功能,我们可以通过event.axis == event.HORIZONTAL_AXIS或event.axis == event.VERTICAL_AXIS得知是水平滚动还是垂直滚动。

兼容方案如下:

var wheel = function(obj,callback){

  var wheelType = "mousewheel";

  try{

    document.createEvent("MouseScrollEvents");   //创建DOMMouseScroll事件,如果是火狐就会执行,不是火狐,就报错

    wheelType = "DOMMouseScroll";

  }catch(){}

  addEvent(obj,wheelType,function(event){    //给对象obj绑定鼠标滚动事件

    if("wheelDelta" in event){   //统一为120,其中正数为向上滚动,负数代表往下滚动

      var delta = event.wheelDelta;

      if(window.opera && opera.version()<10){  //opera9系列的方向跟上面的相反

        delta = -delta

      }

      event.delta = Math.round(delta) / 120; //早期的safari会出现浮点数。为什么不赋值给wheelDelta,因为事件对象的原始属性是只读的,因此我们只能添加一个自定义属性delta来解决兼容性问题

    }

    else if("detail" in event){  //如果是火狐

      event.wheelDelta = -event.detail * 40;  //修复事件的wheelDelta属性,这样,火狐浏览器的这个属性就跟标准一样了

      event.delta = event.wheelDelta / 120;   //添加自定义属性delta解决兼容性问题

    }

    callback.call(obj,event);//这里的event.delta属性值是所有浏览器兼容的,往上一圈为1,往下一圈为-1.而event.wheelDelta属性在opera9系列和早期的safari中仍然存在问题,在其他浏览器下是正常的,往上一圈是120,往下一圈是-120.

  })

}

滚轮事件触发页面的加载是电商领域必须知道的技术点,面试前一定要去了解一下整个流程。

mouseenter与mouseleave事件

在前端开发中,我们经常遇到隐藏弹出层或下拉菜单的需要。这就是所谓的显隐效果。我们经常使用mouseenter和mouseleave来实现。为什么不用mouseover和mouseout来实现呢,我来说一下这个问题:假设弹出层里面有无数子孙元素,我们的mouseout只监听弹出层最外面的大容器,我们很容易就移出这个大容器(鼠标移动到大容器的子元素,对于mouseout来说也算移出),但是实际上在鼠标还是在大容器范围内,会让判断失效。但mouseleave就不会,只有鼠标跑到大容器的外面才会触发,这是因为mouseenter和mouseleave不会冒泡。

但是webkit浏览器下不支持mouseenter和mouseleave事件。如何在不支持这两个事件的浏览器中模拟它们:

jQuery.each(

  {  

    mouseenter:"mouseover",

    mouseleave:"mouseout"

  },

  function(orig, fix){   //orig是mouseenter,fix是mouseover

    jQuery.event.special[orig] = {    //把mouseenter事件当做特殊事件处理

      delegateType:fix,   //用mouseover伪装mouseenter

      bindType: fix,

      handle:function(event){   //这时的event已经被修复了

        var ret,target = this,handleObj = event.handleObj, related = event.relatedTarget;//对mouseover事件而言,事件的主目标是获得光标的元素,而相关元素就是那个失去光标的元素。类似地,对mouseout事件而言,事件的主目标是失去光标的元素,而相关元素则是获得光标的元素。IE下不支持这个属性,这个relatedTarget属性是在修复event时修复的,在IE下,它的值在mouseover时,等于fromElement(假设从div1移动到目标元素div2,那么这时的fromElement是div1),在mouseout时,等于toElement(假设从目标元素div2移出来到div1中,那么这时的toElement是div1)。

        if(!related || (related ! == target && !jQuery.contains(target,related))){ //这时related=div1,target = div2,并且div2不包含div1,就是if语句执行回调方法,模拟mouseenter,mouseleave。如果是在div2中移动,比如移动到div2的子元素div3中,这时会触发div2的mouseout事件,这时target就是div2,relatedTarget就是div3,但是target包含related,所以不会进入if语句,解决了mouseover显隐时的问题。同时也会触发div3的mouseover事件,然后冒泡到div2,这时target就是div2,relatedTarget也是div2,所以也不会进入if语句。

          event.type = handleObj.origType;   //事件的原始类型,也就是mouseenter

          ret = handleObj.handler.apply(this,arguments);  //执行回调方法

          event.type = fix;   //事件的修复类型,也就是mouseover

        }

        return ret;

      }

    }

  }

)

related也有不存在的情况下,比如,从窗口外面直接进入到div2. 这样就能在所有浏览器下通过mouseenter和mouseleave实现显隐效果了。

加油!

时间: 2024-10-28 19:10:24

第二十七课:滚轮事件,mouseenter与mouseleave事件的修复的相关文章

第二十七课

第一单元语法部分        Vて行く Vて来る「行く.来る」有方向性.以某物为参照物.接在「Vて」形式后面,表示完成V动作后进行方向性移动.     Vていく    ①表示移动时的状态.“…着去,…去”        例:学校まで走っていこう.    ②表示远离说话人而去.         例:船はどんどん遠くに離れていった.    ③表示做完某动作行为再去.“…了再去”        例:母の誕生日だから.途中で花を買って行きました.    ④以某一时间为基准,变化或动作继续下去.“…下去

linux学习笔记-第二十七课-tamcat与resin

一.tomcat 1. 安装JDK [[email protected] src]# tar -zxvf jdk-7u79-linux-i586.tar.gz # 编辑初始化信息脚本 [[email protected] src]# mv jdk1.7.0_79  /usr/local/jdk1.7.0_79 [[email protected] src]# vim /etc/profile.d/java.sh JAVA_HOME=/usr/local/jdk1.7.0_79 JAVA_BIN=

为控件创建MouseEnter和MouseLeave事件(覆盖WndProc,增加对消息的处理)——真简单!

其实很简单: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TURLLabel = class(TLabel) procedure WndProc(var Message : TMessage); override; end; type TForm1 = class(TForm) procedure FormCr

Spring入门第二十七课

声明式事务 直接上代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring jdbc.initPoolSize=5 jdbc.maxPoolSize=10 applicationContext.xml <?xml version="1.0" encodin

ParisGabriel:Python全栈工程师(0基础到精通)教程 第二十七课(类变量、方法、继承、覆盖)

ParisGabriel 每天坚持手写  一天一篇  决定坚持几年 为了梦想为了信仰  开局一张图 Python人工智能从入门到精通 补充: 实例方法都是操作实例对象的 属于此类对象的方法 实例变量 添加/修改属性: 对象.属性名 = 表达式 删除: del 对象.属性名 类 |          对象 | 实例 class  object     instance 类的本质上也是对象 类可以创建此类对象 ---------------------------------------------

第二十七课 再论智能指针(上)

思考: 使用智能指针替换单链表LinkLIst中的原生指针是否可行? 将LinkList.h中的Node指针全部改成智能指针: 1 #ifndef LINKLIST_H 2 #define LINKLIST_H 3 4 #include "List.h" 5 #include "Exception.h" 6 #include "SmartPointer.h" 7 8 namespace DTLib 9 { 10 11 template <

Jquery hover方法使用及 mouseenter与mouseleave和 mouseover与mouseout的区别

定义和用法 hover() 方法规定当鼠标指针悬停在被选元素上时要运行的两个函数. jQuery 1.7 版本前该方法触发 mouseenter 和 mouseleave 事件. jQuery 1.8 版本后该方法触发 mouseover和 mouseout事件. 语法 $(selector).hover(inFunction,outFunction)//inFunction 必需,规定 mouseover 事件发生时运行的函数:outFunction 可选,规定 mouseout 事件发生时运

mouseout和mouseover、mouseenter和mouseleave

      在前端开发中经常会碰到当鼠标放到一个元素上时会弹出你一个元素,鼠标离开那个弹出元素后隐藏.这类效果一般要用到一些鼠标事件,一类是mouseout和mouseover,另一类是mouseenter和mouseleave. 其中mouseout和mouseover是会冒泡的,可能会出现不想要的结果:而mouseenter和mouseleave是不会冒泡,这个比较理想.但mouseenter和mouseleave只有在IE下才支持.想要在Firefox下用就必须实现mouseenter和m

mouseenter以及mouseleave兼容性

在IE的全系列中都实现了mouseenter和mouseleave事件,但是在早起的w3c浏览器中却没有实现这两个事件.有时候,我们需要使用 mouseenter事件来防止子元素的冒泡,这就涉及到事件兼容性的问题了. 先比较mouseenter和mouseover的异同点,当从元素外围进入元素内部时同时触发mouseover和mouseenter事件,但是在元素内部, 鼠标进入元素子节点时会继续触发mouseover事件,该事件是可以向上冒泡的:对于mouseenter则不会冒泡,当然也不会触发