Original link http://ymblog.net/2016/03/28/by mobile page Click through the thought of
First I think of what:
- How the click-Through is caused
- How to Solve
- What is event impersonation
First, how is the click penetration caused?
The event contains Touchstart/touchmove/touchend/mousedown/mousemove/mouseup/click, possibly caused by a delay in the Click event or by event bubbling.
The reason for the click-through is that the click event in the Mobile page has a 200-300ms delay, in order to experience better we used the Zepto touch event, or the Touchstart/touchend event that was used, after the touch event was executed, Target event execution, at which point the Click event is still in the 300ms of latency. When the 300ms arrives, the click is actually the element underneath the hidden element.
If the element that is directly below has a bind click event, it is triggered at this point, if it does not occur if the Click event is not bound. If the input input box (or Select/radio/checkbox) is just below, click the default focus and pop-up keyboard, there is a "point through" phenomenon.
Then why should there be a delay? The browser waits about 300ms after touchend, because it determines whether the user has double tap behavior. If there is no tap behavior, the Click event is triggered and the Click event is not appropriate for the double-tap process. From this you can see that the Click event Trigger represents the end of a round of touch events.
Dom Event Flow:
1, event capture phase;
2, in the target stage;
3, event bubbling phase.
Speaking of which, let's take a look at the order in which events are executed, and in the mobile page, the order in which the touch events are executed is touchstart
touchmove
touchend -> mousedown ->mouseup ->click,当然在web端中可能顺序又不一样。
That seems to be taken for granted by the above-mentioned penetrating question. Because this is the default behavior of the browser!
Second, how to solve
In general, adding the following code will solve the problem.
It is possible to block the default behavior of the browser in the Touchend event.
Event.preventdefault ();
The above is a kind of solution, I remember there will be a situation even if add this line statement or invalid more special case, some people say that using fastclick can solve the problem, when I used to find it really seems to click a lot faster, But in the Huawei Glory 3 C model, but found that there will be click through the phenomenon, and then consider this I need to introduce a file HTTP request, so decisively give up.
There is also a way to cure the symptoms, as follows:
Because of the lag of the Click event, the original clicked element disappears during this period, so it "penetrates". So we think along this line of thought, can give the disappearance of the element to do a fade effect, like in jquery fadeOut
, and set the animation duration greater than 300ms, so when the delayed click Trigger, it will not "penetrate" to the elements below.
Similarly, without time-lapse animations, we can also dynamically generate a transparent element in the touch position, so that when the upper element disappears and the deferred click arrives, it clicks on the transparent element and does not "penetrate" to the bottom. After a certain timeout, the resulting transparent element is removed.
$ (' #closePopup '). On (' Tap ', function (e) { $ (' #popupLayer '). Hide (); $ (' #bgMask '). Hide (); $ (' #underLayer '). CSS (' pointer-events ', ' none '); SetTimeout (function () { $ (' #underLayer '). CSS (' pointer-events ', ' Auto '); }, 400);});
But if there's more click events on the page, that's certainly not possible.
Third, what is the event simulation
The tap events on the Zepto are also simulated, and we seem to be able to simulate click events on our own.
We can print the event object printed on the console,
The so-called event simulation is a specific way to pass in the specified parameters, and then distribute the custom event.
var event = document.createevent (' mouseevents ');
This parameter can be selected as follows:
- Uievents
- Mouseevents
- Mutationevents, generalized DOM changes
- Htmlevents General DOM Events
var type = ' click '; Type of event to trigger var bubbles = true; Whether the event can bubble var cancelable = true; Whether the event can block browser default event var view = Document.defaultview; The view associated with the event, which is default, regardless of var detail = 0;var ScreenX = 0;var ScreenY = 0;var ClientX = 0;var ClientY = 0;var Ctrlkey = false; Whether to press Ctrlvar Altkey = false; Whether to press Altvar Shiftkey = False;var Metakey = False;var Button = 0;//indicates which mouse button to press var relatedtarget = 0; used when simulating MouseMove or out, event-related object var event = document.createevent (' mouseevents '); event.initmouseevent (type, Bubbles, cancelable, view, detail, ScreenX, ScreenY, ClientX, Clienty,ctrlkey, Altkey, Shiftkey, Metakey, button, relatedtarget);
The Final Solution:
var el = Null;var list = document.getElementById (' list '); function GetEvent (EL, E, type) { e = e.changedtouches[0];
var event = document.createevent (' mouseevents '); Event.initmouseevent (Type, true, true, window, 1, E.screenx, E.screeny, E.clientx, E.clienty, False, False, False, False, 0, NULL); Event.forwardedtouchevent = true; return event;} List.addeventlistener (' Touchstart ', function (e) { var firsttouch = e.touches[0] el = firsttouch.target;}) List.addeventlistener (' Touchend ', function (e) { e.preventdefault (); var event = getEvent (EL, E, ' click '); El.dispatchevent (event);}) List.addeventlistener (' click ', Function (e) { list.style.display = ' none '); SetTimeout (function () { list.style.display = "; }, 1000);})
We can block the browser's default behavior at the time of the Touchend event, and then simulate the generation and triggering of the event itself. This is when you create a click event object to trigger it, and all the clicks still use click.
Iv. Summary
Reading from the morning to see the information now, the beginning of the idea is very clear, the source of the problem, the emergence of problems, and how to solve ... Look at a long time, see more things suddenly found to become blurred, found a lot of things are conflict, such as click through is Zepto caused? Read the Netizen said, because Zepto analog tap event is bubbling to document only triggered, and before bubbling to document, finger touch and leave the screen (touchstart/touchend) will trigger the Click event. So there's this problem? So I stopped the browser from the default event is not OK?
But it seems to be that the difference between Android and iOS is that MouseDown is performing faster, Android is bigger than iOS
The results obtained on Android are amazing, this unwinnable Android inside Moveover event accidentally Binima Touchstart also fast!!!
and iOS just ignore the MouseOver event, this is the main cause of the problem!!!
While android in MoveDown time, happy heart triggered the focus event of input, then the keyboard bounced up!!!
So for Android, we have to kill MouseDown!!!!
In fact, we have input to get the focus, is triggered by MouseDown, iOS is also, so to solve the problem of Android under the other level to grab
This has resulted in the final solution: that is, the above is for a single click event, the following for all:
var touch = {};var T = new Date (). GetTime ();d ocument.addeventlistener (' click ', Function (event) {if (Event.myclick = = True) {return true; } if (event.stopimmediatepropagation) {event.stopimmediatepropagation (); } else {event.propagationstopped = true; } event.stoppropagation (); Event.preventdefault (); return true; }, True); Document.addeventlistener (' Touchstart ', function (e) {touch.starttime = E.timestamp; Touch.el = E.target; t = E.timestamp; }); Document.addeventlistener (' Touchmove ', function (e) {}); Document.addeventlistener (' Touchend ', function (e) {touch.last = E.timestamp; var event = document.createevent (' Events '); Event.initevent (' Click ', True, true, window, 1, E.changedtouches[0].screenx, E.changedtouches[0].screeny, E.changedtouches[0].clientx, E.changedtouches[0].clienty, False, False, False, FALSE, 0, NULL); Event.Myclick = true; Touch.el && touch.el.dispatchEvent (event); return true; }); Dom.addeventlistener (' click ', Function (e) {alert (1); });
Its core is to simulate events and distribute them.
var event = document.createevent (' Events '); event.initevent (' Click ', True, true, window, 1, E.changedtouches[0].screenx , E.changedtouches[0].screeny, E.changedtouches[0].clientx, E.changedtouches[0].clienty, False, False, False, False, 0 , null); Event.myclick = True;touch.el && touch.el.dispatchEvent (event);
V. References
The first point to open this article: https://segmentfault.com/q/1010000000691822
And then I opened this post: 1190000003848737
And then in the footer of this article see a lot, and then look at this article: http://www.cnblogs.com/yexiaochai/p/3462657.html
And then read this article: http://www.cnblogs.com/yexiaochai/p/3442220.html
By the mobile page click through the thought of