If you follow me, YOU should know that I have recently made mobile adaptations to PC pages. In this process, in order to save 300ms time for users and give them more timely click feedback (which means better user experience), I tried to use the touchStart event unique to mobile terminal to replace the traditional click event. During this process, I encountered some small problems and successfully solved them. You can check out the details in this article.

When I was about to launch, I suddenly found another weird phenomenon on mobile devices after using the TouchStart event: when the user scrolls the page, the TouchStart event originally bound to the fixed positioning navbar element would often fail. You can see this strange phenomenon for yourself by scanning the QR code below and using your Safari or Chrome browser (note: not a built-in emulator).

Eventually, of course, I managed to fix the problem, and interestingly, it didn’t seem to be my code, but rather a browser Bug. However, I only have a rough guess about the mechanism of this Bug. If you know the reason of this phenomenon clearly, you are welcome to share with me.

In this article, I will not only record my solution, but also record the debug process and analysis ideas after I encounter this problem. But if you’re struggling with this problem and just want to get rid of it, you can head to the “Solutions” section at the bottom of this article for my solution (how sweet of me, right? 😜).

I. Problem description

  • Mobile device: iPhone 6
  • Operating system: iOS 11.2.5
  • Test browsers: Safari, Chrome

  • Click here to see sample code

When you open a web page using a test browser on a mobile device and scroll, you see that the TouchStart event attached to the Navbar element is not triggered (or occasionally not) when you click navbar again.

Ii. Analysis and investigation

Step 1: Use search engines

I stumbled upon this problem by observing that the TouchStart event bound to navbar would sometimes be triggered and sometimes fail. So I googled the phrase “touchStart event occasionally fails” and, unfortunately, didn’t get a solid answer. That means “there is no problem with occasional touchStart failures.” In other words, I need to find out exactly what caused the TouchStart response event to fail.

I then tried various actions on the mobile device (double click, scroll, zoom, etc.) and paid attention to the response of the mobile device, and finally determined that the cause of the Failure of the TouchStart binding event was “after the page scroll”. The next thing to do is simply go ahead and Google search for “The TouchStart event expires after the page scrolls.” Take a look at the first screen of search results and click in to check. Unfortunately, there is nothing suitable:

Then I tried to switch baidu search for the same keywords, not bad, there has been a high degree of similarity of the search results, but after reading found that I still do not want:

It’s time for the final kill, using English keyword search! Here are my Google search results using the keyword “touch event doesn’t respond after Page Scroll” :

As usual, no satisfactory results. So far I’ve learned two things:

  1. Maybe there’s something wrong with my code: because it’s very unlikely that something strange will happen that no one has ever encountered before;
  2. I should be fromtouchThe related concept of the event to find the cause;

(2) Step 2: Isolate the code and clarify the concept

At this point, the first phase of debug is over. My futility shows that this problem is not simple and I need to take it seriously. Next, I use the following two methods:

  1. Remove the core code and exclude external causes by isolating external uncertainties;
  2. Refer to the documentation of touch events on MDN to find the internal cause that may cause such problems;

Pretty clear thinking, right? But I don’t find any inspiration in the documentation that might cause this problem. Fortunately, I’ve made the problem very clear with the first step, so keep thinking.


(3) Step 3: Make bold assumptions and carefully verify them

Basically, at this stage, the debug process enters the realm of experience and intuition. To successfully solve this problem, you sometimes need a little luck. I tried the following solutions during this process:

“No-brain test” : I’ll try solutions to some problems I see in search engines, one at a time, hoping that one of them will work and I’ll get more information to locate the cause of the problem. These attempts include adding the e.preventDefault() method to the event callback, replacing the TouchStart event with the Touchend event, or simply the Click event.

Embarrassingly, none of these attempts worked, and the problem is still there, but that’s ok. I wasn’t expecting much from this brief attempt, but it turns out that this strange phenomenon has nothing to do with the specific event type of the Touch, and nothing to do with the touch event accidentally triggering other events.

Now that I know I’m using the Touch event correctly, and that nothing else can interfere with the click event, I’m naturally starting to wonder if the browser is actually detecting the “click” of my finger. This can be answered with the following code:

