Skip to content

页面包含

元信息

  • 目标:解决页面间大量重复(站点头尾/侧边栏)的共享问题——像定义并调用函数一样"包含"公共区块;对比 script 注入与 ajax 注入两代方案的思路与缺陷
  • 关键概念:页面包含、公共区块、script 注入、document.write、ajax 注入、DOM 写入、全局变量污染
  • 关联阶段:cp3
  • 常见误区:以为包含是浏览器/HTML 的原生能力(要靠 script 或 ajax 手工模拟);把页面内容塞进 js 字符串还忘了转义引号;多个被包含文件用同名全局变量相互覆盖;没意识到这正是后来组件化要解决的历史问题

需求

各大Web站点的各个页面之间通常存在大量的重复,手工编写页面工作量巨大,如何能够消除这些重复或共享?

  • 全站:相同的站点头、站点底部
  • 同内容类型或栏目:侧边栏、区块

设计思路

  • 将站点头和站点底独立为两个页面文件,类似于定义一个函数
  • 在各静态页面中,将这个文件包含进来,类似于调用一个函数

如何实现包含这个功能,类似服务端脚本语言中的include ?

基于 script 标记的实现方案

  • 将被包含的页面文件转换成一个js代码文件
  • 将被包含的页面文件的内容转化一个字符串类型的全局变量
  • 在目标页面中引入这个js文件,将字符串变量写入相应的位置

示例

import "./styles.css";

document.getElementById("app").innerHTML = `
<h1>Hello world</h1>
`;

<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>

缺陷

  • 复杂的共享页面的书写较麻烦,比如双引号的转义
  • 使用了全局变量。当包含多个文件时,潜在有变量命名冲突的可能

基于 ajax 的注入实现方案

  • 无需将页面文件转换为js代码文件
  • 使用ajax技术远程读取该页面文件的内容
  • 使用dom技术将获得的内容写入相应的位置

基本思路:回忆上一章中我们使用ajax时,将js代码转换为json数据,理解程序的层次感

示例

<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>