您的位置 首页 技术

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

JS滚轮事件(mousewheel/DOMMouseScroll)了解 一、学无止境、温故知新 //zxx: 本段与技术无关,一些很个人的吐槽,可以跳过已经没有了小学生时代过目不忘…

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)(可点击此页面单独查看表格内容):

三、兼容的滚轮事件方法

知己知彼百战百胜,知道了差异就知道如何处理这些差异。毕竟不是写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基础教程》

以上就是了解JS滚轮事件(mousewheel/DOMMouseScroll)的详细内容,更多请关注24课堂在线网其它相关文章!

本文来自网络,不代表24小时课堂在线立场,转载请注明出处:http://www.24ketang.cn/76305.html

为您推荐

发表评论

电子邮件地址不会被公开。 必填项已用*标注

返回顶部