摘要:去查看一下的源碼,發(fā)現(xiàn)被改裝了,監(jiān)聽的回調(diào)回在事件觸發(fā)的時候觸發(fā)。搞清楚的觸發(fā)機制根據(jù)的描述當活動歷史記錄條目更改時,將觸發(fā)事件。說明了上,依舊不能阻止的觸發(fā)。最終解決由于刷新重新加載是肯定不會觸發(fā)的,所以可以后進行。
背景:
在使用Tarojs開發(fā)的時候,發(fā)現(xiàn)在ios上跳轉(zhuǎn)至其他頁面,再返回回來會出現(xiàn)接口接連調(diào)用兩次的情況。
排查過程:1.由于接口調(diào)用在組件的didMount里,所以看其他的組件也是didMount調(diào)用兩次,這讓我感覺很詫異,componentDidMount這個生命周期應(yīng)該不會調(diào)用兩次的;
2.我打開了weinre查看,發(fā)現(xiàn)了有兩個一模一樣的頁面組件,如下圖
因為是router層級上double了,所以所有組件都會實例化兩次,此時我懷疑是taro/router的問題。
我又去看了一下果園是否也是有同樣的情況,結(jié)果發(fā)現(xiàn)在page componentDidMount里調(diào)用的tree/get等首屏數(shù)據(jù)接口調(diào)用了兩次。。。
去查看一下@tarojs/router的源碼,發(fā)現(xiàn)
history被tarojs/router改裝了,history.listen監(jiān)聽的回調(diào)回在popstate事件觸發(fā)的時候觸發(fā)。
現(xiàn)在的問題根源確定了是由于popstate事件的觸發(fā),導致了tarojs/router認為當前頁面是進行了一次前端路由跳轉(zhuǎn),所以進行了兩次頁面級別的渲染,導致所有的組件實例的生命周期都走了兩次。那么問題來了,明明我們根本沒有利用history的特性,所有的跳轉(zhuǎn)都是刷新式跳轉(zhuǎn),為什么這個popstate會觸發(fā)呢。
3.搞清楚popstate的觸發(fā)機制
根據(jù)MDN的描述:
當活動歷史記錄條目更改時,將觸發(fā)popstate事件。如果被激活的歷史記錄條目是通過對history.pushState()的調(diào)用創(chuàng)建的,或者受到對history.replaceState()的調(diào)用的影響,popstate事件的state屬性包含歷史條目的狀態(tài)對象的副本。
需要注意的是調(diào)用history.pushState()或history.replaceState()不會觸發(fā)popstate事件。只有在做出瀏覽器動作時,才會觸發(fā)該事件,如用戶點擊瀏覽器的回退按鈕(或者在Javascript代碼中調(diào)用history.back())
理論上popstate是不會在我們的應(yīng)用了觸發(fā)的,我試驗了一下這個東西究竟是何方神圣。
var a = document.getElementById("a"); a.onclick = function() { location.href = "/aaa.html" } window.addEventListener(‘popstate’, function handlePopState() { console.log("handlePopState") }, false);
點擊后返回,壓根沒有觸發(fā)popstate,不管在ios還是android上。
然后我將
location.href = ‘/aaa.html"
替換成
history.replaceState(null, "", "aaa.html");
在ios上返回是無刷新式的返回,觸發(fā)了popstate事件,僅僅url回退成popstate.html。
在android上返回是刷新式返回,同樣觸發(fā)了popstate事件,然后會重新解析/加載/執(zhí)行。
到這里已經(jīng)確定了location.href的跳轉(zhuǎn)后返回是不會觸發(fā)popstate的,因為是刷新式的返回,那就是我們在業(yè)務(wù)里有動了history的api,此時我懷疑是在業(yè)務(wù)底層代碼使用了history。
4.查看業(yè)務(wù)底層跳轉(zhuǎn)代碼
看到navigation.forward在H5僅僅使用了location.href進行跳轉(zhuǎn),但是在此之前為了加is_back參數(shù)表示當前頁面是通過回退到達的,使用了history.replaceState。
我模擬一下這個操作
var a = document.getElementById("a"); a.onclick = function() { history.replaceState(null, "", "popstate33.html?a=1"); location.href = "/aaa.html" }
果不其然,在ios里在返回的時候會觸發(fā)popstate事件,而android不會觸發(fā)。
說明了ios上,依舊不能阻止popstate的觸發(fā)。
5.解決方案
由于在ios中返回頁面會觸發(fā)popstate,在tarojs/router此時認為進行了一次前端路由
5.1 在進入頁面后根據(jù)is_back進行一次reload
5.2 在底層跳轉(zhuǎn)代碼包上進行再一次包裝,跳轉(zhuǎn)的時候不再使用history.replaceState
然而。。。。。。。tarojs/router有這么一行- -,也就是業(yè)務(wù)層不使用history.replaceState,它自己本身也用了,我把這行注釋掉,且業(yè)務(wù)上不使用replaceState,ios回退才不會觸發(fā)popstate。
所以。。。。
5.1由于不能使用replaceState將is_back去掉,不然將無限循環(huán)刷新;
5.2由于tarojs/router本身自己使用了history.replaceState,也沒有了意義。
一切又回到了起點。。。。
最終解決
由于刷新重新加載是肯定不會觸發(fā)popstate的,所以可以replaceState后進行reload。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/106161.html
摘要:單頁應(yīng)用的原理從早起的根據(jù)的變化,到根據(jù)的的變化,實現(xiàn)無刷新條件下的頁面重新渲染。那么在單頁應(yīng)用中是如何監(jiān)聽的變化呢,本文將總結(jié)一下,如何在單頁頁面中優(yōu)雅的監(jiān)聽的變化。在下幾章中,重點介紹一下如何監(jiān)聽的改變。 ??單頁應(yīng)用的原理從早起的根據(jù)url的hash變化,到根據(jù)H5的history的變化,實現(xiàn)無刷新條件下的頁面重新渲染。那么在單頁應(yīng)用中是如何監(jiān)聽url的變化呢,本文將總結(jié)一下,...
摘要:單頁應(yīng)用的原理從早起的根據(jù)的變化,到根據(jù)的的變化,實現(xiàn)無刷新條件下的頁面重新渲染。那么在單頁應(yīng)用中是如何監(jiān)聽的變化呢,本文將總結(jié)一下,如何在單頁頁面中優(yōu)雅的監(jiān)聽的變化。在下幾章中,重點介紹一下如何監(jiān)聽的改變。 ??單頁應(yīng)用的原理從早起的根據(jù)url的hash變化,到根據(jù)H5的history的變化,實現(xiàn)無刷新條件下的頁面重新渲染。那么在單頁應(yīng)用中是如何監(jiān)聽url的變化呢,本文將總結(jié)一下,...
摘要:單頁應(yīng)用的原理從早起的根據(jù)的變化,到根據(jù)的的變化,實現(xiàn)無刷新條件下的頁面重新渲染。那么在單頁應(yīng)用中是如何監(jiān)聽的變化呢,本文將總結(jié)一下,如何在單頁頁面中優(yōu)雅的監(jiān)聽的變化。在下幾章中,重點介紹一下如何監(jiān)聽的改變。 ??單頁應(yīng)用的原理從早起的根據(jù)url的hash變化,到根據(jù)H5的history的變化,實現(xiàn)無刷新條件下的頁面重新渲染。那么在單頁應(yīng)用中是如何監(jiān)聽url的變化呢,本文將總結(jié)一下,...
摘要:與事件都是瀏覽器歷史記錄,兩者都是中的,相對而言比更為強大。事件本身只是監(jiān)測的變化,我認為目前其主要意義就是與搭配使用從而使得在下歷史記錄前進后退按鈕依然有效。地址新的歷史記錄條目的地址。 hashchange與popstate事件都是瀏覽器歷史記錄API,兩者都是HTML5中的API,相對而言popstate比hashchange更為強大。注意這兩種歷史記錄管理都受同源策略的限制,這...
摘要:問題最近碰到兩個問題從首頁進入列表頁之后,點擊下一頁的時候,使用請求更新數(shù)據(jù),然后點擊瀏覽器后退按鈕就直接返回到首頁,實際這里想要的效果是返回列表頁上一頁。沒法記住之前分頁狀態(tài)。 問題 最近碰到兩個問題: 從首頁進入列表頁之后,點擊下一頁的時候,使用ajax請求更新數(shù)據(jù), 然后點擊瀏覽器后退按鈕就直接返回到首頁,實際這里想要的效果是返回列表頁上一頁。 在列表頁分頁為2的頁面進入詳情頁,...
閱讀 3948·2021-09-24 10:24
閱讀 1386·2021-09-22 16:01
閱讀 2713·2021-09-06 15:02
閱讀 1014·2019-08-30 13:01
閱讀 1002·2019-08-30 10:52
閱讀 633·2019-08-29 16:36
閱讀 2232·2019-08-29 12:51
閱讀 2333·2019-08-28 18:29