🙃 兼容性 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)