Skip to content
This repository has been archived by the owner on Jun 9, 2022. It is now read-only.

Ghost focus problem #27

Closed
zeroonea opened this issue Nov 14, 2012 · 19 comments
Closed

Ghost focus problem #27

zeroonea opened this issue Nov 14, 2012 · 19 comments

Comments

@zeroonea
Copy link

Click on a button to transition (css3 slide) to next page, if on next page there is an input right there the position of the button on previous page, the input will get focus and soft keyboard open up.

jsfiddle: http://jsfiddle.net/sX3WJ/
open it in mobile browser: http://fiddle.jshell.net/sX3WJ/show/

@mattcg
Copy link
Contributor

mattcg commented Nov 14, 2012

Thank you for reporting. What browser/OS/device is this on?

@zeroonea
Copy link
Author

Thanks for fast response. My environtment: web app + phonegap on android 4.1 galaxy nexus. I updated test case

@ghost ghost assigned mattcg Nov 14, 2012
mattcg added a commit that referenced this issue Nov 14, 2012
@steverandy
Copy link

Having similar issue with contenteditable. Any quick temp hack to prevent it?

@yfarooq
Copy link

yfarooq commented Feb 6, 2013

i have the same problem, any idea how to prevent it ?

@mattcg
Copy link
Contributor

mattcg commented Feb 6, 2013

@steverandy and @yfarooq are you both encountering the problem on Android?

@dryabov
Copy link

dryabov commented Feb 6, 2013

I reproduced the issue on Android 2.3.5 (caret in input field is moved to the position of click).
To log sequence of events, I've modified fiddler code in the following way: http://jsfiddle.net/HXRFM/ (http://fiddle.jshell.net/HXRFM/show/) To my surprise, this version works correctly, so I don't know what is the difference (either browser processes "bubbled" events in special way, or a delay because of logger does matter).

@steverandy
Copy link

@mattcg, it happens on mobile safari ios 6 for me.

@ghost
Copy link

ghost commented Feb 6, 2013

Thank you Mattcg for response, i am facing the problem on iOS . i am not sure if i am implementing it properly however the response of buttons changed. i want fast click to target all the buttons and links
I am using Jquerymobile and this is how i am implementing.

    <script type="application/javascript" src="js/fastclick.js"></script> 
    <script type="application/javascript">
        window.addEventListener('load', function () {
          new FastClick(document.body);
        }, false);
    </script> 

after body start i have a div class with id FastClick

all my pages are here.

Cheers ,

@mattcg
Copy link
Contributor

mattcg commented Feb 7, 2013

Thanks @yamafarooq. That looks like a different issue. Will you create a test case and open a new ticket please?

@mattcg
Copy link
Contributor

mattcg commented Feb 7, 2013

@dryabov thanks for that. I think the DOM manipulation caused by the logging is causing the browser to behave differently.

@dryabov
Copy link

dryabov commented Feb 7, 2013

You are right, I've postponed manipulations with setTimeout and the issue comes back. But the list of caught events was the same, so I've included other events to log (http://jsfiddle.net/HXRFM/2/show/). Result is:

touchstart DIV#btn DIV#btn null
click DIV#btn DIV#btn DIV#btn
touchend DIV#btn DIV#btn null
mousedown INPUT#text INPUT#text INPUT#text
mouseup INPUT#text INPUT#text INPUT#text

So, the problem is that browser emulates mouse events after touchend.

@dryabov
Copy link

dryabov commented Feb 7, 2013

From http://developer.apple.com/library/IOS/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html

If the user taps a nonclickable element, no events are generated. If the user taps a clickable element, events arrive in this order: mouseover, mousemove, mousedown, mouseup, and click. The mouseout event occurs only if the user taps on another clickable item. Also, if the contents of the page changes on the mousemove event, no subsequent events in the sequence are sent.

From http://jquerymobile.com/demos/1.2.0/docs/api/events.html

Webkit based browsers synthesize mousedown, mouseup, and click events roughly 300ms after the touchend event is dispatched. The target of the synthesized mouse events are calculated at the time they are dispatched and are based on the location of the touch events and, in some cases, the implementation specific heuristics which leads to different target calculations on different devices and even different OS versions for the same device. This means the target element within the original touch events could be different from the target element within the synthesized mouse events.

Most likely a minor modifying of DOM would be the way to cancel mouse events generation.
Or, alternatively, maybe it's possible to stop mousedown or mouseup (or both) event propagation like it's done for click event.

@steverandy
Copy link

@mattcg, this is a screen recording, showing the issue that I'm having.
https://dl.dropbox.com/u/2271268/ghostclick.mov

I'm not sure if it's because of the css3 animation or the confirm box.

@dryabov
Copy link

dryabov commented Feb 8, 2013

@zeroonea try this version: https://raw.github.com/dryabov/fastclick/master/lib/fastclick.js If it works, I'll create pull request.

The issue is because of EventDispatcher::dispatchSimulatedClick() method in WebKit (https://trac.webkit.org/browser/trunk/Source/WebCore/dom/EventDispatcher.cpp#L222) dispatches mouseover, mousedown, mouseup, and click events. And fastclick.js "disables" click only. Fortunately, we can stop other simulated events as well (as I did in above fork). Unfortunately, dispatchSimulatedClick() calls to node->setActive(true) so the node (that will be under touch position in 300 ms after touchend) will be activated (but not focused).

PS. Next week I'll try to fix setActive() issue using call to this.focus(oldTargetElement); in simulated click event. Hope it will allow to "undo" all effects of dispatchSimulatedClick().

@mattcg
Copy link
Contributor

mattcg commented Feb 8, 2013

@dryabov that's brilliant work tracking down the cause of the issue. спасибо!

Please do make a pull request if this does work.

@steverandy
Copy link

Managed to fix my issue by using defer to wrap the function that will show the confirm dialog box.

@dryabov
Copy link

dryabov commented Feb 9, 2013

@mattcg it does work in the sense that inputbox in @zeroonea example is not focused. But WebKit (Android 2.3.5, stock browser) highlight it with a border. It's better than nothing, but doesn't correspond to initial behaviour (without fastclick.js input box is not highlighted after click).

@tonyawad88
Copy link

That did it for me too "https://raw.github.com/dryabov/fastclick/master/lib/fastclick.js"

Thank you !

@mattcg
Copy link
Contributor

mattcg commented Feb 19, 2013

The patched version was merged into master in 17aea94.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants