參考資料
- html5新特性:利用history的pushState等方法來解決使用ajax導(dǎo)致頁面后退和前進(jìn)的問題
- 擊按鈕切換iframe的src,這個(gè)路徑如何不會被記錄到history中?
- iframe 后退 瀏覽器history 問題
- ajax與HTML5 history pushState/replaceState實(shí)例
一. 遇到的問題
我們使用iframe嵌套自己系統(tǒng)的頁面,但是瀏覽器刷新之后,無法保持當(dāng)前打開的頁面
二. 問題分析
?原因
之所以會刷新頁面后無法保持住當(dāng)前打開的頁面,是因?yàn)闉g覽器地址欄的url始終是固定的,我們打開的頁面改變的是iframe
標(biāo)簽的src屬性值,從而實(shí)現(xiàn)不同頁面之間的切換。
?解決
在url的后面添加?name=當(dāng)前畫面id,當(dāng)我們進(jìn)入頁面之后,根據(jù)name的參數(shù)值,來改變iframe
標(biāo)簽,從而實(shí)現(xiàn)刷新后頁面保持。
三. 代碼示例
?登錄頁面,點(diǎn)擊后登錄到系統(tǒng)的首頁
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="login">點(diǎn)擊登錄系統(tǒng)</button>
</body>
<script>
login.addEventListener("click", function() {
location.replace("./03-2-系統(tǒng)頁面.html?name=home");
});
</script>
</html>
?主系統(tǒng)頁面文章來源:http://www.zghlxwxcb.cn/news/detail-487304.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#contanier {
display: flex;
justify-content: space-between;
}
iframe {
/* 根據(jù)視口的寬度和高度計(jì)算iframe的寬和高 */
width: calc(100vw - 150px);
height: calc(100vh - 30px);
}
</style>
<title>系統(tǒng)首頁</title>
</head>
<body>
<div id="contanier">
<div id="menu">
<li id="es6">ES6網(wǎng)站</li>
<li id="css">css網(wǎng)站</li>
<li id="java">java網(wǎng)站</li>
<li id="php">php網(wǎng)站</li>
</div>
<div id="content">
<iframe></iframe>
</div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.6.3.js"></script>
<script>
// 頁面的工具類
class Utils {
// 模擬從后臺獲取到的菜單欄以及其url
static urlMap = new Map([
['es6', './03/02-es6.html'],
['css', './03/03-css.html'],
['java', './03/04-java.html'],
['php', './03/05-php.html'],
['home', './03/01-首頁.html']
]);
// 獲取本頁面不含參數(shù)的url
static getUrl() {
const {
origin,
pathname
} = location;
return origin + pathname;
}
// 獲取url中指定的參數(shù)
static getParamFromUrl(url, param) {
return new URLSearchParams(new URL(url).search).get(param);
}
}
$(function() {
// 事件綁定
eventBind();
// 加載頁面
loadPage();
});
function eventBind() {
// 當(dāng)瀏覽器前進(jìn)后退時(shí),會觸發(fā)popstate事件
window.addEventListener("popstate", function(evnet) {
loadPage();
});
$("#menu li").click(function(event, triggerFlg) {
const pageId = this.id;
reloadIframe(pageId);
/*
如果是用戶手動(dòng)點(diǎn)擊觸發(fā),則將當(dāng)前url添加到瀏覽器的history中
如果是通過函數(shù)來觸發(fā)的點(diǎn)擊事件,則不將url添加到瀏覽器的history中
*/
if(!triggerFlg) {
history.pushState(null, "", `${Utils.getUrl()}?name=${pageId}`);
}
});
}
function loadPage() {
const pageId = Utils.getParamFromUrl(location.href, "name");
// 如果url中沒有 ?name=對應(yīng)的屬性值,或者Utils.urlMap中沒有pageId對應(yīng)值的話
if(!pageId || !Utils.urlMap.get(pageId)) {
// 將當(dāng)前 url + ?name=home 的路徑替換到瀏覽器的history中
history.replaceState(null, "", `${Utils.getUrl()}?name=home`);
// 重載頁面,此時(shí)url中的參數(shù)為?name=home
loadPage();
return;
}
// 如果當(dāng)前是home頁的話,就重載iframe標(biāo)簽
if(pageId == "home") {
reloadIframe(pageId);
return;
}
/*
手動(dòng)觸發(fā)點(diǎn)擊事件
第二個(gè)參數(shù)是為了在手動(dòng)觸發(fā)點(diǎn)擊事件的時(shí)候傳遞一個(gè)參數(shù)
傳遞此參數(shù)的目的是為了讓點(diǎn)擊事件的回調(diào)區(qū)分,當(dāng)前點(diǎn)擊事件是用戶主動(dòng)點(diǎn)擊觸發(fā),
還是通過函數(shù)來手動(dòng)觸發(fā)的
*/
$("#" + pageId).trigger("click", true);
}
function reloadIframe(pageId) {
// 或者可以用這種方式
// document.querySelector("iframe").contentWindow.location.replace(Utils.urlMap.get(pageId));
// 清空iframe標(biāo)簽
$("#content").empty();
// 創(chuàng)建新的iframe標(biāo)簽,并指定url
$("<iframe>", {
src: Utils.urlMap.get(pageId)
}).appendTo($("#content"));
}
</script>
</html>
四. 代碼分析
- 在
reloadIframe
方法中,我們并不是直接修改的iframe標(biāo)簽的src屬性,而是銷毀掉既存的iframe標(biāo)簽,并新創(chuàng)建一個(gè)。如果直接修改src屬性的話,src中的地址會直接存入history
對象中,給瀏覽器前進(jìn)后退功能帶來影響。直接創(chuàng)建iframe標(biāo)簽,src中的地址并不會寫入history
對象中。 - 除了新創(chuàng)建iframe標(biāo)簽之外,我們還可以通過直接調(diào)用iframe標(biāo)簽內(nèi)部的window對象中的
location.replace()
方法來實(shí)現(xiàn)地址切換。 - 由于新創(chuàng)建的
iframe
標(biāo)簽的src
屬性值并不會存入history對象中,因此我們需要手動(dòng)調(diào)用history.pushState()
這個(gè)api來存入到history對象中。 -
$("#menu li")
上的點(diǎn)擊事件可由用戶主動(dòng)點(diǎn)擊觸發(fā),也可由window上的popstate
事件手動(dòng)觸發(fā),當(dāng)是由popstate事件手動(dòng)觸發(fā)時(shí),說明用戶使用了瀏覽器的前進(jìn)后退功能,此時(shí)不需要將url存儲history中。
五. 效果
文章來源地址http://www.zghlxwxcb.cn/news/detail-487304.html
到了這里,關(guān)于JS 刷新保持iframe頁面并支持瀏覽器前進(jìn)后退的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!