鼠标滚轮事件和Mac触控板双指事件


Posted in HTML / CSS onDecember 23, 2019

因为下一阶段要做的一个工作是开发一个WEB端的K线图,所以这一周一直在研究这方面的东西,其中涉及到的一个知识点是鼠标滚轮事件和Mac的触控板双指事件,发现这里面还是有一些坑的。

1. 用哪个事件

The wheel event fires when the user rotates a wheel button on a pointing device (typically a mouse). This event replaces the non-standard deprecated mousewheel event.

以前常使用的mousewheel事件已经逐渐被官方废弃了,改用wheel事件代替,所以这里会优先使用wheel,并向下兼容。

另外,即使是wheel事件,各浏览器的表现也可能不尽相同,都是各大浏览器自己的规范,官方并没有一个标准,虽然我也不知道为什么。

2. 兼容写法

// creates a global "addWheelListener" method
// example: addWheelListener( elem, function( e ) { console.log( e.deltaY ); e.preventDefault(); } );
(function(window,document) {

    var prefix = "", _addEventListener, onwheel, support;

    // detect event model
    if ( window.addEventListener ) {
        _addEventListener = "addEventListener";
    } else {
        _addEventListener = "attachEvent";
        prefix = "on";
    }

    // detect available wheel event
    support = "onwheel" in document.createElement("div") ? "wheel" : // 各个厂商的高版本浏览器都支持"wheel"
              document.onmousewheel !== undefined ? "mousewheel" : // Webkit 和 IE一定支持"mousewheel"
              "DOMMouseScroll"; // 低版本firefox

    window.addWheelListener = function( elem, callback, useCapture ) {
        _addWheelListener( elem, support, callback, useCapture );

        // handle MozMousePixelScroll in older Firefox
        if( support == "DOMMouseScroll" ) {
            _addWheelListener( elem, "MozMousePixelScroll", callback, useCapture );
        }
    };

    function _addWheelListener( elem, eventName, callback, useCapture ) {
        elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function( originalEvent ) {
            !originalEvent && ( originalEvent = window.event );

            // create a normalized event object
            var event = {
                // keep a ref to the original event object
                originalEvent: originalEvent,
                target: originalEvent.target || originalEvent.srcElement,
                type: "wheel",
                deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1,
                deltaX: 0,
                deltaZ: 0,
                preventDefault: function() {
                    originalEvent.preventDefault ?
                        originalEvent.preventDefault() :
                        originalEvent.returnValue = false;
                }
            };
            
            // calculate deltaY (and deltaX) according to the event
            if ( support == "mousewheel" ) {
                event.deltaY = - 1/40 * originalEvent.wheelDelta;
                // Webkit also support wheelDeltaX
                originalEvent.wheelDeltaX && ( event.deltaX = - 1/40 * originalEvent.wheelDeltaX );
            } else {
                event.deltaY = originalEvent.detail;
            }

            // it's time to fire the callback
            return callback( event );

        }, useCapture || false );
    }

})(window,document);

这个是MDN 上推荐的兼容写法,可以看到这几个事件的顺序是 wheel > mousewheel > DOMMouseScroll。如果使用wheel事件,event不做处理。否则,重新封装了event。

3. 方向判断

鼠标滚轮的话,只有上、下两个方向,但是如果是触摸板的双指行为的话,除了上、下以外,还有左、右方向,以及双指向内收缩、向外扩张四种情况,接下来,就对这几种情况做判断处理。
 

function wheelEvent (e) {
    if (Math.abs(e.deltaX) !== 0 && Math.abs(e.deltaY) !== 0) return console.log('没有固定方向');
    if (e.deltaX < 0) return console.log('向右');
    if (e.deltaX > 0) return console.log('向左');
    if (e.ctrlKey) {
        if (e.deltaY > 0) return console.log('向内');
        if (e.deltaY < 0) return console.log('向外');
    } else {
        if (e.deltaY > 0) return console.log('向上');
        if (e.deltaY < 0) return console.log('向下');
    }
}

经过测试,delta是用来判断方向最好的一个值,wheelDelta和detail都有各自的兼容等问题。

deltaX是左右方向的滑动,deltaY是上下方向。

向里收缩是和向下滚动相同,向外扩张是和向上滚动相同。这是正常的用户习惯,但是麻烦的是事实刚好和我们的习惯相反,这样单纯依靠deltaY来判断是区分不开的。

经过测试ctrlKey这个字段只有在双指方向不一致时,才会为true。这样就能区分开了,从而产生了6种情况,逐一处理。

所以上面的兼容写法还需要将ctrlKey返回。

