第二十七课:滚轮事件,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实现显隐效果了。
加油!
第二十七课:滚轮事件,mouseenter与mouseleave事件的修复的更多相关文章
- NeHe OpenGL教程 第二十七课:影子
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- 星星打分,今天我们就用Jq代码来实现,看看究竟是如何实现的 其中有两个重要的事件mouseenter和mouseleave效果如下图
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <met ...
- python第二十七课——os模块
演示os模块中常用的属性和函数: 1.os模块: 作用:管理文件和目录 属性: os.name:返回系统类型 常用的windows系统 --> nt os.environ:返回当前系统所有的环境 ...
- Python学习第二十七课——写一个和Django框架的自己的框架
MyWeb框架: from wsgiref.simple_server import make_server def application(environ, start_response): pri ...
- 简单深刻:为控件创建MouseEnter和MouseLeave事件(覆盖WndProc,增加对消息的处理,真简单!)——连对CM_MOUSEENTER的消息处理都是颇有深意啊!
其实很简单: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, D ...
- 潭州课堂25班:Ph201805201 django 项目 第二十七课 docker简介,配置文件 (课堂笔记)
新闻搜索功能实现 一.docker介绍 1.什么是docker? 使用容器让创建.部署.运行应用程序更简单的一个工具 让应用所需的库和依赖环境打包 有一点点像虚拟机 2.为什么使用docker? 3. ...
- Spring入门第二十七课
声明式事务 直接上代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Dri ...
- JAVA学习第二十七课(多线程(六))- 多生产者多消费者问题(JDK1.5新特性)
多生产者多消费者问题 以生产馒头 消费馒头为例. class Resource { private String name; private int count = 1; private boolea ...
- mouseenter以及mouseleave兼容性
在IE的全系列中都实现了mouseenter和mouseleave事件,但是在早期的w3c浏览器中却没有实现这两个事件.有时候,我们需要使用 mouseenter事件来防止子元素的冒泡,这就涉及到事件 ...
随机推荐
- Linux objcopy命令
一.简介 [功能] 将目标文件的一部分或者全部内容拷贝到另外一个目标文件中,或者实现目标文件的格式转换. [描述] objcopy工具使用BFD库读写目标文件,它可以将一个目标文件的内容拷贝到另外一个 ...
- Intent详解
ntent组件虽然不是四大组件,但却是连接四大组件的桥梁,学习好这个知识,也非常的重要. 一.什么是Intent 1.Intent的概念: Android中提供了Intent机制来协助应用间的交互与通 ...
- [译]OpenStack Object Storage Monitoring
注:翻译的不完整,主要是有些地方翻译后反而妨碍理解,有些不知道怎么翻,anyway,需要时拿来用用也是可行的,顺便共享啦.欢迎提意见. 一个OpenStack Object Storage(OSOS) ...
- 怎么运用好ZBrush中Magnify膨胀笔刷
Magnify膨胀笔刷是ZBrush笔刷中经常使用的,利用该笔刷可绘制中心向四周膨胀的效果.本文内容向大家介绍ZBrush®中膨胀笔刷以便大家熟悉它的用法和特性. 查看更多内容请直接前往:http:/ ...
- HTML meta viewport属性详解
什么是Viewport 手机浏览器是把页面放在一个虚拟的“窗口”(viewport)中,通常这个虚拟的“窗口”(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中(这样会破坏没有针对手机 ...
- jquery和css自定义video播放控件
下面介绍一下通过jquery和css自定义video播放控件. Html5 Video是现在html5最流行的功能之一,得到了大多数最新版本的浏览器支持.包括IE9,也是如此.不同的浏览器提供了不同的 ...
- HDU 4964 Emmet --模拟
题意:给你一个字符串,要求把它按语法转化成HTML格式. 分析:这题其实不难,就是一个递归的事情,当时忽略了括号嵌套的情况,所以一直WA,后来加上这种情况后就过了.简直醉了. 处理id和class时, ...
- RabbitMQ 一二事(3) - 订阅模式(微信公众号模式)的应用
之前讲的消费者互相可以把队列中的消息全部读取,但是不是读完整的所有信息 那么采用订阅模式就行,这就是微信公众号的模式, 比如10个人订阅了我的公众号"BeJavaGod",当我发送 ...
- AC日记——过河卒 洛谷 1002
题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. ...
- [3D跑酷] MissionManager
前言 许久没有更新日志了,之前写了GUIManager,GUIClickEventReceiver还有AudioManager,这次写MissionManager 引用关系 首先看下MissionMa ...