我正在尝试使用历史 API 来制作普通 JavaScript 路由。我尝试使用此方法 history.pushState()
更改我的 URL,它可以工作并根据需要重命名我的 URL,但当我刷新页面时它不起作用
此代码片段示例使用 firebase,但我认为如果不使用实时服务器在本地运行它来生成本地主机 URL,它将无法正常工作:
//🚨 start config genrated by firebase app 🚨//
var firebaseConfig = {
apiKey: "AIzaSyAFN-KRpzvA4Aup1FBtq6BRfaVl_ErkxpE",
authDomain: "zeeda-f3f19.firebaseapp.com",
databaseURL: "https://zeeda-f3f19.firebaseio.com",
projectId: "zeeda-f3f19",
storageBucket: "zeeda-f3f19.appspot.com",
messagingSenderId: "295957581266",
appId: "1:295957581266:web:e52b40b525f249a3"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
//🚨 end genrated by firebase app 🚨//
//🚨 referance vriable 🚨//
const db = firebase.firestore();
const auth = firebase.auth()
/* start app */
const title = document.getElementById('title')
const content = document.getElementById('content')
const blo1 = document.getElementById('blo1')
const blo2 = document.getElementById('blo2')
const blo3 = document.getElementById('blo3')
let blogid = '1';
blo1.addEventListener('click', ()=>{
blog('1');
})
blo2.addEventListener('click', ()=>{
blog('2')
})
blo3.addEventListener('click', ()=>{
blog('3')
})
function blog(blogid){
db.collection('blog').doc(blogid).get().then(snap =>{
const titleData = snap.data().title;
const contentData = snap.data().content;
title.innerHTML = titleData;
content.innerHTML = contentData;
history.pushState({name:"blog"},'',`blog${blogid}`)
})
}
db.collection('blog').doc(blogid).get().then(snap =>{
const titleData = snap.data().title
const contentData = snap.data().content
title.innerHTML = titleData
content.innerHTML = contentData
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://www.gstatic.com/firebasejs/7.6.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.6.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.6.2/firebase-firestore.js"></script>
<title>Document</title>
<style>
ul {
padding: 0;
margin: 0;
list-style: none;
display: flex;
}
li {
margin: 10px;
}
a {
text-decoration: none;
}
</style>
</head>
<body>
<nav>
<ul>
<button id="blo1">blog1</button>
<button id="blo2">blog2</button>
<button id="blo3">blog3</button>
</ul>
</nav>
<h1 id="title"></h1>
<p id="content"></p>
</body>
</html>
最佳答案
当点击链接时,JavaScript 会发生两件事:
- 文档已转变为不同的状态
- 新网址已被推送到历史记录中
(JavaScript 还会阻止链接的正常行为(加载整个新页面)发生)。
通过将 URL 插入历史记录,您实际上是在声明该 URL 代表您将页面更改为的文档。
因此,为了实现这一点,您需要让服务器为该 URL 提供一个 HTML 文档,该文档将为您提供该状态。
这意味着您需要:
- 从服务器生成最终状态的文档
- 从客户端 JavaScript 为每个 URL 生成最终状态的文档
您可以使用手工制作的静态页面或增加以编程方式生成的静态页面或服务器端编程的级别来实现此目的。
是的,这往往需要大量工作。虽然 pushState
本身既快速又简单,但如果不做大量工作,它的用途就不会很大。
通过使用共享模板或围绕 Next.JS 等框架构建页面,您可以减轻大量工作量,这些框架可以在服务器端呈现客户端代码。
有些人喜欢为每个 URL 提供相同的 HTML 框架文档,并使用 JavaScript 加载所有内容……但是 breaks if the JS fails对于搜索引擎来说并不是很好的食物。
关于javascript - 如何使历史 API 中的链接像真实的一样工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59773791/