ctrlKey: originalEvent.ctrlKey || false,

这个问题解决了,之后会抽时间把K线图的代码整理一下。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3弹性布局内容对齐(justify-content)属性使用详解
Jul 31 HTML / CSS
CSS3 Pie工具推荐--让IE6-8支持一些优秀的CSS3特性
Sep 02 HTML / CSS
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
Dec 29 HTML / CSS
html5 桌面提醒:Notifycations应用介绍
Nov 27 HTML / CSS
HTML5之SVG 2D入门5—颜色的表示及定义方式
Jan 30 HTML / CSS
HTML5梦幻之旅——炫丽的流星雨效果实现过程
Aug 06 HTML / CSS
HTML5使用drawImage()方法绘制图像
Jun 23 HTML / CSS
HTML5触摸事件实现移动端简易进度条的实现方法
May 04 HTML / CSS
使用PDF.JS插件在HTML中预览PDF文件的方法
Aug 29 HTML / CSS
HTML5中的Web Notification桌面通知功能的实现方法
Jul 29 HTML / CSS
关于webview适配H5上传照片或者视频文件的方法
Nov 04 HTML / CSS
HTML5 语义化标签(移动端必备)
Aug 23 HTML / CSS
HTML5 Canvas 实现K线图的示例代码
Dec 23 #HTML / CSS
html5利用canvas实现颜色容差抠图功能
Dec 23 #HTML / CSS
HTML5 客户端数据库简易使用:IndexedDB
Dec 19 #HTML / CSS
吃透移动端 Html5 响应式布局
Dec 16 #HTML / CSS
HTML文本属性&amp;颜色控制属性的实现
Dec 17 #HTML / CSS
吃透移动端 1px的具体用法
Dec 16 #HTML / CSS
关于html字符串正则判断和匹配的具体使用
Dec 12 #HTML / CSS
You might like
日本十大最佳动漫,全都是二次元的神级作品
2019/10/05 日漫
咖啡产品发展的三大浪潮
2021/03/04 咖啡文化
php小型企业库存管理系统的设计与实现代码
2011/05/16 PHP
PHP封装分页函数实现文本分页和数字分页
2014/10/23 PHP
php开发工具有哪五款
2015/11/09 PHP
PHP开发的微信现金红包功能示例
2017/06/29 PHP
JavaScript 加号(+)运算符号
2009/12/06 Javascript
JavaScript中的noscript元素属性位置及作用介绍
2013/04/11 Javascript
jQuery表单美化插件jqTransform使用详解
2015/04/12 Javascript
jQuery解析XML文件同时动态增加js文件的方法
2015/06/01 Javascript
原生JavaScript制作微博发布面板效果
2016/03/11 Javascript
vue.js 使用v-if v-else发现没有执行解决办法
2017/05/15 Javascript
jQuery实现表格冻结顶栏效果
2017/08/20 jQuery
详解vue-cli构建项目反向代理配置
2017/09/07 Javascript
Vue的轮播图组件实现方法
2018/03/03 Javascript
原生JS+HTML5实现跟随鼠标一起流动的粒子动画效果
2018/05/03 Javascript
vue draggable resizable 实现可拖拽缩放的组件功能
2019/07/15 Javascript
基于JS实现快速读取TXT文件
2020/08/25 Javascript
微信小程序组件生命周期的踩坑记录
2021/03/03 Javascript
[01:31:22]DOTA2-DPC中国联赛定级赛 LBZS vs Magma BO3第二场 1月10日
2021/03/11 DOTA
Python多线程学习资料
2012/12/19 Python
python字符串str和字节数组相互转化方法
2017/03/18 Python
python爬虫之线程池和进程池功能与用法详解
2018/08/02 Python
python 高效去重复 支持GB级别大文件的示例代码
2018/11/08 Python
Python文件操作函数用法实例详解
2019/12/24 Python
匈牙利最大的健身制造商和销售商:inSPORTline
2018/10/30 全球购物
shallow copy和deep copy的区别
2016/05/09 面试题
建筑设计所实习生自我鉴定
2013/09/25 职场文书
求职信格式范本
2013/11/15 职场文书
动员大会主持词
2014/03/20 职场文书
大型会议策划方案
2014/05/17 职场文书
2014年档案管理工作总结
2014/11/17 职场文书
工程质检员岗位职责
2015/04/08 职场文书
贷款收入证明范本
2015/06/12 职场文书
幼儿园元旦主持词
2015/07/06 职场文书
解决Goland 同一个package中函数互相调用的问题
2021/05/06 Golang