Skip to main content

Mobile Page Click-Through Problem Solutions

Free2015-08-24#JS#Front-End#Solution#click through#zepto点击穿透#点透#点穿#300ms延迟#解决点透问题#跨页面点击穿透#ghost click

Mobile page click-through problem is an easy-to-encounter basic problem, this article explains its principles and various solutions in detail

I. click and 300ms Delay

Mobile browsers provide a special feature: double tap to zoom

The 300ms delay comes from here, after user touches the page, needs to wait for a period of time to judge whether it's a double tap action, instead of immediately responding to click, this waiting time is about 300ms. Previously had a brief introduction: [Anye Qingyang: HTML5 Touch Events](/articles/html5 触摸事件/)

Mobile events provide touchstart, touchmove, touchend but don't provide tap support, mainstream frameworks (libraries) all manually implement custom tap events, to eliminate 300ms delay and improve page response speed. For simple pages, can use touchstart or touchend as tap, but there are some problems, for example, finger touches target element, holds without releasing, slowly moves out of response area, will trigger touchstart event to execute corresponding event handler (shouldn't trigger), touchend event also has similar problems.

In addition, using native touch events also has click-through problem, because click is triggered about 300ms after touch series events occur, mixing touch and click will definitely cause click-through problem, detailed introduction below

II. Click-Through Problem

There are 3 types of click-through phenomena:

  • Click-through problem: Click close button on mask, after mask disappears, find that click event of element below button is triggered

    Mask's close button is bound with touch event, while button's underlying element is bound with click event, after touch event triggers, mask disappears, 300ms later this point's click event fires, event's target naturally is the element below button, because button disappeared together with mask

  • Cross-page click-through problem: If button below happens to be an a tag with href attribute, then page will navigate

    Because a tag navigation defaults to click event trigger, so principle is exactly the same as above

  • Another cross-page click-through problem: This time no mask, directly click in-page button to navigate to new page, then find that click event of corresponding position element in new page is triggered

    Same logic as mask, if js control page navigation logic is bound on touch event, and corresponding position element in new page is bound with click event, and page completes navigation within 300ms, all three conditions met simultaneously, this situation occurs

If must subdivide, there's a fourth type, but probability is very low, that is corresponding position element in new page happens to be a tag, then continuous navigation occurs... and so on, all are click-through problems

III. Solutions

Problem is already very clear, there are many solutions, but ideas are不外乎 2 types:

  1. Don't mix touch and click

Since touch triggers click after 300ms, only using touch or only using click naturally won't have problems

  1. Consume (or say consume) the click after touch

Still use tap, just do extra processing in situations where click-through may occur, use something to block, or delay 350ms after tap before hiding mask, pointer-events, do detection in underlying element's event handler (with global flag), etc., as long as it can consume it

Detailed solutions:

  1. Only use touch

Simplest solution, perfectly solves click-through problem

Change all click in page to touch events (touchstart, 'touchend', 'tap'), need to特别注意a tags, a tag's href is also click, need to remove and change to js-controlled navigation, or directly change to span + tap control navigation. If requirements are not high, don't care about sliding out or sliding in triggering events, span + touchend is fine, after all tap needs to import third-party library

Not using a tags is actually nothing, mobile app development doesn't need to consider SEO, even if using a tags, generally will remove all default styles, might as well use span directly

  1. Only use click

Worst strategy, because it brings 300ms delay, any custom interaction in page will add 300ms delay, just thinking about it feels slow

Not using touch won't have problem of click triggering 300ms after touch, if interactivity requirements are not high can do this, strongly not recommended, faster is always better

  1. Use something to block

Relatively stupid method, never use

Ye Xiaochai's "chrysanthemum" method, for more information please see 【Mobile Compatibility Problem Research】JavaScript Event Mechanism Detailed Explanation (Involving Mobile Compatibility)

  1. Delay 350ms after tap before hiding mask

Minimal changes, disadvantage is hiding mask becomes slow, 350ms can still feel slow

Only need to handle mask, changes are very small, if requirements are not high, using this is more labor-saving

  1. pointer-events

Relatively troublesome and has defects, not recommended

After mask hides, add pointer-events: none; style to element below button, let click pass through, remove this style after 350ms, restore response

Defect is within 350ms after mask disappears, user can see element below button unresponsive when clicked, if user hand speed is very fast will definitely discover

  1. Do detection in underlying element's event handler (with global flag)

Relatively troublesome, not recommended

Global flag records button click position (coordinate point), judge event's coordinate point in underlying element's event handler, if same then it's that damn click, refuse to respond

Above is just idea, haven't tested, if really can't then use record timestamp to judge, wait 350ms, this way is similar to pointer-events

  1. fastclick

Good solution, if don't mind loading a few more KB, not recommended, because someone encountered bugs, for more information please see: Fastclick Causes click Event to Trigger Twice Problem

First import fastclick library, then change all touch events in page to click, actually slightly troublesome, suggest importing these few KB just to solve click-through problem is not worth it, might as well use first method

IV. DEMO

Wrote quite a few test pages, please see: Git @OSC ayqy / my.js

References

  • Several senior blog posts

Comments

No comments yet. Be the first to share your thoughts.

Leave a comment