How to bind 'touchstart' and 'click' events but not respond to both?

前端 未结 30 3078
抹茶落季
抹茶落季 2020-11-22 14:08

I\'m working on a mobile web site that has to work on a variety of devices. The one\'s giving me a headache at the moment are BlackBerry.

We need to support both key

相关标签:
30条回答
  • 2020-11-22 14:19

    You could try like this:

    var clickEvent = (('ontouchstart' in document.documentElement)?'touchstart':'click');
    $("#mylink").on(clickEvent, myClickHandler);
    
    0 讨论(0)
  • 2020-11-22 14:19

    There are many things to consider when trying to solve this issue. Most solutions either break scrolling or don't handle ghost click events properly.

    For a full solution see https://developers.google.com/mobile/articles/fast_buttons

    NB: You cannot handle ghost click events on a per-element basis. A delayed click is fired by screen location, so if your touch events modify the page in some way, the click event will be sent to the new version of the page.

    0 讨论(0)
  • 2020-11-22 14:20

    Taking advantage of the fact that a click will always follow a touch event, here is what I did to get rid of the "ghost click" without having to use timeouts or global flags.

    $('#buttonId').on('touchstart click', function(event){
        if ($(this).data("already")) {
            $(this).data("already", false);
            return false;
        } else if (event.type == "touchstart") {
            $(this).data("already", true);
        }
        //your code here
    });
    

    Basically whenever an ontouchstart event fires on the element, a flag a set and then subsequently removed (and ignored), when the click comes.

    0 讨论(0)
  • 2020-11-22 14:21

    You could try something like this:

    var clickEventType=((document.ontouchstart!==null)?'click':'touchstart');
    $("#mylink").bind(clickEventType, myClickHandler);
    
    0 讨论(0)
  • 2020-11-22 14:22

    The best method I have found is to write the touch event and have that event call the normal click event programatically. This way you have all your normal click events and then you need to add just one event handler for all touch events. For every node you want to make touchable, just add the "touchable" class to it to invoke the touch handler. With Jquery it works like so with some logic to make sure its a real touch event and not a false positive.

    $("body").on("touchstart", ".touchable", function() { //make touchable  items fire like a click event
    var d1 = new Date();
    var n1 = d1.getTime();
    setTimeout(function() {
        $(".touchable").on("touchend", function(event) {
            var d2 = new Date();
            var n2 = d2.getTime();
            if (n2 - n1 <= 300) {
                $(event.target).trigger("click"); //dont do the action here just call real click handler
            }
        });
    }, 50)}).on("click", "#myelement", function() {
    //all the behavior i originally wanted
    });
    
    0 讨论(0)
  • 2020-11-22 14:23

    Usually this works as well:

    $('#buttonId').on('touchstart click', function(e){
        e.stopPropagation(); e.preventDefault();
        //your code here
    
    });
    
    0 讨论(0)
提交回复
热议问题