1. <popup-info img="img/alt.png" data-text="Your card validation code (CVC) is an extra security feature — it is the last 3 or 4 numbers on the back of your card."></popup-info>

    组件定义和使用,js部分

    1. class PopUpInfo extends HTMLElement {
    2. constructor() {
    3. // Always call super first in constructor
    4. super();
    5. // Create a shadow root
    6. const shadow = this.attachShadow({mode: 'open'});
    7. // Create spans
    8. const wrapper = document.createElement('span');
    9. wrapper.setAttribute('class', 'wrapper');
    10. const icon = document.createElement('span');
    11. icon.setAttribute('class', 'icon');
    12. icon.setAttribute('tabindex', 0);
    13. const info = document.createElement('span');
    14. info.setAttribute('class', 'info');
    15. // Take attribute content and put it inside the info span
    16. const text = this.getAttribute('data-text');
    17. info.textContent = text;
    18. // Insert icon
    19. let imgUrl;
    20. if(this.hasAttribute('img')) {
    21. imgUrl = this.getAttribute('img');
    22. } else {
    23. imgUrl = 'img/default.png';
    24. }
    25. const img = document.createElement('img');
    26. img.src = imgUrl;
    27. icon.appendChild(img);
    28. // Create some CSS to apply to the shadow dom
    29. const style = document.createElement('style');
    30. console.log(style.isConnected);
    31. style.textContent = `
    32. .wrapper {
    33. position: relative;
    34. }
    35. .info {
    36. font-size: 0.8rem;
    37. width: 200px;
    38. display: inline-block;
    39. border: 1px solid black;
    40. padding: 10px;
    41. background: white;
    42. border-radius: 10px;
    43. opacity: 0;
    44. transition: 0.6s all;
    45. position: absolute;
    46. bottom: 20px;
    47. left: 10px;
    48. z-index: 3;
    49. }
    50. img {
    51. width: 1.2rem;
    52. }
    53. .icon:hover + .info, .icon:focus + .info {
    54. opacity: 1;
    55. }
    56. `;
    57. // Attach the created elements to the shadow dom
    58. shadow.appendChild(style);
    59. console.log(style.isConnected);
    60. shadow.appendChild(wrapper);
    61. wrapper.appendChild(icon);
    62. wrapper.appendChild(info);
    63. //外部css的方式,由于不会阻塞渲染,可能会导致一瞬间空白样式
    64. const linkElem = document.createElement('link');
    65. linkElem.setAttribute('rel', 'stylesheet');
    66. linkElem.setAttribute('href', 'style.css');
    67. shadow.appendChild(linkElem);
    68. }
    69. }
    70. // Define the new element
    71. customElements.define('popup-info', PopUpInfo);

    ;host是整个shadowRoot popup-info的样式
    :host()选择包含使用这段 CSS 的Shadow DOM的影子宿主,括号里是父元素的选择器
    https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_shadow_DOM#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95

    1. //https://github.com/mdn/web-components-examples/tree/master/host-selectors
    2. let style = document.createElement('style');
    3. const shadowRoot = this.attachShadow({mode: 'open'});
    4. shadowRoot.appendChild(style);
    5. style.textContent = 'span:hover { text-decoration: underline; }' +
    6. ':host-context(h1) { font-style: italic; }' +
    7. ':host-context(h1):after { content: " - no links in headers!" }' +
    8. ':host-context(article, aside) { color: gray; }' +
    9. ':host(.footer) { color : red; }' +
    10. ':host { background: rgba(0,0,0,0.1); padding: 2px 5px; }';
    • connectedCallback:当 custom element首次被插入文档DOM时,被调用。
    • disconnectedCallback:当 custom element从文档DOM中删除时,被调用。
    • adoptedCallback:当 custom element被移动到新的文档时,被调用。
    • attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用。

    需要注意的是,如果需要在元素属性变化后,触发 attributeChangedCallback()回调函数,你必须监听这个属性。这可以通过定义observedAttributes() get函数来实现,observedAttributes()函数体内包含一个 return语句,返回一个数组,包含了需要监听的属性名称:
    static get observedAttributes() {return [‘w’, ‘l’]; }