官方网站:
Web Component - Web API 接口参考 | MDN
1) 传入path
2) 使用fetch将path字符串所在的文件找到并返回内容
const res = await fetch(path).then(res => res.text());
3) 使用DOMParser实例的parseFromString方法将至转换为shadowRoot
const parser = new DOMParser();
const doc = parser.parseFromString(res, "text/html"); // shadowRoot
4) shadowRoot支持dom查找元素的方法, 可以找到template, script, style标签元素
5) 根据不同的path, 存放相应的template, script, style
// 动态加载组件并解析
async function loadComponent(path, name) {
this.caches = this.caches || {};
// 当缓存存在
if (!!this.caches[path]) {
return this.caches[path]
}
const res = await fetch(path).then(res => res.text());
// 利用DOMParser,生成shaow-root
const parser = new DOMParser();
const doc = parser.parseFromString(res, "text/html");
// 解析模板,脚本,样式
const template = doc.querySelector("template");
const script = doc.querySelector("script");
const style = doc.querySelector("style");
// 缓存内容
this.caches[path] = {
template,
script,
style
}
return this.caches[path]
}
// 容器组件
class CustomComponent extends HTMLElement {
async connectedCallback() {
console.log("custom-component connected");
// 获取组件的path,即html的路径
const strPath = this.getAttribute("path");
// 加载html
const cInfos = await loadComponent(strPath);
// Element.attachShadow() 方法给指定的元素挂载一个 Shadow DOM,并且返回对 ShadowRoot 的引用。
const shadow = this.attachShadow({ mode: "closed" });
// 添加html对应的标签和内容
this._addElements(shadow, cInfos);
}
_addElements(shadow, info) {
if (info.template) {
shadow.appendChild(info.template.content.cloneNode(true));
}
if (info.script) {
var fn = new Function(`${info.script.textContent}`);
// 绑定脚本的this为当前的影子根节点, 防止全局污染
fn.call(shadow);
}
if (info.style) {
shadow.appendChild(info.style);
}
}
}
window.customElements.define("custom-component", CustomComponent);
// 使用示例: renderComponent.call(thisArg, route)
function renderComponent(route) {
var el = document.createElement("custom-component");
el.setAttribute("path", `/${route.component}.html`);
// append可以追加节点和字符串,appendChild只能追加节点;
el.id = "_route_";
this.append(el);
}
1) 先新建goods.html
商品详情-goos
下面商品是????
2) 在index.html使用
先引入custom-component.js
然后在index.html的script标签写:
renderComponent.call(document.getElementById('box'), {
component: './goods'
})
index.html文件代码
index