window.addEventListener("touchstart", e => {
    console.log(e.target)
})
Copy the code

Amazing thing happened, my Navbar actually no longer has the page scroll after the touch event failure problem! But when I replace the code along the same lines with the following code to see the return value:


var navbar = document.querySelector(".navbar")

navbar.addEventListener("touchstart", e => {
    console.log(e.target)
})
Copy the code

The problem is again, and when the page scrolls, every time I click navbar again, the console doesn’t get any output, which means the browser thinks I didn’t click Navbar!

It’s not scientific, but I can see the light at the end of the tunnel. When I bind the touchStart event that was originally bound to navbar to the Window object via the event bubble mechanism and call the event back by judging the E.target property — the problem is solved, the page is fine, the world is clean…

The ultimate solution

The code is as follows:

var navbar = document.querySelector(".navbar")

window.addEventListener("touchstart", e => {
    if (e.target === navbar) {
        // callback}})Copy the code

Scan the QR code to see the correct effect:

Has the problem been solved successfully so far? Don’t.

While it’s refreshing to see the world go clean, it’s just a need being fulfilled, not a problem being solved. I mean the question in my mind: “Why is this ok when it wasn’t?” . This is a very important question, and I hope you don’t lose sight of it.

Do you agree? So let’s move on.

Let’s go back and look at our code again. It’s pretty clear that it’s pretty lean, and the only thing that could go wrong is the fixed positioning we gave to navBar. Navbar could not detect our clicks, but Window could. By putting these two clues together, I came up with a very suspicious object: hierarchy.

I tried to cancel navbar position: fixed; For the record, sure enough, everything is back to normal. This statement seems to be the cause of this bizarre phenomenon. And the factor THAT I can think of that is the hierarchy, I mean the hierarchy of DOM objects.

Here’s how I ended up explaining this strange phenomenon:

When the page is initialized, the browser’s DOM tree is rendered correctly, meaning that the relationship between DOM elements is correct, so the Navbar element captures our TouchStart event exactly. But when the page scrolls, the browser loses the navbar element hierarchy. The TouchStart event cannot be captured by the navbar element via bubbling, so our bound event has no response. Once we have the entire Window object monitoring the TouchStart event, the browser can re-evaluate the relationship between DOM objects correctly, the Navbar layer can catch bubbles, and everything is fine.

Does this explanation convince you? In fact, I have no idea, after all, this is just a speculation based on the phenomenon. But in any case, the browser, not my code, should be blamed for this strange phenomenon.

Is that the end of the problem? Don’t. If only by a phenomenon, a speculation on the pan browser, will let people have a feeling of approval, so that some people disagree with it? Will, my own heart is more empty, but it doesn’t matter, as long as master the following key tricks, the pan browser is not a minute.

The trick is to test a few browsers yourself, my friend!

We differentiate browsers by engine,

  • Browsers that use Webkit: Chrome, Safari
  • The browser using the Gecko engine is Firefox
  • Browser using the Presto engine: Opera

So I downloaded the Firefox browser to re-test the original code under the page effect, and there was no problem!

Hehe, it’s not my code. All Webkit browsers are bad :).

Three, summary

You think this article is over? Not at all. In fact, you should feel that although the debug successfully solved the problem, the whole process was not smooth and efficient, and there were some detours in the process. Based on the experience of this debug, I summarize the following aspects that need to be paid attention to in the next debug process:

  • Use Google, Google (English keywords), Baidu search engine search question keywords;
  • Be alert for problems where you don’t find results (check your code);
  • Write Demo, isolate core code, simplify analysis background;
  • Ensure to master relevant technical knowledge;
  • Test with each browser first (so you can rule out browser bugs early);
  • As soon as possible to usedebuggerKeyword instead ofconsole.logMethod for debugging; (that’s right.debuggerKeywords make debugging more efficient);
  • Observe the problem carefully, make bold assumptions, and verify it carefully;
  • Don’t give up. After solving a need, solve a problem.
  • If you have the time and energy, write a blog post summarizing the problems you found and what you learned during the debug process.

The above is the process and thinking of finding, analyzing and solving problems in the actual development process. I hope it will be helpful to you.