使用 web component 构建一个通用无依赖 html 单文件 select 组件

效果

使用 web component 构建一个通用无依赖 html 单文件 select 组件_第1张图片

体验
web component select

web components polyfill 兼容旧版本浏览器的支持插件
https://www.webcomponents.org...


Web Component 是一系列 web 平台的 API,它们可以允许你创建全新可定制、可重用并且封装的 HTML 标签

定制的组件基于 Web Component 标准构建,可以在现在浏览器上使用,也可以和任意与 HTML 交互的 JavaScript 库和框架配合使用。

它赋予了仅仅使用纯粹的JS/HTML/CSS就可以创建可重用组件的能力。如果 HTML 不能满足需求,我们可以创建一个可以满足需求的 Web Component。


源码
(function () {
  const selectListDemo = [
    {name: 'test1', value: 1},
    {name: 'test2', value: 2},
    {name: 'test3', value: 3}
  ]

  class MidociSelect extends HTMLElement {
    static get observedAttributes() {
      return ['acitve-title', 'active-sub-title']
    }

    constructor() {
      super()
      this.attachShadow({mode: 'open'})
      this.shadowRoot.innerHTML = `
        
        
        
1
1
2
3
4
` this._wrapperDom = null this._listDom = null this._titleDom = null this._list = [] this._arrowFlip = false this._value = null this._name = null } connectedCallback() { this._wrapperDom = this.shadowRoot.querySelector('.wrapper') this._listDom = this.shadowRoot.querySelector('.list') this._titleDom = this.shadowRoot.querySelector('.title') this.initEvent() this.list = selectListDemo } disconnectedCallback() { this._wrapperDom.removeEventListener('click', this.flipArrow.bind(this)) this._wrapperDom.removeEventListener('blur', this.blurWrapper.bind(this)) this.shadowRoot.querySelectorAll('.item') .forEach((item, index) => { item.removeEventListener('click', this.change.bind(this, index)) }) } attributeChangedCallback(attr, oldVal, newVal) { // const attribute = attr.toLowerCase() // if (attribute === 'descriptions') { // console.log(1) // this.render(newVal) // } } set list(list) { if (!this.shadowRoot) return this._list = list this.render(list) } get list() { return this._list } set value(value) { this._value = value } get value() { return this._value } set name(name) { this._name = name } get name() { return this._name } initEvent() { this.initArrowEvent() this.blurWrapper() } initArrowEvent() { this._wrapperDom.addEventListener('click', this.flipArrow.bind(this)) } initChangeEvent() { this.shadowRoot.querySelectorAll('.item') .forEach((item, index) => { item.addEventListener('click', this.change.bind(this, index)) }) } change(index) { this.changeTitle(this._list, index) let changeInfo = { detail: { value: this._value, name: this._name }, bubbles: true } let changeEvent = new CustomEvent('change', changeInfo) this.dispatchEvent(changeEvent) } changeTitle(list, index) { this._value = list[index].value this._name = list[index].name this._titleDom.innerText = this._name } flipArrow() { if (!this._arrowFlip) { this.showList() } else { this.hideList() } } showList() { this._arrowFlip = true this._wrapperDom.classList = 'wrapper flip' } hideList() { this._arrowFlip = false this._wrapperDom.classList = 'wrapper' } blurWrapper() { this._wrapperDom.addEventListener('blur', (event) => { event.stopPropagation() this.hideList() }) } render(list) { if (!list instanceof Array) return let listString = '' list.forEach((item) => { listString += `
${item.name}
` }) this._listDom.innerHTML = listString this.changeTitle(list, 0) this.initChangeEvent() } } const FrozenMidociSelect = Object.freeze(MidociSelect); customElements.define('midoci-select', FrozenMidociSelect); })()
注意:如果父元素高度太低,需要关闭父元素的 overflow 属性,否则会遮盖 下拉列表

使用





你可能感兴趣的:(组件化,css3,html5,web-components)