引言
在现代Web开发中,我们经常需要在不同的标签页或窗口之间共享数据。IndexedDB提供了一种在客户端存储大量结构化数据的方法,并且可以通过定时器轮询的方式实现跨标签页的通信。本文将介绍如何使用IndexedDB和setInterval来实现这一功能。
IndexedDB简介
IndexedDB是一个运行在浏览器中的非关系型数据库,它允许我们存储和检索大量结构化数据。与传统的本地存储解决方案(如localStorage)相比,IndexedDB提供了更复杂的查询功能,并且可以存储二进制数据。
实现跨标签页通信
为了实现跨标签页通信,我们可以利用IndexedDB的数据库实例在不同标签页间共享的特性。通过在每个标签页中轮询数据库,我们可以检测到其他标签页对数据库所做的更改,并相应地更新当前标签页的数据。
示例代码
以下是实现跨标签页通信的示例代码,包括HTML和JavaScript部分。
HTML代码
我们有两个HTML文件:index.html用于添加学生信息,index2.html用于显示学生信息。
<!-- index.html -->
<body>
<h1>新增学生</h1>
<div>
<span>学生学号:</span>
<input type="text" name="stuId" id="stuId">
</div>
<div>
<span>学生姓名:</span>
<input type="text" name="stuName" id="stuName">
</div>
<div>
<span>学生年龄:</span>
<input type="text" name="stuAge" id="stuAge">
</div>
<button id="addBtn">新增学生</button>
<script src="./db.js"></script>
<script>
openDB('stuDB', 1)
.then((db) => {
document.getElementById("addBtn").onclick = function () {
addData(db, "stu", { "stuId": stuId.value, "stuName": stuName.value, "stuAge": stuAge.value });
stuId.value = stuName.value = stuAge.value = "";
}
})
</script>
</body>
<!-- index2.html -->
<body>
<h1>学生表</h1>
<table id="tab"></table>
<script src="./db.js"></script>
<script>
function render(arr) {
let tab = document.querySelector("#tab");
tab.innerHTML = `
<tr>
<td>学号</td>
<td>姓名</td>
<td>年龄</td>
</tr>
`;
var str = arr.map((item) => {
return `
<tr>
<td>${item.stuId}</td>
<td>${item.stuName}</td>
<td>${item.stuAge}</td>
</tr>
`
}).join("");
tab.innerHTML += str;
}
async function renderTable() {
let db = await openDB('stuDB', 1);
let stuInfo = await getDataByKey(db, "stu");
render(stuInfo);
setInterval(async function () {
let stuInfo2 = await getDataByKey(db, "stu");
if (stuInfo2.length !== stuInfo.length) {
stuInfo = stuInfo2;
render(stuInfo);
}
}, 1000);
}
renderTable();
</script>
</body>
JavaScript代码
db.js文件包含了操作IndexedDB的函数。
function openDB(dbName, version = 1) {
return new Promise((resolve, reject) => {
var db;
const request = indexedDB.open(dbName, version);
request.onsuccess = function (event) {
db = event.target.result;
console.log("数据库打开成功");
resolve(db);
};
request.onerror = function (event) {
console.log("数据库打开报错");
};
request.onupgradeneeded = function (event) {
db = event.target.result;
var objectStore = db.createObjectStore("stu", { keyPath: "stuId", autoIncrement: true });
objectStore.createIndex("stuId", "stuId", { unique: true });
objectStore.createIndex("stuName", "stuName", { unique: false });
objectStore.createIndex("stuAge", "stuAge", { unique: false });
};
});
}
function addData(db, storeName, data) {
var request = db.transaction([storeName], "readwrite").objectStore(storeName).add(data);
request.onsuccess = function (event) {
console.log("数据写入成功");
};
request.onerror = function (event) {
console.log("数据写入失败");
};
}
function getDataByKey(db, storeName) {
return new Promise((resolve, reject) => {
var transaction = db.transaction([storeName]);
var objectStore = transaction.objectStore(storeName);
var request = objectStore.getAll();
request.onerror = function (event) {
console.log("事务失败");
};
request.onsuccess = function (event) {
resolve(request.result);
};
});
}
总结
通过上述代码,我们可以实现在不同标签页之间共享和更新学生信息。这种方法利用了IndexedDB的持久性存储和定时器轮询的实时性,为跨标签页通信提供了一种有效的解s决方案。