iPad/iPhone hover problem causes the user to double click a link

后端 未结 26 1574
太阳男子
太阳男子 2020-11-27 09:18

I have some websites I built times ago, that use jquery mouse events...I just got an ipad and i noticed that all the mouse over events are translated in clicks...so for inst

相关标签:
26条回答
  • 2020-11-27 09:44

    Avoid changing of "display" style inside of hover css event. I had "display: block" in hover state. After removing ios went on lins by single tap. By the way it seems that latest IOS updates fixed this "feature"

    0 讨论(0)
  • 2020-11-27 09:46

    Haven't tested this fully but since iOS fires touch events, this could work, assuming you are in a jQuery setting.

    $('a').on('click touchend', function(e) {
        var el = $(this);
        var link = el.attr('href');
        window.location = link;
    });
    

    The idea is that Mobile WebKit fires a touchend event at the end of a tap so we listen for that and then redirect the browser as soon as a touchend event has been fired on a link.

    0 讨论(0)
  • 2020-11-27 09:46

    I think it'd be wise to try mouseenter in place of mouseover. It's what's used internally when binding to .hover(fn,fn) and is generally what you want.

    0 讨论(0)
  • 2020-11-27 09:46

    Just an improvement to avoid redirection when you slide your finger on a link by mistake.

    // tablet "one touch (click)" X "hover" > link redirection
    $('a').on('touchmove touchend', function(e) {
    
        // if touchmove>touchend, set the data() for this element to true. then leave touchmove & let touchend fail(data=true) redirection
        if (e.type == 'touchmove') {
            $.data(this, "touchmove_cancel_redirection", true );
            return;
        }
    
        // if it's a simple touchend, data() for this element doesn't exist.
        if (e.type == 'touchend' && !$.data(this, "touchmove_cancel_redirection")) {
            var el = $(this);
            var link = el.attr('href');
            window.location = link;
        }
    
        // if touchmove>touchend, to be redirected on a future simple touchend for this element
        $.data(this, "touchmove_cancel_redirection", false );
    });
    
    0 讨论(0)
  • 2020-11-27 09:50

    What worked for me is what others here have already said:

    Don't show/hide elements on hover or mousemove (which is the event in my case).

    Here's what Apple says (https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html):

    A clickable element is a link, form element, image map area, or any other element with mousemove, mousedown, mouseup, or onclick handlers

    If the user taps a clickable element, events arrive in this order: mouseover, mousemove, mousedown, mouseup, and click. Also, if the contents of the page changes on the mousemove event, no subsequent events in the sequence are sent. This behavior allows the user to tap in the new content.

    So, you could use @woop's solution: detect the userAgent, check if it's and iOS device and then bind the event. I ended up using this technique because it suits my needs and it makes more sense do not bind hover events when you don't want it.

    But... if you don't wanna mess with userAgents and still hide/show elements on hover/mousemove, i found out you can do so by using native javascript, like this:

    $("body").on("mouseover", function() {
           document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
           document.querySelector(".my-selector div").style.display = 'none'; // hide element
    });
    

    This will work on the Desktop version and will do nothing on the mobile version.

    And for a little more compatibility...

    $("body").on("mouseover", function() {
       if (document.getElementsByTagName && document.querySelector) { // check compatibility
           document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
           document.querySelector(".my-selector div").style.display = 'none'; // hide element
        } else {
            $(".my-class").show();
            $(".my-selector div").hide();
        }
    });
    
    0 讨论(0)
  • 2020-11-27 09:50

    You could check navigator.userAgent like this:

    if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i)) {
        //bind your mouseovers...
    }
    

    but you would have to check for blackberries, droids, umpty other touchscreen devices. You could also bind the mouseovers only if the userAgent contains Mozilla, IE, Webkit, or Opera, but you still need to screen for some devices because the Droid, for instance, reports its userAgent string as:

    Mozilla/5.0 (Linux; U; Android 2.0.1; en-us; Droid Build/ESD56) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17
    

    The iPhone's string is similar. If you just screen for iPhone, iPod, iPad, Android and Blackberry you might get the majority of handhelds, but not all of them.

    0 讨论(0)
提交回复
热议问题