动态加载 HTML 内容到网页的三种方式






4.94/5 (10投票s)
演示了三种动态添加或替换网页 HTML 内容的方法。
引言
本文提出的三种动态替换 HTML 内容(响应用户操作)的方法都能正常工作;我将演示这三种方法,您可以选择最适合您情况的一种。
背景
在我构建和设计我的 HTML5 应用/网站的过程中,我一直在思考如何才能最佳地响应用户的选择来替换 HTML 内容。我最初考虑预先生成 HTML 并将其存储在单独的文件中以备需要时访问,但我觉得这似乎是一种过于“粗暴”(业余)的方法——动态生成 HTML 会更“优雅”。于是,我的第一个实现是使用 jQuery 的 getJSON()
,访问并解析原始的 *.json 文件。 但是 jQuery 的 HTML 构建代码有点难读而且“丑陋”,所以我决定更“前沿”一些,采用了 Razor 路线(这是个双关语,但我不想承认),将 C#/Razor 类转换为 *.json 文件(仍然使用 jQuery 的 getJSON()
,但访问的是 Razor/*.cshtml 文件而不是原始的 *.json 文件)。
最后,我回到了最初的想法,使用了 jQuery 的 Load()
方法来获取 HTML 文件。后者不得不承认,是最不花哨或“优雅”的,但却是最直接的,不需要像 Razor 这样的“中间人”来将 C# 类转换为 json,也不需要创建原始的 JSON 文件然后进行解析和转换成 HTML。理论上,“去除中间人”不仅更容易维护,而且应该运行更快(实际上,从速度上看,这几种方法似乎差别不大,我也没对其进行性能分析以确定哪种操作类型最快)。
使用代码
我使用的第一种方法是使用 jQuery 的 getJSON()
方法加载 *.json 文件(创建 *.json 文件留给读者作为练习——就我而言,我创建了一个 C# 工具,将所需数据保存到 CSV 文件,然后使用 CSV to JSON 转换器,最后使用 JSON Lint 网站 来清理由于我的工具中的 bug 和数据中的“边缘情况”而渗入的任何错误数据)。
这是来自“sundance.json”的一些示例文本 JSON。
{
"category":"2012",
"film":"blankfilm",
"instavid":"blankbluray",
"bluray":"blankdvd",
"dvd":"blankinstavid",
"imghtml":"blankimghtml"
},
{
"category":"U.S. Grand Jury Prize Dramatic",
"film":"Beasts of the Southern Wild",
"instavid":"B00A7JKMA2",
"bluray":"B008220ALC",
"dvd":"B008220AGC",
"imghtml":"http://www.amazon.com/exec/obidos/ASIN/B008220ALC/garrphotgall-20\"
target=\"_blank\"><img height=\"160\" width=\"107\"
src=\"http://images.amazon.com/images/P/B008220ALC.01.MZZZZZZZ.jpg\"
alt=\"Beasts of the Southern Wild Movie Cover\" /></a>"
},
{
"category":"U.S. Grand Jury Prize Documentary",
"film":"The House I Live In",
"instavid":"B00B19HFMK",
"bluray":"--",
"dvd":"B00CEJVNEM",
"imghtml":"http://www.amazon.com/exec/obidos/ASIN/B00CEJVNEM/garrphotgall-20\"
target=\"_blank\"><img height=\"160\" width=\"107\"
src=\"http://images.amazon.com/images/P/B00CEJVNEM.01.MZZZZZZZ.jpg\"
alt=\"The House I Live In Movie Cover\" /></a>"
},
{
"category":"World Cinema Grand Jury Prize Dramatic",
"film":"Violeta Went to Heaven (Violeta se Fue a Los Cielos)",
"instavid":"--",
"bluray":"--",
"dvd":"B00CKDO9I4",
"imghtml":"http://www.amazon.com/exec/obidos/ASIN/B00CKDO9I4/garrphotgall-20\"
target=\"_blank\"><img height=\"160\" width=\"107\"
src=\"http://ecx.images-amazon.com/images/I/513Puff-bQL._SL160_.jpg\"
alt=\"Violeta Went to Heaven (Violeta se Fue a Los Cielos) Movie Cover\" /></a>"
},
{
"category":"World Cinema Grand Jury Prize Documentary",
"film":"The Law in These Parts",
"instavid":"--",
"bluray":"--",
"dvd":"B00C4WL3ZI",
"imghtml":"http://www.amazon.com/exec/obidos/ASIN/B00C4WL3ZI/garrphotgall-20\"
target=\"_blank\"><img height=\"160\" width=\"107\"
src=\"http://images.amazon.com/images/P/B00C4WL3ZI.01.MZZZZZZZ.jpg\"
alt=\"The Law in These Parts Movie Cover\" /></a>"
},
{
"category":"Audience Award U.S. Dramatic",
"film":"The Surrogate (retitled The Sessions)",
"instavid":"B00B7G3NFU",
"bluray":"B00ANGICRE",
"dvd":"B00AEK9BKQ",
"imghtml":"http://www.amazon.com/exec/obidos/ASIN/B00ANGICRE/garrphotgall-20\"
target=\"_blank\"><img height=\"160\" width=\"107\"
src=\"http://images.amazon.com/images/P/B00ANGICRE.01.MZZZZZZZ.jpg\"
alt=\"The Surrogate (retitled The Sessions) Movie Cover\" /></a>"
},
{
"category":"Audience Award U.S. Documentary",
"film":"The Invisible War",
"instavid":"B009G9YCB4",
"bluray":"--",
"dvd":"B008MIYKLW",
"imghtml":"http://www.amazon.com/exec/obidos/ASIN/B008MIYKLW/garrphotgall-20\"
target=\"_blank\"><img height=\"160\" width=\"107\"
src=\"http://images.amazon.com/images/P/B008MIYKLW.01.MZZZZZZZ.jpg\"
alt=\"The Invisible War Movie Cover\" /></a>"
},
{
"category":"Audience Award World Cinema Documentary",
"film":"Searching for Sugar Man",
"instavid":"B00AY7Q01C",
"bluray":"B008JFUTUY",
"dvd":"B008JFUTT0",
"imghtml":"http://www.amazon.com/exec/obidos/ASIN/B008JFUTUY/garrphotgall-20\"
target=\"_blank\"><img height=\"160\" width=\"107\"
src=\"http://images.amazon.com/images/P/B008JFUTUY.01.MZZZZZZZ.jpg\"
alt=\"Searching for Sugar Man Movie Cover\" /></a>"
},
…这是用于获取并解析它,将其转换为 HTML 的 jQuery 代码
function Urlify(ASINVal) {
return "http://www.amazon.com/exec/obidos/ASIN/" + ASINVal + "/garrphotgall-20";
}
$.getJSON('Content/sundance.json', function (data) {
$.each(data, function (i, dataPoint) {
if (IsYearOrTwoYearSpan(dataPoint.category)) {
htmlBuilder += '<div class=\"yearBanner\">' + dataPoint.category + '</div>';
} else {
htmlBuilder += '<section class=\"wrapper\" >
<a id=\"mainImage\" class=\"floatLeft\" href=\"' +
dataPoint.imghtml +
'<div id=\"prizeCategory\" class=\"categorySmallerFont\">' +
dataPoint.category +
'</div><br/><cite id=\"prizeTitle\" >' +
dataPoint.film +
'</cite><br/>';
if (dataPoint.bluray.length > 2) {
htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.bluray) + '\"' +
' target=\"_blank\" >Blu-Ray</a></button>';
}
if (dataPoint.dvd.length > 2) {
htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.dvd) + '\"' +
' target=\"_blank\" >DVD</a></button>';
}
if (dataPoint.instavid.length > 2) {
htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.bluray) + '\"' +
' target=\"_blank\" >InstaVid</a></button>';
}
htmlBuilder += '</section>';
} //else
}); //each
$('#MoviesContent').html(htmlBuilder).
find('img, button').click(function () {
$(this).css('border', '1px solid silver');
});
$('#MoviesContent').css('background-color', 'black');
$('button').button();
}) //getJSON
这效果很好(正如您通过从我的网站选择 Movies > Sundance 所见),但编写代码很难,因为需要确保所有引号都被正确转义等等,而且很难看,“比一袋屁股还丑 9 倍”,这是我一位老朋友 Eddie J. Nelson 的说法。
然后,主要是因为创建原始 *.json 文件是一个耗时但必要的初步步骤,我决定使用 Razor 将 C# 类转换为 json(让一个工具写出 C# 类实例比通过 CSV 到 JSON 的过程更容易——也更容易阅读它们)。这是一个 Razor 代码的示例。
@{
var books = new List<BookClass>
{
new BookClass{Year=2013, YearDisplay="blankYearDisplay", Category="2013",
Title="blankTitle", Author="blankAuthor",
KindleASIN="blankKindleASIN", HardboundASIN="blankHardboundASIN",
PaperbackASIN="blankPaperbackASIN", ImgSrc="blankImgSrc"},
new BookClass{Year=2013, YearDisplay="2013", Category="Best Novel",
Title="Redshirts", Author="John Scalzi", KindleASIN="B0079XPUOW",
HardboundASIN="0765316994", PaperbackASIN="0765334798",
ImgSrc="http://images.amazon.com/images/P/B0079XPUOW.01.MZZZZZZZ"},
new BookClass{Year=2013, YearDisplay="2013", Category="Best Novella",
Title="The Emperor's Soul", Author="Brandon Sanderson",
KindleASIN="B00A1XOPE8", HardboundASIN="--",
PaperbackASIN="1616960922",
ImgSrc="http://images.amazon.com/images/P/B00A1XOPE8.01.MZZZZZZZ"},
. . .
new BookClass{Year=1946, YearDisplay="blankYearDisplay", Category="1946",
Title="blankTitle", Author="blankAuthor",
KindleASIN="blankKindleASIN", HardboundASIN="blankHardboundASIN",
PaperbackASIN="blankPaperbackASIN", ImgSrc="blankImgSrc"},
new BookClass{Year=1946, YearDisplay="1946", Category="Best Novella",
Title="Animal Farm", Author="George Orwell",
KindleASIN="B003ZX868W", HardboundASIN="0151010269",
PaperbackASIN="184046254X",
ImgSrc="http://images.amazon.com/images/P/B003ZX868W.01.MZZZZZZZ"}
};
Response.ContentType = "application/json";
Json.Write(books, Response.Output);
}
如您所见,上面的代码在调用 Json.Write
时将 C# 类转换为 JSON 文件。处理这些 JSON 化数据的 jQuery 与处理原始 *.json 文件相同,除了它引用上面的 GetHugos.cshtml 文件,而不是 *.json 文件:
$.getJSON('GetHugos', function (data) {
. . .
最后,我尝试了最直接的方法,即生成 HTML 内容,下面是一个示例:
<div class="yearBanner">2013</div>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/B0085DOE2O/garrphotgall-20"
target="_blank"><img height="160" width="107"
src="http://images.amazon.com/images/P/B0085DOE2O.01.MZZZZZZZ.jpg"
alt="Tucker's Reckoning by Ralph Compton and Matthew Mayo book cover"></img></a>
<div class="category">Best Short Novel</div><br/><cite
>Tucker's Reckoning</cite><br/><div class="author">Ralph
Compton and Matthew Mayo</div><br/><button><a
href="http://www.amazon.com/exec/obidos/ASIN/B0085DOE2O/garrphotgall-20"
target="_blank" rel="nofollow" >Kindle</a></button><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/0451415612/garrphotgall-20"
target="_blank" rel="nofollow" >Hardcover</a></button>
<button><a href="http://www.amazon.com/exec/obidos/ASIN/0451465482/garrphotgall-20"
target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/B00ERRJ9VS/garrphotgall-20"
target="_blank"><img height="160" width="107"
src="http://ecx.images-amazon.com/images/I/51FamWEIkzL._SL160_.jpg"
alt="With Blood in Their Eyes by Thomas Cobb book cover"></img></a>
<div class="category">Best Long Novel</div><br/><cite
>With Blood in Their Eyes</cite><br/><div class="author"
>Thomas Cobb</div><br/><button><a
href="http://www.amazon.com/exec/obidos/ASIN/0816521107/garrphotgall-20"
target="_blank" rel="nofollow" >Kindle</a></button>
<button><a href="http://www.amazon.com/exec/obidos/ASIN/0816521107/garrphotgall-20"
target="_blank" rel="nofollow" >Hardcover</a></button><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/B00ERRJ9VS/garrphotgall-20"
target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/B008EXK2LC/garrphotgall-20"
target="_blank"><img height="160" width="107"
src="http://images.amazon.com/images/P/B008EXK2LC.01.MZZZZZZZ.jpg"
alt="The Coyote Tracker by Larry Sweazy book cover"></img></a>
<div class="category">Best Paperback</div><br/><cite
>The Coyote Tracker</cite><br/><div class="author">Larry Sweazy</div>
<br/><button><a href="http://www.amazon.com/exec/obidos/ASIN/B008EXK2LC/garrphotgall-20"
target="_blank" rel="nofollow" >Kindle</a></button><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/1410454002/garrphotgall-20" target="_blank"
rel="nofollow" >Hardcover</a></button><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/0425250415/garrphotgall-20"
target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/B0083JCERC/garrphotgall-20"
target="_blank"><img height="160" width="107"
src="http://images.amazon.com/images/P/B0083JCERC.01.MZZZZZZZ.jpg"
alt="Panhandle by Brett Cogburn book cover"></img></a><div
class="category">Best First Novel</div><br/><cite
>Panhandle</cite><br/><div class="author">Brett Cogburn</div><br/>
<button><a href="http://www.amazon.com/exec/obidos/ASIN/B0083JCERC/garrphotgall-20"
target="_blank" rel="nofollow" >Kindle</a></button><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/1410460975/garrphotgall-20"
target="_blank" rel="nofollow" >Hardcover</a></button>
<button><a href="http://www.amazon.com/exec/obidos/ASIN/B00ERJREPO/garrphotgall-20"
target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/B009T3C88Q/garrphotgall-20"
target="_blank"><img height="160" width="107"
src="http://images.amazon.com/images/P/B009T3C88Q.01.MZZZZZZZ.jpg"
alt="Geronimo by Robert M. Utley book cover"></img></a><div
class="category">Best Biography</div><br/><cite
>Geronimo</cite><br/><div class="author">Robert M. Utley</div>
<br/><button><a href="http://www.amazon.com/exec/obidos/ASIN/B009T3C88Q/garrphotgall-20"
target="_blank" rel="nofollow" >Kindle</a></button><button><a
href="http://www.amazon.com/exec/obidos/ASIN/0300126387/garrphotgall-20" target="_blank"
rel="nofollow" >Hardcover</a></button><button><a
href="http://www.amazon.com/exec/obidos/ASIN/0300198361/garrphotgall-20" target="_blank"
rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/B009KM8OGQ/garrphotgall-20" target="_blank">
<img height="160" width="107" src="http://images.amazon.com/images/P/
B009KM8OGQ.01.MZZZZZZZ.jpg" alt="With Golden Visions Bright Before Them: Trails to the Mining West,
1849-1852 by Will Bagley book cover"></img></a><div class="category">Best
Historical</div><br/><cite >With Golden Visions Bright Before Them: Trails to the Mining West,
1849-1852</cite><br/><div class="author">Will Bagley</div><br/><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/B009KM8OGQ/garrphotgall-20" target="_blank"
rel="nofollow" >Kindle</a></button><button><a
href="http://www.amazon.com/exec/obidos/ASIN/0806142847/garrphotgall-20"
target="_blank" rel="nofollow" >Hardcover</a></button><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/B00CLHRS4Q/garrphotgall-20" target="_blank"
rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/B0080K3P40/garrphotgall-20"
target="_blank"><img height="160" width="107"
src="http://images.amazon.com/images/P/B0080K3P40.01.MZZZZZZZ.jpg"
alt="Desert Reckoning: A Town Sheriff, A Mojave Hermit and the Biggest Manhunt in Modern California History
by Deanne Stillman book cover"></img></a><div class="category">Best Nonfiction
Contemporary</div><br/><cite >Desert Reckoning: A Town Sheriff, A Mojave Hermit and
the Biggest Manhunt in Modern California History</cite><br/><div class="author">
Deanne Stillman</div><br/><button><a
href="http://www.amazon.com/exec/obidos/ASIN/B0080K3P40/garrphotgall-20" target="_blank"
rel="nofollow" >Kindle</a></button><button><a
href="http://www.amazon.com/exec/obidos/ASIN/B00B1L0ZW0/garrphotgall-20"
target="_blank" rel="nofollow" >Hardcover</a></button><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/B00CWL160S/garrphotgall-20" target="_blank"
rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/B0074VTH6G/garrphotgall-20"
target="_blank"><img height="160" width="107"
src="http://images.amazon.com/images/P/B0074VTH6G.01.MZZZZZZZ.jpg"
alt="Wide Open by Larry Bjornson book cover"></img></a><div
class="category">Best Juvenile Fiction</div><br/><cite
>Wide Open</cite><br/><div class="author">Larry Bjornson</div>
<br/><button><a href="http://www.amazon.com/exec/obidos/ASIN/B0074VTH6G/garrphotgall-20"
target="_blank" rel="nofollow" >Kindle</a></button><button>
<a href="http://www.amazon.com/exec/obidos/ASIN/1410460584/garrphotgall-20"
target="_blank" rel="nofollow" >Hardcover</a></button>
<button><a href="http://www.amazon.com/exec/obidos/ASIN/0425247481/garrphotgall-20"
target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft"
href="http://www.amazon.com/exec/obidos/ASIN/0803235208/garrphotgall-20"
target="_blank"><img height="160" width="107"
src="http://images.amazon.com/images/P/0803235208.01.MZZZZZZZ.jpg"
alt="Light on the Prairie: Solomon D. Butcher, Photographer of Nebraska’s Pioneer Days
by Nancy Plain book cover"></img></a><div class="category">
Best Juvenile Nonfiction</div><br/><cite >Light on the Prairie: Solomon D. Butcher,
Photographer of Nebraska’s Pioneer Days</cite><br/><div class="author">Nancy
Plain</div><br/><button><a href="http://www.amazon.com/exec/obidos/ASIN/0803235208/garrphotgall-20"
target="_blank" rel="nofollow"
>Hardcover</a></button></section>
使用它的代码如下。
$('#BooksContent').load('Content/spur.html', function () {
$('button').button();
});
从编码的角度来看,直接的 HTML 方法是最简单的。显然,jQuery 代码非常简洁,事实上,“$('button').button()
”这一行是装饰(jQuery UI 的功能),并非必需。
您可以通过选择我的 HTML5 应用/网站上使用它们的奖项来比较各种方法的性能:对于原始 HTML 方法,选择 Books > Spurs (Western);对于 Razor/cshtml getJSON() 方法,选择 Books > Hugos (Science Fiction)。
到目前为止,所有其他都使用原始 *.json 文件 / getJSON()
方法。除非我确信有其他更好的方法,否则尚未添加的奖项(Nobel Prize for Literature, Nebulas, James Beard, and Edgars)将使用原始 HTML 替代方案。
兴趣点
如前所述,这三种方法都有效。后两种方法最容易“预处理”——也就是说,创建 Razor 代码的工具和生成原始 HTML 的工具比先创建 CSV 文件、将其转换为 JSON,然后调整该 JSON 文件直到其能正确解析要快得多。除非我找到一个充分的理由改变主意,否则我可能会坚持使用“乏味”、不够优雅且“略显粗暴”的方法,即使用原始 HTML 文件和 jQuery Load() 方法替换内容,而不是调用 getJSON()
。
历史
- 首次发布于 2013 年 10 月 1 日。