网页是否可以在不需要服务器调用的情况下从另一个文件动态插入数据?
我的意思是,.html页面可以使用XMLHttpRequest之类的内容进行自身更新,但是可以仅通过读取与html页面相同位置的文件来代替对服务器的调用。
伪代码
if(userclicks on x)
{
read and display contents of y within this div)
}
背景
我正在转换一个HTML报告,该报告当前使用一个 frameset 分为左右两个面板。左侧面板列出了一系列已处理的文件夹,右侧显示了对所选文件夹进行的处理。
答案 0 :(得分:1)
如果我正确阅读了您的问题,则所有必要的数据一开始就是页面的一部分(由于您无法从服务器加载,因此具有< / strong>到所有已经存在的地方-但请参见下面的内容以获取更多信息。但是你说过:
当用户更改选择内容时,先加载页面的所有内容然后使用javascript隐藏/显示文件的内容是不可行的,因为单个html文件太大而加载太慢。
因此,这表明数据本身比数据表示形式要小得多。
您当然可以在页面上拥有一个元素(例如,div
),并使用DOM通过呈现页面所保存数据的子集来进行更新。这是一个简单的示例:
const data = [
{label: "one", a: "a one", b: "b one", c: "c one"},
{label: "two", a: "a two", b: "b two", c: "c two"},
{label: "three", a: "a three", b: "b three", c: "c three"},
{label: "four", a: "a four", b: "b four", c: "c four"}
];
function populateMenu() {
const menu = document.getElementById("menu");
for (let i = 0; i < data.length; ++i) {
const entry = data[i];
const a = document.createElement("a");
a.href = `#entry-${i}`;
a.textContent = entry.label;
a.addEventListener("click", event => {
event.preventDefault();
showEntry(entry);
});
menu.appendChild(a)
}
}
function showEntry(entry) {
const content = document.getElementById("content");
const {a, b, c} = entry;
content.textContent = `a: ${a}, b: ${b}, c: ${c}`;
}
populateMenu();
#menu a {
padding: 4px;
}
<div id="menu"></div>
<div id="content"></div>
它使用ES2015 +语法,但是只有在需要针对目标环境的情况下,才可以对ES5执行相同的操作。
那里的content
div当然可以是页面显示的大部分。
这是单页应用程序(SPA)的基本性质,因此使用该术语进行进一步的研究可能会有用。但是您的SPA是独立的(尽管大多数SPA会进行服务器调用,但仍会如上所述更新页面)。
在评论中您说过:
当前,文件是在一开始就创建的,有一个主文件夹和一个代表每个文件夹处理的文件。用户可能已经处理了1000个文件夹,这意味着主文件实际上是1000个文件夹的列表,然后还有1000个其他文件,每个文件包含几页数据。因此,很明显,如果我们将所有这些内容合并到一个文件中,则大约要大1000倍,而用户只能看到与一个文件夹相关的处理信息,因此,您的上述方法对我而言不起作用。
恐怕你想吃蛋糕并吃掉它。 :-)您可以稍后再加载数据,也可以一开始就在页面上全部加载。您在问题中说过您以后不能加载数据,因此它必须在一开始就位于页面中。
但是:您在上面使用的“文件”一词表明,没有服务器的此报告可以是文件的集集,而不仅仅是单个文件。>
如果HTML文件A需要从HTML文件B加载内容,则您的跨浏览器选项为:
iframe
并更新src
以在文件之间移动。您在问题中说过,它们“不是为了页面的主要内容”,但这不是我的理解;而且它们很丑陋,但是可以通过CSS 完全进行样式设置。它们可以从字面上无缝地集成到主页中。src
以在文件之间移动。是的,frames
已在HTML5中删除。它们绝对不会从网络浏览器中删除,因为有太多遗留物。遗憾的是,从XMLHttpRequest
URL加载页面时,您无法可靠地使用file:
。有些浏览器允许,其他浏览器不允许。 (您不能在其中任何一个中使用fetch
,它特别不支持file:
方案。)
恐怕您的限制实际上会限制您的选择。
这是一个iframe
示例:
report.html
:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<title>Report</title>
<style>
#menu a {
padding: 4px;
}
#content {
border: none;
}
</style>
</head>
<body>
<div id="menu">
<a href="#file-1" data-file="file1.html">File 1</a>
<a href="#file-2" data-file="file2.html">File 2</a>
<a href="#file-3" data-file="file3.html">File 3</a>
</div>
<iframe id="content" src="file1.html"></iframe>
<script>
document.getElementById("menu").addEventListener("click", event => {
event.preventDefault();
const a = event.target.closest("a");
document.getElementById("content").src = a.getAttribute("data-file");
});
</script>
</body>
</html>
file1.html
(file2.html
和file3.html
是相同的,只是名称和数字不同):
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<title>File 1</title>
</head>
<body>
This is file 1.
</body>
</html>
答案 1 :(得分:1)
<template>
如果文件上有本地内容,请尝试使用<iframe>
或<template>
。我们将考虑后者。 <template>
是惰性的,浏览器会忽略它,因此无论您的多余内容有多大,这都不是问题。
<!DOCTYPE html>
<html>
<head>
<title>Page 1</title>
<style>
html {
font: 400 16px/1.5 'Consolas';
background: #000;
color: #fc0;
}
fieldset {
border-color: goldenrod;
border-radius: 8px;
}
input,
output {
display: block;
font: inherit;
}
[type=submit] {
float: right;
background: none;
color: gold;
border: 1px solid gold;
border-radius: 4px;
margin-top: 4px;
cursor: pointer;
}
</style>
</head>
<body>
<form id='import'>
<fieldset>
<legend>Import data.html by <b>XMLHttpRequest()</b></legend>
<output id='content'></output>
</fieldset>
<input type="submit">
</form>
<template id='data'>
<style>{margin: 30px auto}table{table-layout: fixed;border: 3px solid cyan;width: 99%;border-radius: 6px}caption{font-size:1.2rem;color:gold}th{width: 33%;background: rgba(0,11,187,0.3);border: 1px solid rgba(0,11,187,0.7);color:#fc3}td{min-height: 30px;border: 2px ridge cornflowerblue;;color: yellow;background: none}
</style><section><table><caption>DATA</caption><thead><tr><th>TH</th><th>TH</th><th>TH</th></tr></thead><tbody><tr><td>TD</td><td>TD</td><td>TD</td></tr><tr><td>TD</td><td>TD</td><td>TD</td></tr><tr><td>TD</td><td>TD</td><td>TD</td></tr></tbody></table></section>
</template>
<script>
document.forms.import.onsubmit = getContent;
function getContent(e) {
e.preventDefault();
const destination = document.querySelector('#content');
const template = document.querySelector('#data');
const clone = document.importNode(template.content, true);
destination.appendChild(clone);
}
</script>
</body>
</html>
假设与目标网页位于相同域中的单独网页是可行的,则可以使用XMLHttpRequest()从另一个网页(无论是来自服务器还是相同域)导入HTML。
在首页上,要导入HTML的元素需要这样做:
<div data-x="data.html"...
为任何类型的元素分配了data-x
属性,并带有导入的网页URL的值。
此堆栈摘录无法正常运行,因为它加载了外部页面,有关有效的演示,请查看此Plunker
<!DOCTYPE html>
<html>
<head>
<title>Page 1</title>
<style>
html {
font: 400 16px/1.5 'Consolas';
background: #000;
color: #fc0;
}
fieldset {
border-color: goldenrod;
border-radius: 8px;
}
input,
output {
display: block;
font: inherit;
}
[type=submit] {
float: right;
background: none;
color: gold;
border: 1px solid gold;
border-radius: 4px;
margin-top: 4px;
cursor: pointer;
}
</style>
</head>
<body>
<form id='import'>
<fieldset>
<legend>Import data.html by <b>XMLHttpRequest()</b></legend>
<output data-x="data.html"></output>
</fieldset>
<input type="submit">
</form>
<script>
function xhr(e) {
e.preventDefault();
const tags = document.querySelectorAll("*");
let clone, file, xh;
for (let i = 0; i < tags.length; i++) {
if (tags[i].dataset.x) {
clone = tags[i].cloneNode(false);
file = tags[i].dataset.x;
xh = new XMLHttpRequest();
xh.onreadystatechange = function() {
if (xh.readyState == 4 && xh.status == 200) {
clone.innerHTML = xh.responseText;
tags[i].parentNode.replaceChild(clone, tags[i]);
xhr();
}
};
xh.open("GET", file, true);
xh.send();
return;
}
}
}
document.forms.import.addEventListener('submit', xhr);
</script>
</body>
</html>
这只是导入到index.html的纯网页,有关有效的演示,请查看此Plunker
<style>
section {
margin: 30px auto;
}
table {
table-layout: fixed;
border: 3px solid cyan;
width: 99%;
border-radius: 6px;
}
caption {
font-size:1.2rem;
color:gold;
}
th {
width: 33%;
background: rgba(0,11,187,0.3);
border: 1px solid rgba(0,11,187,0.7);
color:#fc3;
}
td {
min-height: 30px;
border: 2px ridge cornflowerblue;;
color: yellow;
background: none;
}
</style>
<section>
<table>
<caption>DATA</caption>
<thead>
<tr>
<th>TH</th>
<th>TH</th>
<th>TH</th>
</tr>
</thead>
<tbody>
<tr>
<td>TD</td>
<td>TD</td>
<td>TD</td>
</tr>
<tr>
<td>TD</td>
<td>TD</td>
<td>TD</td>
</tr>
<tr>
<td>TD</td>
<td>TD</td>
<td>TD</td>
</tr>
</tbody>
</table>
</section>