zoukankan      html  css  js  c++  java
  • Web Components之Custom Elements

    什么是Web Component?

    Web Components 包含了多种不同的技术。你可以把Web Components当做是用一系列的Web技术创建的、可重用的用户界面组件的统称。Web Components使开发人员拥有扩展浏览器标签的能力,可以自由的进行定制组件。但截至本文时间,Web Components依然是W3C工作组的一个草案,并为被正式纳入标准,但这并不妨碍我们去学习它。

    Web组件

    何为Web组件?Web组件相对于Web开发者来说并不陌生,Web组件是一套封装好的HTML,CSS,以及JavaScript,它最大的特点就是可复用。基本在每一个网站上我们都可以看到各式各样的组件,例如下拉菜单、按钮、图片滚播、日历控件等。慢着,既然我们已经可以实现web组件的封装,那Web Component这家伙出现的意义是什么呢?Web Component回答道:“你们的实现方式不够优雅也不够完美,还是看看我的吧”。

    因为当我们使用各种编程技巧对组件进行封装时,一个无法规避的事实是,组件的内部是可被访问和影响的,例如我们对样式表进行改动时经常会担心影响到页面组件的样式。而通过Web Component封装出来的组件,我们可以选择让组件的内部隐藏起来,也就是说,组件内部是与世隔绝的!

    Web Component的组成

    • Custom Elements
    • HTML Templates
    • Shadow Dom
    • HTML Imports

    总的来说,Web Components包含以上四种技术,本文着重谈谈Custom Element,这也是Web component中最核心的部分。

    Custom Elements

    自定义元素是一个可由创建者来自定义接口的对象。在创建时我们需要通过 document.registerElement() 来对自定义元素进行注册。该方法会返回一个元素的构造器,通过该构造器我们就可以创建我们的自定义元素的实例了。

    var MyButton= document.registerElement('my-button');
    document.body.appendChild(new MyButton());

    实际上 document.registerElement(tag-name, prototype) 包含两个参数:

    tag-name: 自定义元素的标签名,这个标签名必须包含连字符'-',这样做的母的是用以区分自定义元素和HTML规范的元素

    prototype: 这是一个可选的参数,用于描述该元素的原型,在该元素中你可以为自定义元素进行接口的定义

    var MyElement = document.registerElement('my-element', { 
      prototype: Object.create(HTMLElement.prototype, { 
        createdCallback: { 
          value: function() { 
            this.innerHTML = "<p>I'm a Custom Element</p>";
          } 
        } 
      }) 
    });
    document.body.appendChild(new MyElement())

    在上面的例子中,我们通过Object.create()方法创建了一个继承自HTMLElement的对象作为自定义对象的原型,并设置了元素默认的 innerHTML ,如果你对Object.create()方法的第二个参数不熟悉,你最好先去查阅一下。实际上它的上面的例子跟下面给出的写法的效果是一样的:

    var MyElementProto = Object.create(HTMLElement.prototype)
    
    MyElementProto.createdCallback = function() {
        this.innerHTML = "<p>I'm a Custom Element</p>"
    }
    
    var MyElement = document.registerElement('my-element', { prototype: MyElementProto })
    
    document.body.appendChild(new MyElement())

    接着,在页面上我们可以看到渲染出如下结构:

    自定义元素的生命周期

    在上面的例子中我们可以看到自定义元素的原型上有一个 createdCallback 属性,它的值是一个回调函数,在自定义元素被创建的时候被调用。实际上自定义元素在它的生命周期中可能会经历以下几种变化:

    • 自定义元素在其注册前被创建
    • 自定义元素被注册
    • 自定义元素的实例在自定义元素注册后被创建
    • 自定义元素被插入到文档中
    • 自定义元素从文档中移除
    • 自定义元素的属性被创建、移除、修改

    在自定义元素经历上面某些变化时,不同的回调函数会被调用。这些回调函数被保存在一个名为生命周期回调的键值对集合中。我们可实现的回调函数总共有以下4种,其中 attributeChangedCallback 的回调函数中我们可以通过其参数访问到操作的属性名、老的属性值、新的属性值。

    DOM:

    <div id="modify">
      <label class="CEgreen"><input type="radio" name="CEclass" value="green">green box</label>
      <label class="CEred"><input type="radio" name="CEclass" value="red">red box</label>
    </div>

    JS:

    var MyElement = document.registerElement('my-element', { 
      prototype: Object.create(HTMLElement.prototype, { 
        createdCallback: { 
          value: function() {
            this.innerHTML = "<span>I'm a Custom Element</span>"
          }
        },
        attributeChangedCallback: {
          value: function(property, oldValue, newValue) {
            this.innerHTML = "attribute '" + property + "' is modified to " + newValue
          }
        }
      }) 
    })
    document.body.appendChild(new MyElement())
    
    var temp = document.querySelector("#modify")
    var myElement = document.querySelector("my-element")
    
    temp.addEventListener('click', function(e){
      console.log(e.target.value)
      myElement.className = e.target.value
    })

    另外,给自定义元素添加样式和普通元素是一样的,这是上面例子中为自定义元素添加的样式:

    my-element {display: inline-block;margin-top: 20px;padding: 10px;font-size: 24px;}

    这就是一个最基础的自定义元素的实现了。如果我们希望自定义元素内部不受外部样式的影响,我们需要使用Shadow Dom来对内部dom结构和样式进行封装。

  • 相关阅读:
    Tornado @tornado.gen.coroutine 与 yield
    ThreadPoolExecutor执行任务,异常日志缺失问题
    Mybatis关联查询<association> 和 <collection>
    Spring整合mybatis
    Jedis操作Redis--Key操作
    Jedis操作Redis--SortedSet类型
    Jedis操作Redis--Set类型
    同义词 “stop from”,“keep from”和“prevent from”的区别
    test
    Python win32gui调用窗口到最前面
  • 原文地址:https://www.cnblogs.com/WhiteCusp/p/4321139.html
Copyright © 2011-2022 走看看