对于网站来说很多页面之间都有着大量的共享模块, 如页头, 页脚和用户栏等. 对于具备后端视图引擎的框架来说这些共享都比较容易抽取, 如 ASP.NET mvc 来说就有统一布局的 MasterPage,@Section 等功能可以共享视图模板功能. 但对于 html 就没这么幸运了, 在 HTML 文件里并不具备这些功能, 所以当你用纯 HTML 页面来写应用网站的时候估计不得不面对这些重复的工作, 虽然可以通过嵌套 IFrame 的方式来实现, 不过这种实现方式并不理想和友好.
实际场分析
最近基于自有框架实现一个网站, 由于框架并不具备后端视图引擎, 这种麻烦事就碰到了... 我们先来看一下实际情况.
以上两个 HTML 页面除了核心部分是独有的, 其他数据块都是相同. 如果没有后端视图引擎你想到怎样做呢.... 刚开始每个地方修改都要同步到其他页面. 后来发现这样的做法一定会把自己迫死的. 经过一段时间的思考想到了一个解决的办法.
公共模板定义
思考后发现可以把公共模板抽取到一个 HTML 文件中 (文件名就暂定 PublicModule.HTML), 如下:
- id="header">
- class="navbar-header">
- class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".navbar-collapse">
- class="sr-only">Toggle navigation
- class="icon-bar">
- class="icon-bar">
- class="icon-bar">
- class="navbar-brand" href="/">.Net Library
- class="navbar-collapse collapse" role="navigation">
- style="margin-top:15px;margin-left:120px; position:absolute;"> style="color:white;padding-top:20px;">XXXXX
- class="nav navbar-nav">
- class="nav navbar-nav navbar-right">
href="/Blog.html"> 博客
href="https://github.com/IKende/FastHttpApi" target="_blank">GitHub.com
href="/admin/index.html"> 网站管理
- id="doc_tags_navbar">
- class="container-fluid" style="padding:0px;">
- class="nav navbar-nav btn-group-sm" id="tagbar">
style="font-weight:bold; padding-bottom:6px;padding-top:6px;" href="/index.html"> 首页
- v-for="item in Data"> v-bind:title="item.Remark" style="font-weight:bold; padding-bottom:6px;padding-top:6px;" v-bind:href="['/index.html?tag='+item.ID]">{{item.Title}}
- var tagbarControl;
- tagbarControl = new vue({ el: '#tagbar', data: { Data: [] } });
- async function ListDocTags() {
- var result = await $ListDocTags();
- tagbarControl.Data = result.Data;
- }
- ListDocTags();
通过 template 标签来定义一个模板块, 然后针对每个块定义一个唯一 ID. 可能有些同学会问 template 并不是有效的 HTML 标签, 那怎处理里呢? 对的 template 浏览器是不会处理, 但 jQuery 是可以, 说到这里相信有此同学理解原理了.
在 HTML 中应用模板
当模块定义后, 那在 HTML 中怎么引用呢? 其实 HTML 并不支持这样的功能, 不过我们可以给 HTML 定义一些自定义属性给 jQuery 解释, 在这里定义了一个 slot 属性用于指定模板 ID
- class="navbar navbar-inverse navbar-fixed-top">
- class="container" slot="header">
- class="navbar navbar-default" style="padding:0px;margin:0px;min-height:0px;" slot="doc_tags_navbar">
模板定义了, 页面的 HTML 也引用了, 接下来就要整合他们. 到了这里相信熟悉 jQuery 的朋友一定想到要怎么做了:)
使用 jQuery 整合加载
对于 jQuery 来说可以把公共模块页加载后转成 DOM, 然后替换页面上定义了 slot 的元素
- function moduleLoad(url) {
- $.get(url, function (result) {
- var HTML = $(result);
- var __templates = HTML;
- $("[slot]").each(function () {
- var id = $(this).attr('slot');
- var body = $(__templates).find('#' + id).HTML();
- $(this).HTML(body);
- });
- });
- }
- $(document).ready(function () {
- moduleLoad("/PublicModule.html");
- });
代码简单有效, 把整会脚本存到一个文件中, 然后添加到页中就自动加载了.
加载速度问题
原本一次就能加载的 HTML 页面, 现在还需要 Ajax 加载不会导致加载慢了吗? 其实可以把公共模块的 HTML 页做一个本地缓存策略, 这样所有页面加载模块的时候都能直接从本地拿; 由于公共部分抽取出来, 从而让相关页面的休积变得更小, 加载速度更快.
基于纯 HTML/JS 前端开发优势
对于习惯使用服务端视图引擎的朋友来说, 完全使用 HTML/JS 的前端开发模式可以有点困难. 但完全基于 HTML/JS 的前端开发有着明显的优势, 视图处理不需要服务解释大大降低了服务器的损耗, HTML 可以更好地做本地化缓存, 还有现在大量的 HTML/JS 框架让你在编写的时候更轻松简单.
来源: https://www.cnblogs.com/codelove/p/9778890.html