我是怎样经由过程debug胜利甩锅浏览器的:处理fixed定位元素,在页面转动后touch事宜失效题目

假如你关注我应当晓得,我近来对PC端页面举行挪动适配。在这个历程当中,为了节约用户300ms的时刻,同时赋予用户更实时的点击反应(这意味着更好的用户体验),我在尝试运用挪动端独占的 touchstart 事宜替代传统的 click 事宜,这历程当中我碰到了一些小题目,并成功处理了,你能够经由历程这篇文章检察详细的状况。

所谓灾患丛生,在行将宣布上线的时刻,我又倏忽发明运用 touchstart 事宜后,挪动装备上涌现了另一个比较诡异的征象:当用户转动页面后,底本绑定在fixed定位的navbar元素上的 touchstart 事宜会时常失效。你能够经由历程扫描下方二维码,并运用你的Safari浏览器或Chrome浏览器(注重:不是浏览器自带的模拟器)亲身觉得这一新鲜的征象。

《我是怎样经由过程debug胜利甩锅浏览器的:处理fixed定位元素,在页面转动后touch事宜失效题目》

固然,终究我成功处理了这个题目,而且有意思的是,这个题目好像并不出自我的代码,而被我归罪因而浏览器的Bug。然则关于这个Bug涌现的道理,我也只需一个也许的推想,假如你清楚的晓得发作这一征象的缘由,也迎接你和我分享。

在本篇文章中,我不但会纪录我的处理计划,而且会纪录我在碰到这个题目后的debug的历程与剖析思绪。不过假如你正被这个题目搞得焦头烂额,只想快点挣脱这个题目,你能够直接翻阅到文章底部“处理计划”部份,参考我的处理计划(我真是知心,对吧? ?)。

一 · 题目形貌

  • 挪动装备:iPhone 6
  • 操纵系统:iOS 11.2.5
  • 测试浏览器:Safari,Chrome
  • 点击此处检察示例代码

当在挪动装备上运用测试浏览器翻开网页并转动屏幕后,会发明再次点击navbar,navbar元素绑定的 touchstart 事宜并没有被触发(或偶然不被触发)。

二 · 剖析排查

(一)步骤一:运用搜刮引擎

我是在无意中发明该题目的,当时视察到的征象是绑定在navbar上的 touchstart 事宜偶然会被触发,偶然会失效。因而我运用Google搜刮了“touchstart 事宜偶然失效”的症结字,很遗憾,并没有什么靠谱的答案。这申明“并不存在touchstart偶然失效的题目”。也就是说,我须要找到确实的令 touchstart 相应事宜失效的缘由。

接下来,我不停的在挪动装备上尝试种种操纵(双击,转动屏幕,放大等),并留意挪动装备的相应,终究将 touchstart 绑定事宜失效的缘由确定为在“页面转动以后”。接下来的事很简朴,继承Google搜刮“touchstart 事宜在页面转动后失效”。视察首屏搜刮结果,并点击进去检察,遗憾的是,并没有什么适宜的信息:

《我是怎样经由过程debug胜利甩锅浏览器的:处理fixed定位元素,在页面转动后touch事宜失效题目》

接着我抱着碰命运运限的立场切换百度搜刮一样的症结词,还不错,已有了一个类似度很高的搜刮结果,然则阅读后发明依旧不是我想要的:

《我是怎样经由过程debug胜利甩锅浏览器的:处理fixed定位元素,在页面转动后touch事宜失效题目》

是时刻上终究的大杀器了,运用英文症结字搜刮!以下是我运用了“touch event doesn’t respond after page scroll”症结字的Google搜刮结果:

《我是怎样经由过程debug胜利甩锅浏览器的:处理fixed定位元素,在页面转动后touch事宜失效题目》

老样子,照样没有使人满意的结果。至此我获得了两点信息:

  1. 多是我的代码写的有题目:由于很小能够涌现新鲜的征象历来没有人碰到过;
  2. 我应当从 touch 事宜的相干观点上找缘由;

(二)步骤二:断绝代码,清楚明了观点

至此,debug的第一阶段完毕,我的徒劳无功表清楚明了这个题目并不简朴,我须要认真对待,接下来我采用了以下两种要领:

  1. 抽离中心代码,经由历程断绝外界不确定要素,消除外因;
  2. 查阅MDN上touch事宜的文档,查找能够激发此类题目的内因;

思绪很清楚对吧,然则我并没有在相干文档中找到能够激发此题目的任何灵感。不过幸亏我经由历程第一步已让题目变得异常清楚了,不要泄气,继承思索。

(三)步骤三:斗胆勇敢假定,警惕求证

基本上到了这个阶段,debug的历程就进入到履历和直觉范畴了,要成功处理这个题目,你偶然还须要一点点命运运限,我在这个历程当中尝试了以下计划:

“无脑试对”:我将在搜刮引擎中看到的一些题目的处理要领,逐一实验,愿望有个会管用,我能够获得更多信息去定位题目涌现的缘由。这些尝试有:为事宜的回调函数增加 e.preventDefault() 要领,替代 touchstart 事宜为 touchend 事宜或许直接是 click 事宜。

