1

I am building a web app using Jquery Mobile for use on a desktop, iPad and Android phone. I want the user to be able to tap a button to increment (or decrement) a value. My code works fine on a desktop, but on the iPad and Android, when the user taps rapidly, the screen zooms instead of the value incrementing. I have been trying to implement the solution here: Safari iPad : prevent zoom on double-tap (and in particular the refinement provided by Christopher Thomas.

Here is my code for the button and value:

    <div class="content">
        <div id ="status_page" data-role="page">
            <div data-role="content" data-theme="d">
                <div id="val">1</div>
                <div id="but" data-role="button">Click</div>
            </div>
        </div>
    </div>

Here is my event handler for a click on the button (btw - I think the parameters in Christopher's answer were the wrong way round):

        $(".content") .on("click",$("#but"),function(){
            var but_val = parseInt($("#val").text());
            $("#val").text(but_val+1);
        });

...and here is the nodoubletap function:

(function($) {
$.fn.nodoubletapzoom = function() {
    if($("html.touch").length == 0) return;

    $(this).bind('touchstart', function preventZoom(e){
        var t2 = e.timeStamp;
        var t1 = $(this).data('lastTouch') || t2;
        var dt = t2 - t1;
        var fingers = e.originalEvent.touches.length;
        $(this).data('lastTouch', t2);
        if (!dt || dt > 500 || fingers > 1){
            return; // not double-tap
        }
        e.preventDefault(); // double tap - prevent the zoom
        // also synthesize click events we just swallowed up
        $(this).trigger('click');
    });
};
})(jQuery);

This function is trapping the double tap correctly. However, the trigger function at the end is not working (the event is not being fired). If I substitute $(this).trigger('click'); with $('#but').trigger('click'); then everything works as it should. I want this to work for a number of different buttons, so I need to be able to trigger the event based on the object that called the touchstart event. Can anyone help me to fix this please.

Community
  • 1
  • 1
engeeaitch
  • 81
  • 3
  • 11
  • I've added a jsfiddle here: [link]http://jsfiddle.net/GZEM7/11/ Version 11 works fine (it uses `$('#but')`) Version 10 does not work (it uses `$(this)`). – engeeaitch Apr 07 '13 at 13:01
  • you don't explain here how you are applying the jquery function to your elements, for example, see my code where I say "$("body).nodoubletapzoom();" that is because I want to apply the function to the entire document, this could explain why you are getting the entire document and not the element selected? – Christopher Thomas Apr 08 '13 at 10:37
  • also, I have a "content" node inside the body, I want to make sure all the events don't bubble up to the body element, so I am attaching jquery click handlers, etc to the content node using jquery.on() and then I attach the double tap handler to the body. this means any event which escapes the "content" node and reaches body, I want to ignore, but I use "content" like a <> to catch the events, do you get it? – Christopher Thomas Apr 08 '13 at 10:39
  • Hi Christopher - many thanks for your help. I must be doing something wrong, but I'm not sure what - if you take a look at the jsfiddle, I have bound the nodoubletapzoom function to the body, and I have a content node inside the body. If you can point out where I've gone wrong, I would be very grateful. – engeeaitch Apr 08 '13 at 11:47
  • it should be "$(this).trigger("click")" and you changed it to $("#but")..... – Christopher Thomas Apr 08 '13 at 12:53
  • I played around a little bit and on my android galaxy note 10.1 this works perfectly: http://jsfiddle.net/GZEM7/14/ – Christopher Thomas Apr 08 '13 at 13:07
  • http://jsfiddle.net/GZEM7/16/ works fine too, I only removed the IOS check you had at the top.... – Christopher Thomas Apr 08 '13 at 13:10
  • Hi - using $("#but") works fine - but using $(this) does not. I want several buttons on the page, so I need $(this) to work so that I can fire the trigger for the button that was clicked. Version 10 of the jsfiddle uses $(this) and does not work for me. – engeeaitch Apr 08 '13 at 13:11
  • ahhh, I misunderstood that part obviously, let me check again – Christopher Thomas Apr 08 '13 at 13:12
  • ok, this appears to be working for me: http://jsfiddle.net/GZEM7/18/ when I do that, the counter goes up like normal – Christopher Thomas Apr 08 '13 at 13:19
  • can you mark my answer as correct then please, so I can collect the points :D – Christopher Thomas May 03 '13 at 12:57

1 Answers1

3

ok, so "engeeaitch" the final solution was in the following jsfiddle?

http://jsfiddle.net/GZEM7/18/

and the solution was to replace

$(this).trigger("click"):

with

$(e.target).trigger("click");

and of course, I removed your IOS testing because then it'll work on chrome and android devices :D

thats the final solution? Cool! I'm going to update my code with the new version, I think it'll be better

the final code is:

$.fn.nodoubletapzoom = function() {
    $(this).bind('touchstart', function preventZoom(e){
        var t2 = e.timeStamp;
        var t1 = $(this).data('lastTouch') || t2;
        var dt = t2 - t1;
        var fingers = e.originalEvent.touches.length;
        $(this).data('lastTouch', t2);
        if (!dt || dt > 500 || fingers > 1){
            return; // not double-tap
        }
        e.preventDefault(); // double tap - prevent the zoom
        // also synthesize click events we just swallowed up
        $(e.target).trigger('click');
    });
};
})(jQuery);

$(document).on('pageinit',"#status_page", function(){
        $("body").nodoubletapzoom();
        $(".content").on("click", "#but", function() {
            var curr_val = parseInt($("#val").text());
            $("#val").text(curr_val + 1);
        });
});
Christopher Thomas
  • 4,424
  • 4
  • 34
  • 49