当前位置:Web前端 > > 正文

mac鼠标怎么实现触摸板功能(鼠标滚轮事件和Mac触控板双指事件)

时间:2021-10-10 00:58:57类别:Web前端

mac鼠标怎么实现触摸板功能

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

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

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

    上一篇下一篇

    猜您喜欢

    热门推荐