传统的组件开发:
代码由四部分构成:
- 引入CSS组件样式部分
<link rel="stylesheet" href="***.css">
- JS组件封装逻辑部分
<script src="***.js"></script>
- HTML组件模板代码
<div></div>
- JS组件创建脚本代码
<script></script>
新一代开发:
vue、react等框架都是在webCpmponent上引申出来的。
代码由两部分组成:
- 引入html组件源文件
<link rel="import" href="component.html">
- 使用标签webCpmponent的组件
<component></component>
实现一个自定义组件:
在一个标准的html文件中引入并使用webCpmponent组件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webComponent</title>
<!-- 导入组件(一般是异步加载,但import就变成同步加载了) -->
<link rel="import" href="./component.html">
</head>
<body>
<!-- 使用标签 -->
<component></component>
</body>
</html>
webCpmponent组件:
<!-- HTML结构部分 -->
<template>
<!-- CSS结构部分 -->
<style>
.color{
color: red;
}
</style>
<p>我最喜欢的颜色是:
<strong class="color">Red</strong>
</p>
</template>
<!-- JS完成组件的逻辑部分 -->
<script>
// 创建闭包
(function(){
// 基于HTML元素的原型创建对象
// HTMLElement.prototype是所有节点的原型
var element = Object.create(HTMLElement.prototype);
// template是:#document-fragment,内容是<template>内的所有代码,object类型。
// DocumentFragment叫做 文档碎片,dom对象的缓存区(缓存在V8引擎),广泛用于框架中对dom元素的批量操作。
// document.currentScript.ownerDocument:是被引入组件的文档
// document:是要引入的html文档
var template = document.currentScript.ownerDocument.querySelector('template').content;
console.log(template);
element.createdCallback = function(){
// 创建shadow root节点:具备作用域的dom节点,不影响其他组件,隔离作用
var shadowRoot = this.createShadowRoot();
var clone = document.importNode(template,true);
// 添加模板克隆对象到shadow root中
shadowRoot.appendChild(clone);
}
// 注册新组件
document.registerElement('netease-color',{
prototype:element
});
}())
</script>
在webCpmponent.html组件中,代码同样两部分,<template></template>
和<script></script>
。
其中,<template></template>
内书写CSS样式和html模板。
而<script></script>
内是一段标准的Cpmponent代码。
在浏览器打开文件后,会提示文件加载跨域的错误,解决办法:打开命令行,切换到浏览器的安装目录,运行命令:
cd C:\Program Files (x86)\Google\Chrome\Application
chrome.exe --disable-web-security --user-data-dir
实现组件流程:
- template组件html模板:
- 创建闭包:
- 基于HTML Element原型创建对象:
- 设置生命周期对调函数:
- 创建影子根对象
- 注册webcomponent标准组件。
X-Tag:
可以手动封装一个X-Tag库。
扩展:
假如有一个需求,需要创建10万个div:
for(var i = 0;i<100000;i++){
var d = document.createElement("div");
document.body.appendChild(d);
}
// 可以改下面这样:性能是N倍(避免重绘操作)
// 先创建一个临时缓存区:
var f = document.createDocumentFragment();
for(var i = 0;i<100000;i++){
var d = document.createElement("div");
// 将创建的dom节点加到缓存区
f.appendChild(d);
}
//最终循环完毕,在一次放入document.body中
document.body.appendChild(f);