Detecting that the browser has no mouse and is touch-only

前端 未结 24 2044
终归单人心
终归单人心 2020-11-27 09:35

I\'m developing a webapp (not a website with pages of interesting text) with a very different interface for touch (your finger hides the screen when you click) and mouse (re

24条回答
  •  甜味超标
    2020-11-27 09:58

    @SamuelRossille No browsers that I'm aware of expose the existence of (or lack thereof) a mouse, unfortunately.

    So, with that being said, we just have to try and do the best we can with our existing option... events. I know it's not exactly what you're looking for... agreed it is currently far from ideal.

    We can do our best to figure out whether a user is using a mouse or touch at any given moment. Here is a quick and dirty example using jQuery & Knockout:

    //namespace
    window.ns = {};
    
    // for starters, we'll briefly assume if touch exists, they are using it - default behavior
    ns.usingTouch = ko.observable(Modernizr.touch); //using Modernizr here for brevity.  Substitute any touch detection method you desire
    
    // now, let's sort out the mouse
    ns.usingMouse = ko.computed(function () {
        //touch
        if (ns.usingTouch()) {
            //first, kill the base mousemove event
            //I really wish browsers would stop trying to handle this within touch events in the first place
            window.document.body.addEventListener('mousemove', function (e) {
                e.preventDefault();
                e.stopImmediatePropagation();
            }, true);
    
            //remove mouse class from body
            $('body').removeClass("mouse");
    
            //switch off touch listener
            $(document).off(".ns-touch");
    
            // switch on a mouse listener
            $(document).on('mousemove.ns-mouse', function (e) {
                if (Math.abs(window.lastX - e.clientX) > 0 || window.lastY !== e.clientY) {
                    ns.usingTouch(false);  //this will trigger re-evaluation of ns.usingMouse() and result in ns.usingMouse() === true
                }
            });
    
            return false;
        }
        //mouse
        else {
            //add mouse class to body for styling
            $('body').addClass("mouse");
    
            //switch off mouse listener
            $(document).off(".ns-mouse");
    
            //switch on a touch listener
            $(document).on('touchstart.ns-touch', function () { ns.usingTouch(true) });
    
            return true;
        }
    });
    
    //tests:
    //ns.usingMouse()
    //$('body').hasClass('mouse');
    

    You can now bind/subscribe to usingMouse() & usingTouch() and/or style your interface with the body.mouse class. The interface will switch back and forth as soon as a mouse cursor is detected and on touchstart.

    Hopefully we'll have some better options from the browser vendors soon.

提交回复
热议问题