在Firefox中,当通过window.location.hash更新哈希值时,iframe会不断重新加载
我试图通过将window.location.hash设置为 'hash/value/for/section' 来更新iframe页面的哈希值。
不过,一旦哈希被设置,iframe就会重新加载。加载到页面后,再次进行哈希更新时,又会重新加载。
跳到页面的不同部分时,页面不会跳转到该部分;相反,它会从头加载,然后停在所选的部分。
我使用的是不带 '#' 的哈希值,因为浏览器在设置时会忽略前导的 '#'.引用: https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-location-hash-dev
在Chrome中工作正常。这个问题仅在Firefox浏览器中出现。
有谁遇到过这种问题吗?或者知道原因或解决办法?
import { Dialog, DialogContent, DialogBody } from "/dialog";
const IframeDialog = ({ closeIFrame, accountId }) => (
<Dialog isOpen onClose={closeIFrame} isCentered size="extraExtraLarge" fullSize
fullHeight
>
<DialogContent hasClose>
<DialogBody style={{ padding: "0px", margin: "10px" }}>
<iframe
title="Access Child Organization"
src={`${window.location.origin}/zem/${accountId}?frameorigin=${window.location.origin}#`}
style={
{
width: "100%",
height: "100%",
border: "none"
}
}
/>
</DialogBody>
</DialogContent>
</Dialog>
);
export default IframeDialog;
在iframe应用中,我将通过我们路由类实例的 push 方法来更新哈希。下面附有路由类的代码。
import Events from "@/custom-events";
function getHashPath () {
const { href } = window.location;
const hashIndex = href.indexOf("#");
return hashIndex === -1 ? "" : href.substring(hashIndex + 1);
}
function pushHashPath (path) {
window.location.hash = path;
}
function replaceHashPath (path) {
const hashIndex = window.location.href.indexOf("#");
window.location.replace(`${window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0)}#${path}`);
}
function stripLeadingSlash (path) {
return path.charAt(0) === "/" ? path.substr(1) : path;
}
function stripTrailingSlash (path) {
return path.charAt(path.length - 1) === "/" ? path.slice(0, -1) : path;
}
const decodeHashURL = function () {
let hashStr = getHashPath();
hashStr = stripTrailingSlash(hashStr);
return stripLeadingSlash(hashStr).split("/").map((hashValue) => decodeURIComponent(hashValue));
};
const encodeHashURL = function (hashParams = []) {
hashParams = hashParams.map((hashValue) => encodeURIComponent(hashValue));
return hashParams.join("/");
};
const hash = "policyId/app/menu";
const HASH_CHANGE_EVENT = "hashchange";
class Router extends Events {
state = [];
routeParams = {};
defaultRoute = "";
pushSet = new Set();
replaceSet = new Set();
constructor (props = {}) {
super();
this.defaultRoute = props.route || hash;
window.addEventListener(HASH_CHANGE_EVENT, this.handleHashChange, false);
}
getParams = () => {
const params = decodeHashURL();
const hashMap = this.defaultRoute.split("/");
const p = {};
hashMap.forEach((hsh, index) => {
if (params.length >= index) {
if (index === hashMap.length - 1) {
p[hsh] = params.slice(index).join("/");
} else {
p[hsh] = params[index];
}
}
});
return p;
};
setDefaultRoutePath = (route) => {
this.defaultRoute = route;
};
handleHashChange = (event) => {
// ../../../custom-events/lib/js/init.js
const href = event.newURL;
const hashIndex = href.indexOf("#");
const currentHash = hashIndex === -1 ? "" : href.substring(hashIndex + 1);
if (this.pushSet.has(currentHash)) {
this.pushSet.delete(currentHash);
this.triggerEachAsync("push");
} else if (this.replaceSet.has(currentHash)) {
this.replaceSet.delete(currentHash);
this.triggerEachAsync("replace");
} else {
this.trigger("HashChanged", this.getParams());
}
};
push = (hashParams) => {
const currentPath = getHashPath();
const newPath = encodeHashURL(hashParams);
if (newPath !== currentPath) {
this.pushSet.add(newPath);
pushHashPath(newPath);
}
};
replace = (hashParams) => {
const newPath = encodeHashURL(hashParams);
this.replaceSet.add(newPath);
replaceHashPath(newPath);
};
}
const RouterInstance = new Router();
export { RouterInstance as default };
Firefox版本:150.0.2。Mac 64位
解决方案
据Gemini(下文引用),这是Firefox的自然行为。尽管你也可以 scrollTo 直接滚动到页面的片段;但如果坚持走URL的方式,可以使用 preventDefault。
关键行为怪癖——同值重载: 与Chrome或 Safari不同,在Firefox中,将location.hash = location.hash会强制页面重新加载或滚回到锚点,即使哈希字符串保持相同。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。