Reputation: 16610
I'm doing fast click for mobile browser. When I fast click on link of current page, it does an ajax load to next page. My fast click script can stop the ghost click now. But if there is an input element on next page at click position on current page, it still get a focus and display virtual keyboard. How to prevent ghost focus event too?
Upvotes: 9
Views: 2864
Reputation: 1104
I'm using fastclick.js. Here's my way to prevent auto trigger on next page:
Global CSS:
#preventClick { width:100%; height:100%; position:absolute; z-index:1000; top:0; left:0; }
HTML on next page:
<body>
<div id="preventClick"></div>
<!-- button on the same coordinate with previous page -->
</body>
Script on next page:
function onDeviceReady() {
setTimeout(function(){ $('#preventClick').hide(); }, 300);
}
300 is the minimum and no point putting more than that
Upvotes: 2
Reputation: 31732
To prevent actions related to an event, use .stopImmediatePropagation()
and preventDefault()
.
- stopImmediatePropagation() - Handlers within the same function where it is call, will be executed normally, but will immediately neglect/stop any actions within other functions related to the same event. For example:
// alert will fire
$(document).on('click', '#foo', function(event) {
event.stopImmediatePropagation();
alert('Hello world');
});
// but this will be stopped
$(document).on('click', '#foo', function(event) {
console.log('I am stopped!');
});
- preventDefault() - When called, default action will be neglected. For example
<a href="http://www.google.com" id="foo">Google it!</a>
The link will be halted, but an alert will fire
$(document).on('click', '#foo', function(event) {
event.preventDefault();
alert('I prefer MSN');
});
Both should be combined together in order to stop events from bubbling up the DOM tree.
I made a Demo to explain the differences between both and why both should be combined together.
Based on the above, your code should look like this.
$(document).on('click', '.selector', function (event) {
event.stopImmediatePropagation();
event.preventDefault();
});
I hope this helps.
Upvotes: 10
Reputation: 29
I've been struggeling with this for a little while now, but only found a partial solution. Although I think it's good enough for my problem. Hopefully it will also be helpful to someone else.
This solution is based on jQuery mobile, but you might be able to do something similar if you don't use that.
What I do is, I place an empty div that fills the entire screen on top of other elements, so that it blocks (most) click/touch events.
<div id="ghostBuster" style="position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;display:none;"></div>
I show it before I hide the page I'm changing from.
$("div[data-role='page']").on("pagebeforehide", function() {
$("#ghostBuster").show();
});
And hide it again once the next page is shown.
$("div[data-role='page']").on("pageshow", function() {
$("#ghostBuster").hide();
});
I've not tested it very thoroughly and only on my android device, but so far it seems to work for avoiding ghost clicks and focussing. It doesn't work for avoiding ghost clicking select boxes. And it doesn't work when the transition animation between the pages is very fast. I've solved the problem with select boxes by switching to the non-native alternative that jQuery mobile provides.
You might consider hiding the div again on mouseup, but that doesn't work in my case as I use swipes to change pages.
It's probably not the prettiest possible solution, but so far I've been unable to find or come up with a better one.
Upvotes: -1