0

0

了解JS滚轮事件(mousewheel/DOMMouseScroll)

coldplay.xixi

coldplay.xixi

发布时间:2020-06-13 17:48:42

|

4960人浏览过

|

来源于liqingbo

转载

了解JS滚轮事件(mousewheel/DOMMouseScroll)

JS滚轮事件(mousewheel/DOMMouseScroll)了解

一、学无止境、温故知新

//zxx: 本段与技术无关,一些很个人的吐槽,可以跳过
已经没有了小学生时代过目不忘的记忆力了,很多自己折腾的东西、接触的东西,短短1年之后就全然不记得了。比方说,完全记不得获取元素与页面距离的方法(getBoundingClientRect),或者是不记得现代浏览器下触发DOM自定义事件的方法(dispatchEvent). 显然,适当的温习,翻阅以前的东西,或者自己空余时间处理相关的东西还是有必要的。其实,细想,东西记不住是自己自身原因,在折腾的时候就没有想方设法牢记(而不是通过反复使用记住)。比方说getBoundingClientRect就是“得到客户端矩形边界”的意思,或者使用邪恶记法记住“割(g)逼(b)艹(c)软(r)”。dispatchEvent方法使用“3步走”,“创建(createEvent)-初始(init*Event)-分派(dispatchEvent)”。

学习的脚步不能停止。一站到底的那些“变态”们也有不知道的东西,显然,我们这些草辈,尤其年轻的自己,不知道的更多。谁年轻的时候没有过或多或少 的迷茫,问自己“路在何方”,问自己“该做哪个方向”,无论你选择的是什么,学习的脚步是不能停止的。坚持着坚持着,路自然就会清晰,你就会知道接下来该 怎么走了。只怕畏首畏尾,得过且过,年轻就是资本,义无反顾前行吧。

我凭着兴趣走上现在的道路,完全是兴趣学习(我喜欢这些,我要学),不是职业学习(做前端需要什么,我就去学什么)。工作的这些年,技术、产品的自 我沉浸不知不觉限制了自己的眼界,好在意识到问题的存在其实已经解决了问题的一半。这里之所以会说这些是想提醒自己,万万不可矫枉过正,技术、产品的学习 还是主要的,只是要多多抬头看看办公室之外的世界(不是刷微博获得的浅认识)。

昨天机缘巧合遇到“滚轮事件”,以前折腾“自定义滚动条”时候使用过鼠标滚轮事件,不过这是基于MooTools已经兼容好的mousewheel事件实现的,如果要说出其中的实现机制,浏览器兼容差异等,就傻眼了。学无止境,因此,查阅之,实践之,整理之。

二、兼容差异大全

滚轮事件的兼容性差异有些不拘一格,不是以往的IE8-派和其他派,而是FireFox派和其他派。

包括IE6在内的浏览器是使用onmousewheel,而FireFox浏览器一个人使用DOMMouseScroll. 经自己测试,即使现在FireFox 19下,也是不识onmousewheel。

一个最简单的使用差异(body滚动条由内部一定高div撑开):

document.body.onmousewheel = function(event) {    event = event || window.event;    console.dir(event); };

document.body.addEventListener("DOMMouseScroll", function(event) {
    console.dir(event);
});

以上输出差异见下面(IE7, IE10, Chrome, 以及FireFox,鼠标向下滚动, win7)(可点击此页面单独查看表格内容):

超能文献
超能文献

超能文献是一款革命性的AI驱动医学文献搜索引擎。

下载

三、兼容的滚轮事件方法

知己知彼百战百胜,知道了差异就知道如何处理这些差异。毕竟不是写JS库,我们这里只处理滚动方向这块的差异。

整合我们通常事件添加方法,于是有(下代码代号为addEvent.js):

/**
 * 简易的事件添加方法
 */
 define(function(require, exports, module) {
    exports.addEvent = (function(window, undefined) {        
        var _eventCompat = function(event) {
            var type = event.type;            if (type == 'DOMMouseScroll' || type == 'mousewheel') {
                event.delta = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
            }
            //alert(event.delta);
            if (event.srcElement && !event.target) {
                event.target = event.srcElement;    
            }
            if (!event.preventDefault && event.returnValue !== undefined) {
                event.preventDefault = function() {
                    event.returnValue = false;
                };
            }            /* 
               ......其他一些兼容性处理 */
            return event;
        };
        if (window.addEventListener) {
            return function(el, type, fn, capture) {                if (type === "mousewheel" && document.mozHidden !== undefined) {
                    type = "DOMMouseScroll";
                }
                el.addEventListener(type, function(event) {
                    fn.call(this, _eventCompat(event));
                }, capture || false);
            }
        } else if (window.attachEvent) {
            return function(el, type, fn, capture) {
                el.attachEvent("on" + type, function(event) {
                    event = event || window.event;
                    fn.call(el, _eventCompat(event));    
                });
            }
        }
        return function() {};    
    })(window);        
});

于是,我们就可以很从容使用mousewheel事件了。例如:

addEvent(dom, "mousewheel", function(event) {
    if (event.delta < 0) { alert("鼠标向上滚了!"); }
});

相关代码实现如下,下面这个展示的就是平滑移动的核心代码们(代号为slide.js):

/**
 * 简易的列表左右滑动切换效果
 * 鼠标事件是关键,因此,一些数值写死在方法中,纯测试用
 */
 define(function(require, exports, module) {    var Event = require("/study/201304/addEvent.js");
    var _move = function(ele, to, from) {        // 动画实现
        // ...
    };
    return {
        index: 0,
        visible: 4,
        init: function(box) {            // box指滚动的列表容器
            var self = this
              , length = box.getElementsByTagName("li").length;            Event.addEvent(box.parentNode, "mousewheel", function(event) {
                 if (event.delta > 0 && self.index > 0) {                    // 往上滚
                    self.index--;
                 } else if (event.delta < 0 && self.index < length - self.visible) {                     // 往下
                     self.index++;                     
                 } else {
                    return; 
                 }
                 _move(box, -1 * self.index * 140);    
              
                 event.preventDefault();
            });
        }
    };
});

原理很简单,滚轮改变,索引改变,也就是列表的最终位置改变,动画到目标位置即可。

然后,demo页面使用seajs简单调用就可以了!

var $ = function(id) {
    return document.getElementById(id);
};
seajs.use("/study/201304/slide.js", function(slide) {
    slide.init($("slideBox"));
});

就结束了,一些具体细节,例如关于HTML部分,或者动画的实现等,可以去demo等查看代码展示。

不过从效果来看,IE6以及IE7浏览器下的滚动并没有hold页面的滚动条,多番其他尝试也是如此,希望可以有相关经验的同行指点下,优化IE7/IE7浏览器下的体验效果。

原本还想再添加一个自定义滚动条的demo的,一看时间,我勒个去,已经1:11:11了,好不吉利的数字啊,看了下程序员运势万年历,今天不适宜写demo。于是,结语睡觉。

推荐教程:《JS基础教程

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

1016

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

813

2023.11.06

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

530

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

514

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

678

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

5904

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

492

2023.09.01

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

219

2023.09.04

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

48

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
UNI-APP开发(仿饿了么)
UNI-APP开发(仿饿了么)

共32课时 | 8.9万人学习

JS轻松实现打地鼠游戏
JS轻松实现打地鼠游戏

共6课时 | 0.7万人学习

JS抽象类和事件设计模式视频教程
JS抽象类和事件设计模式视频教程

共25课时 | 5.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号