[TOC] ## 概述 1. 自定义元素的名称必须包含连词线 如`<user-card>`不能写成`<usercard>` ### Shadow DOM Shadow DOM 其实是在文档的主 DOM 中生成了一块子 DOM,这个子 DOM 的 CSS 环境是和主文档隔离的。可以说,使用 Shadow DOM,我们就拥有了一个组件封装的原始模型。 ### 导入组件 `<link rel="import" href="user-card.html">` ## 用 template 解决 ``` <user-card image="https://semantic-ui.com/images/avatar2/large/kristy.png" name="User Name" email="yourmail@some-email.com" ></user-card> <template id="userCardTemplate"> <style> :host { display: flex; align-items: center; width: 450px; height: 180px; background-color: #d4d4d4; border: 1px solid #d5d5d5; box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); border-radius: 3px; overflow: hidden; padding: 10px; box-sizing: border-box; font-family: 'Poppins', sans-serif; } .image { flex: 0 0 auto; width: 160px; height: 160px; vertical-align: middle; border-radius: 5px; } .container { box-sizing: border-box; padding: 20px; height: 160px; } .container > .name { font-size: 20px; font-weight: 600; line-height: 1; margin: 0; margin-bottom: 5px; } .container > .email { font-size: 12px; opacity: 0.75; line-height: 1; margin: 0; margin-bottom: 15px; } .container > .button { padding: 10px 25px; font-size: 12px; border-radius: 5px; text-transform: uppercase; } </style> <img class="image"> <div class="container"> <p class="name"></p> <p class="email"></p> <button class="button">Follow</button> </div> </template> <script> class UserCard extends HTMLElement { constructor() { super(); let shadow = this.attachShadow( { mode: 'closed' } ); let templateElem = document.getElementById('userCardTemplate'); let content = templateElem.content.cloneNode(true); //获取参数 content.querySelector('img').setAttribute('src', this.getAttribute('image')); content.querySelector('.container>.name').innerText = this.getAttribute('name'); content.querySelector('.container>.email').innerText = this.getAttribute('email'); /*封装监听事件*/ shadow.$button = content.querySelector("button"); shadow.$button.addEventListener("click",this.listener); shadow.appendChild(content); } listener(){ alert("asdsd"); } } window.customElements.define('user-card', UserCard); </script> ``` ## 用 js 生成标签 ``` <user-card></user-card> <script> class UserCard extends HTMLElement{ constructor(){ super(); let image = document.createElement('img'); image.src = 'https://semantic-ui.com/images/avatar2/large/kristy.png'; image.classList.add('image'); let container = document.createElement('div'); container.classList.add('container'); let name = document.createElement('p'); name.classList.add('name'); name.innerText = 'User Name'; let email = document.createElement('p'); email.classList.add('email'); email.innerText = 'yourmail@some-email.com'; let button = document.createElement('button'); button.classList.add('button'); button.innerText = 'Follow'; container.append(name, email, button); this.append(image, container); } } window.customElements.define("user-card",UserCard); </script> ```