赞
踩
Web Component 是Html5 推出的一个新特征,即web 组件。提到web组件有一定前端开发经验的人对这个词汇并不陌生,在这个严重依赖前端框架来开发项目的时代,我们推崇使用组件化的思路来编写我们的页面,通过这些低耦合的组件我们可以像搭积木一样组织出我们的页面。
从我们的日常所见到的类似table select 这些耳熟能详的基础标签,更有后来更复杂的video raido等,都是web组件化的一种体现。可惜的是兼容性问题以及api的丰富度不够。目前主流还是使用框架来模拟组件的实现。随着浏览器兼容的越来越好,如果能完全使用web component来组织我们的项目,我们可以少引入很多第三方的框架来编排我们的页面
本文我们将来探究 Web Component
关键的api,它是挂载在window上的api,并非document。
window.customElements.define()
// 参数类型
// name 是组件名称
// constructor 自定义组件的构造类
// options 更多的属性
(method) CustomElementRegistry.define(name: string, constructor: CustomElementConstructor, options?: ElementDefinitionOptions): void
class MyButton extends HTMLButtonElement {
constructor () {
// 必须加super 否则this 无法指向button
super()
this.addEventListener('click', function () {
alert('this is my button')
})
}
}
customElements.define('my-button', MyButton, { extends: "button" })
申明的时候,需要通过extends传入一个已经存在的内置元素,调用的时候通过内置元素的is来扩展,
<button is="my-button">Click me</button>
class TextIcon extends HTMLElement { constructor() { super() this._text = null; } static observedAttributes = ['text']; attributeChangedCallback(name, oldValue, newValue) { this._text = newValue; this.updateRender(); } connectedCallback() { this.updateRender(); } get text () { return this._text; } set text(v) { console.log(v, 'ss') this.setAttribute('text', v) } updateRender () { this.innerText=this._text } } customElements.define('text-icon', TextIcon)
调用方式1
<text-icon text="test1"></text-icon>
调用方式2
const textIcon = document.createElement('text-icon')
textIcon.setAttribute('text', 'sddd')
document.body.appendChild(textIcon)
const textIcon1 = new TextIcon()
textIcon1.text = 12
document.body.appendChild(textIcon1)
window.customElements.upgrade(elementNode)
注意看代码中的注释
// 通过createElemnt创建自定义元素节点,注意此时text-icon 还定义 const testUpgradeDom = document.createElement('text-icon') // 开始定义text-icon 元素 class TextIcon extends HTMLElement { constructor() { super() this._text = null; } static observedAttributes = ['text']; attributeChangedCallback(name, oldValue, newValue) { this._text = newValue; this.updateRender(); } connectedCallback() { this.updateRender(); } get text () { return this._text; } set text(v) { console.log(v, 'ss') this.setAttribute('text', v) } updateRender () { this.innerText=this._text } } customElements.define('text-icon', TextIcon) // 此时我们可以看到testUpgradeDom 这个节点非自定义元素 console.log(testUpgradeDom instanceof TextIcon); //false // 调用升级api customElements.upgrade(testUpgradeDom) // 此时testUpgradeDom 就升级成了自定义元素创建的节点 console.assert(testUpgradeDom instanceof TextIcon); // true
customElements.get('text-icon')
customElements.whenDefined('text-icon').then(function() {
// 自定义操作
})
返回的是一个promise 当监测到text-icon 被定义后,我们可以去做一些操作,比如上面提到的升级操作等。
class MyCheckbox extends HTMLElement{ // 这个标示来控制是否是form关联的元素 static formAssociated = true static observedAttributes = ['checked']; constructor() { super() this._internals = this.attachInternals() this.addEventListener('click', this._onClick.bind(this)); } get form () { return this._internals.form; } get name () { return this._internals.name; } get type() { return this._internals.type } get checked () { return this.getAttribute('checked') } set checked(tag) { console.log(tag,'xx') this.toggleAttribute('checked', Boolean(tag)) } attributeChangedCallback() { this._internals.setFormValue(this.checked? 'on' : 'off') // this._internals.ariaChecked = this.checked; } _onClick (event) { debugger this.checked = !this.checked } } customElements.define('my-checkbox', MyCheckbox)
调用
<form method="post" action="">
<label><my-checkbox name="agreed"></my-checkbox> I read the agreement.</label>
<input type="submit">
</form>
// 初始化 constructor() // 组件第一次关联到文档 connectedCallback() // 组件断开和文档的连接 disconnectedCallback() // 组件关联到新的文档 adoptedCallback() // 组件属性变化回调 attributeChangedCallback() // 组件和表单关联的变化回调 formAssociatedCallback() // 自定义关联表单组件的表单发生了reset操作的回调 formResetCallback() // 自定义form元素 被设置为 disabled时的回调 formDisabledCallback() // form restore时候触发 formStateRestoreCallback()
几个注意点
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。