-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
fix the bug of UIwebview.MutationObserver not working exception in iO… #3027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
多谢详细的报告! 测试例 live link http://yyx990803.github.io/vue-bug-demo/test.html |
const UA = inBrowser && window.navigator.userAgent.toLowerCase() | ||
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0 | ||
export const isAndroid = UA && UA.indexOf('android') > 0 | ||
export const isIos = UA && /(iphone|ipad|ipod|ios)/i.test(UA) | ||
export const isIos93 = isIos && UA.indexOf('os 9_3') > 0 | ||
export const isIndexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line needs to check inBrowser
first otherwise it would throw Error in Node.js.
Also I'd rename it to hasIndexDB
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition: since this check is only used for the specific case of iOS (detecting WKWebView), there is no need to check webkitIndexedDB
and mozIndexedDB
.
调整了一下: const iosVersionMatch = isIos && UA.match(/os ([\d_]+)/)
const iosVersion = iosVersionMatch && iosVersionMatch[1].split('_')
const hasMutationObserverBug =
iosVersion &&
Number(iosVersion[0]) >= 9 &&
Number(iosVersion[1]) >= 3 &&
!window.indexedDB |
Fixed: MutationObserver not working in iOS 9.3.* UIWebView
@GitHubXur thanks, fixed in 9c6a341 |
@GitHubXur 应该和你想的不是一回事。indexedDB 是用来检测是不是 UIWebView 的。 可能是 iOS 10 下的 useragent string 变了,我没升级,你能不能看下 iOS 10 下 UA 和 iosVersion 这两个变量分别是什么值 |
那逻辑上应该没有错啊。 |
Vue.js the bug of UIwebview.MutationObserver not working exception in iOS 9.3.*
Vue.js version
1.0.24
Reproduction Link
https://github.com/miccycn/vue-bug-demo
Steps to reproduce
IOS 9.3.x系统的以下浏览器中打开demo页面:
执行以下动作:
What is Expected? What is actually happening?
点击按钮后,弹出“Right”的是Vue正常工作,弹出“Error”是Vue出现了异常。
我用v-text方法在按钮上输出arr.length。同时我在这里的click事件中用原生方法做了一个强制判断:
而在IOS 9.3.x的这些出现异常的浏览器中这时候arr.length的真实数值和按钮上显示的不一样,所以会弹“Error”。
目前已知在IOS 9.3.x以下浏览器中运行是正常的:
在IOS9.2及以下的系统版本中所有浏览器都是正常的。
通过审查Vue的源码,发现问题出在util/env.js中全局MutationObserver的监听。
v1.0.24里这段不计入代码覆盖率测试的代码中,还特意对IOS的微信webview做了强制降级处理(函数的异步执行不使用MutationObserver而采用setTimeout(0)),所以在微信webview下没有这个异常。尝试取消对IOS的微信的特殊处理后,微信webview也出现了这个问题。
经过实验测试基本可以认为是浏览器底层对MutationObserver的异步执行出现了问题,在浏览器屏幕滚动或回弹的过程中如果同时让touch的一些默认事件触发,会产生对MutationObserver的阻塞,以至于MutationObserver的回调函数不去执行。造成后后面一系列的异常。
IOS 9.3对系统底层的touch、click等很多事件进行了重写,取消了300ms延迟可能会连带着在一些莫名其妙的地方带来阻塞,特别容易对一些涉及异步的原生方法产生影响。
有异常的国产浏览器的共同点是他们都是UIWebView,表现正常的浏览器(safari除外)均采用了WKWebView。
(补充:在IOS中,WKWebView是IOS8以后才有的,比UIWebView更新,性能也更好,现在还没推广开来,国内厂商大都还在用UIWebView。)
我最后提交了一个PR,改成对IOS 9.3的所有UIWebView在MutationObserver这个方法上做降级处理。(UIWebView不支持IndexedDB)
把源码中对ios微信的hack删掉了,毕竟实在太dirty……不过PR里面我对IOS9.3的判断这里我处理得也很dirty,这个与系统的UIwebview相关的bug估计以后不一定会修复,用系统版本来做判断毕竟不是长久之计。这个issue的异常就需要尤大大进一步考虑了。
如果不改Vue的源码,在这里对touch事件全部preventDefault掉,所有默认的触屏事件都用其他库来实现也是解决方法之一。但是我们的业务不允许我们preventDefault掉所有touchmove,所以只有在Vue源码中找原因了。