I modified @ecmanaut's javascript solution to do two things.
- I use modernizr, so it'll put a .touch css class on the html node, so I can detect touch screens instead of using user agent detection. Perhaps there is a "modernizr-less" approach, but I don't know it.
- I separate each "click" so they happen separately, if you click once, it'll click once, if you rapidly click the button/trigger, it'll count multiple times.
- some minor code formatting changes, I prefer each var defined separately etc, this is more a "me" thing than anything else, I suppose you could just revert that, nothing bad will happen.
I believe these modifications make it better, cause you can increment a counter 1,2,3,4 instead of 2,4,6,8
here is the modified code:
// jQuery no-double-tap-zoom plugin
// Triple-licensed: Public Domain, MIT and WTFPL license - share and enjoy!
//
// chris.thomas@antimatter-studios.com: I modified this to
// use modernizr and the html.touch detection and also to stop counting two
// clicks at once, but count each click separately.
(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);
The apply the nodoubletapzoom() to the body tag, like this
$("body").nodoubletapzoom();
your html construction, should be something like this
<body>
<div class="content">...your content and everything in your page</div>
</body>
Then in your javascript, bind your click handlers like this
$(".content")
.on(".mydomelement","click",function(){...})
.on("button","click",function(){...})
.on("input","keyup blur",function(){...});
// etc etc etc, add ALL your handlers in this way
you can use any jquery event handler and any dom node. now you dont have to do anything more than that, you have to attach all your event handlers in this way, I've not tried another way, but this way works absolutely rock solid, you can literally rap the screen 10 times a second and it doesnt zoom and registers the clicks (obviously not 10 per second, the ipad isn't that fast, what I mean is, you can't trigger the zoom)
I think this works because you're attaching the nozoom handler to the body and then attaching all your event handlers to the ".content" node, but delegating to the specific node in question, therefore jquery catches all the handlers at the last stage before the event would bubble up to the body tag.
the main benefit of this solution is you only have to assign the nodoubletapzoom() handler to the body, you only do it once, not once for each element, so it's much less work, effort and thinking required in order to get things done.
this has the additional benefit in that if you add content using AJAX, they automatically have the handlers ready and waiting, I suppose if you DIDNT want that, then this method won't work for you and you'll have to adjust it more.
I've verified this code works on ipad, it's beautiful actually, well done to @ecmanaut for the primary solution!!
** Modified on Saturday 26th May because I found what seems to be a perfect solution with absolutely minimal effort