🙃 兼容性 BUG 万恶之源 : IE 浏览器html
昨天晚上,原本舒舒服服的躺在被窝睡觉,睡前一看企业邮箱,哦豁,好家伙,给我报了四个BUG,我再进入一看,映入眼前的是 : 360兼容模式下,在A页面点击按钮没法跳转
、IE浏览器在B页面点击返回按钮无效果,停留在当前页面
、C页面弹窗按钮,点击以后,弹窗没关闭,点击无效果
...node
什么鬼,玩我呢?这几个 BUG 的最终缘由都是IE上没法跳转(小声逼逼,测试说操做步骤不一样,我心累了)因而今天早上,再次踏上漫长的 fix bug 之路。react
咋,还能代码有问题?相信这段代码,你们都会写吧?浏览器
<Button onClick={this.backEvent} />
复制代码
backEvent = () => {
// 返回前作些其它的处理
let cb_function = dosomething();
const { history } = this.props;
if (history) {
history.push(cb_function);
}
};
复制代码
而后跑项目,找到页面所在的位置,点击返回,果真,gg了react-router
这啥鸡儿玩意,什么叫作对象不支持此操做
,咋滴,变脸了呢,在 Chrome 下你可不是这样的。函数
既然它说这个对象不支持这个操做,那是指 history
对象不支持这个PUSH
操做?测试
因而我去把这个玩意,打印了一下ui
玩尼玛呢,有的啊,这什么骚操做,为啥就报错了???this
因而我又去项目中,看了一下关于 this.props.history.push
的正确使用方式,就是这么写的啊。wc !spa
<!-- 项目中其它地方用到的 this.props.history.push -->
<!-- 代码真实跳转路径和文案已被我和谐 -->
<div styleName="item" onClick={() => {
this.props.history.push('/juejin');
}}
>
跳到掘金
</div>
复制代码
难道是我写这段代码以前没有烧香拜佛的缘由?没办法了,只可以,使用必杀技了,debugger !!!
先来 debugger 能够正常跳转的代码。
这个 push 方法是 react-router
注入的,咱们能够 debugger 看到,进入了 pushState 中,紧接着咱们继续 debugger
再往下,发现进入了 setState({ action, location })
, 接着推入栈
结果就是 : 成功跳转!!!
咱们再来 debugger 一下异类
的代码,在 IE 中,一步一步 debugger。在这里建立了一个 location 对象
紧着着,这里会使用 createHref(location)
函数,生成一个 href
对象,获取 key
和 state
目的就是在可使用 react-router
注入的 history
中,去操做 pushState
方法。
没毛病,可是,到了这里以后,再往下走,就跳到了一个名为 : useLocation.js 的文件中
在这个文件夹中,就报了 对象不支持此操做。就很骚气。 what ????? 这什么鸡儿玩意啊,卧槽
首先怀疑是 pushState
的兼容性问题,因而去看了一下兼容性
果真本身仍是太蠢了,回过头想一想,要真是 pushState 兼容性问题的话,那么第一个跳转也不可能成功。
难道是个人问题?仍是 react-router 的问题?仍是 IE 问题?
其实并无解决,由于我真不知道如何解决了,因此用了降级方法,就是 window.location.href 原生方法。
react-router 对于不可以使用 canUseHistory 时,也是采用的 window.location.href
// 部分代码无偿奉献
function push(path, state) {
var action = 'PUSH';
// 获得一个 location 对象
var location = createLocation(path, state, createKey(), history.location);
transitionManager.confirmTransitionTo(
location,
action,
getUserConfirmation,
function(ok) {
if (!ok) return;
// 建立一个 href 对象
var href = createHref(location);
var key = location.key,
state = location.state;
if (canUseHistory) {
// 第二个不可跳转的,就死在了这里,我也不知道为何
globalHistory.pushState({
key: key,
state: state
}, null, href);
if (forceRefresh) {
window.location.href = href;
} else {
// 第一个能够跳转的就进入到了这里
var prevIndex = allKeys.indexOf(history.location.key);
var nextKeys = allKeys.slice(0, prevIndex + 1);
nextKeys.push(location.key);
allKeys = nextKeys;
setState({
action: action,
location: location
});
}
} else {
// 原生跳转
window.location.href = href;
}
}
);
}
复制代码
在我使用 window.location.href
解决了上述的问题以后,我觉得此事到此结束,可是!!!又出问题了,什么问题呢?测试报了一个现象 :
首先进入项目主页面,此时的 breadcrumb 面包屑均可以跳转(使用的history.push),以后进入到 A 页面,在 A 页面中点击
返回
按钮(此时的返回经过 window.location.href)实现了。成功返回以后,再次点击 breadcrumb ,无响应,不跳转了。
我懵逼了,这是什么鬼玩意啊,总不能将整个项目的跳转方式都换成 window.location.href
吧,因而,再次去排查
咱们看到,它报了一个 Event
错误
const event = new Event()
复制代码
OK,你牛逼 👍,除了牛逼没啥说的,那咋办,在汉鑫哥的帮助下,一块儿排查,定位到了 useLocation
文件上,前边好好的可跳转,都没这个文件的啥事,咋这里就有这个玩意了呢?这个文件是哪来的?
再一看,原来这个文件是在 react-use
里边的,恰好在 A组件中,使用到了这个库,去 node_modules
中找这个文件,看到这段代码
没毛病啊,这是啥状况,再次进行 Debugger,发现,只要没引入这个 A组件,那么在 IE 上,均可以正常跳转,在引入了这个 A组件(也就是用了这个库),就出问题了。
为了验证这个问题,把项目中用到 react-use
的都注释掉(幸亏就一个组件用到了这个库),重启,打开IE,怀着激动的心情,去试了一下,卧槽!!!!竟然能够了!!!!!
问题应该是,本来应该pushState的,在引入这个组件(加载这个库)了以后,就都被hack掉了,以后的跳转,都经过 Event,而 Event 在IE上又不兼容,因此凉了。(我的猜想)
千呼万唤始出来,我尿了,IE真的是太难过,每次作个东西,都要兼容IE、Edge,我心里是崩溃的,不过感谢IE,让我更加有耐心了,比哄女友还更加有耐心,感恩有你 (微笑.jpg)