很为难,这些尝试都没有起到作用,题目依旧存在,不过没有关联,我原本也没有对这个简短的尝试抱太大的希冀,不过这实在也申明这个新鲜的征象和touch详细的事宜范例无关,和touch事宜误触发其他事宜无关。

目前为止,我已晓得了 touch 事宜我运用的体式格局是正确的,而且没有其他的要素能够滋扰点击事宜的触发,自然而然的,我最先猎奇,浏览器究竟有无检测到我手指的“点击”。这能够经由历程以下代码获得答案:

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

巧妙的事变发作了,我的navbar竟然不再涌现页面转动后touch事宜失效的题目!然则当我依据雷同的思绪,将代码替代为下面的代码想要看看返回值时:


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

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

题目又涌现了,而且当页面转动后,每当我再次点击navbar,控制台没有任何输出,这意味着浏览器认为我并没有点击navbar!

这不科学,然则我已然看到成功的曙光。当我我将本来绑定在navbar上的 touchstart 事宜经由历程事宜的冒泡机制绑定在 window 对象,经由历程推断 e.target 属性举行事宜回调时 — 题目处理了,页面一般了,全部天下都清净了…

终究的处理计划

代码以下:

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

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

扫描二维码检察正确的结果:

《我是怎样经由过程debug胜利甩锅浏览器的:处理fixed定位元素,在页面转动后touch事宜失效题目》

到此为止题目被成功处理了吗?并没有。

虽然天下清净了的那一刻使人神清气爽,然则这只是需求被完成了,题目并没有被处理,我指的是我内心的那个题目:“为何如许就行,而本来那样就不可?”。这个题目至关重要,也愿望你们不要疏忽。

你赞同吗?那让我们继承。

让我们再回过甚剖析一下我们的代码,很明显它已异常精简了,唯一能够出题目的处所在于我们给navbar的 fixed 定位。我们再想想我们是怎样“误打误撞”处理这个题目的,navbar检测不到我们的点击,然则window能够,将这两个线索放在一同思索,我得出了一个很值得疑心的对象:层级。

我试着取消了navbar的 position: fixed; 声明,果真,统统又都一般了。看来这一奇特征象的始作俑者就是这条声明。而我能想到与之相干的要素就是层级,我是指DOM对象的层级

终究我是如许诠释这个新鲜征象发作的缘由:

在页面初始化时,浏览器的DOM树被正确的衬着,也就是说DOM元素间的关联正确,因而 navbar 元素能够正确的捕获我们的 touchstart 事宜,然则当页面转动后,浏览器丧失了 navbar 元素的层级关联, touchstart 事宜没法经由历程冒泡被 navbar 元素捕获,因而我们绑定的事宜没有相应。而当我们让全部window对象监测 touchstart 事宜后,浏览器能够从新正确的盘算DOM对象间的关联,navbar 层能够捕获到冒泡的事宜,因而统统就都一般了。

这个诠释有压服你吗?实在我内心也没个底,毕竟这只是我基于征象的一种推想。但无论如何,这类新鲜征象的发作,应当被归罪于浏览器,而不是我的代码(哈,松了一口气)。

到这里,这个题目就完毕了吗?并没有。假如只是凭一个征象,一个推想就甩锅浏览器,会不会让人有一种钦定的觉得,让某些人不服呢?会的,我本身心就比较虚,不过没紧要,只需控制了以下的症结窍门,甩锅浏览器还不是分分钟的事。

该窍门就是 — 你本身去多测几个浏览器啊,朋侪!!

我们依据引擎辨别差别浏览器,

  • 运用Webkit引擎的浏览器:Chrome,Safari
  • 运用Gecko引擎的浏览器:Firefox
  • 运用Presto引擎的浏览器:Opera

因而我下载了Firefox浏览器从新测试了原代码下页面结果,果真没有题目!

呵呵,不是我代码的题目。都是运用Webkit引擎的浏览器不好 :)。

三 · 总结

你认为本篇文章就这么完毕了?并没有(扫兴吧),现实上写到这里,你应当也有所觉得,虽然此次debug成功处理了题目,但全部历程并不流通高效,而且在个中走了些许弯路。连系本次debug的履历,我总结了以下几个在下次debug历程当中须要注重的方面:

  • 顺次运用Google,Google(英文症结字),百度搜刮引擎搜刮题目症结字;
  • 对没有搜刮到结果的题目保持警惕(搜检本身的代码);
  • 编写Demo,断绝中心代码,简化剖析背景;
  • 确保控制相干手艺学问点;
  • 起首运用各浏览器测试(如许便能够尽早消除是不是是浏览器Bug);
  • 尽早运用 debugger 症结字而不是 console.log 要领举行调试;(没错,debugger 症结字让调试更高效);
  • 仔细视察题目,斗胆勇敢假定,警惕求证;
  • 不要摒弃,在处理需求后,要处理题目;
  • 假如偶然刻精神的话,将发明的题目和debug历程当中学到的学问总结一篇博客吧 :);

以上,是我在现实开辟历程当中发明题目,剖析题目并处理题目的历程和思绪,愿望对你们有协助。

    原文作者:libinfs
    原文地址: https://segmentfault.com/a/1190000013446850
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