欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-09-17 12:47:33
这篇文章主要介绍了鼠标滚轮事件&Mac触控板双指事件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 19-12-23...

因为下一阶段要做的一个工作是开发一个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线图的代码整理一下。

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