当前位置: 首页 > Web前端 > HTML5

使用webcomponent搭建一个通用的无依赖html单文件select组件

时间:2023-04-05 16:07:13 HTML5

效果体验webcomponentselectwebcomponentspolyfill兼容老浏览器支持插件https://www.webcomponents.org...WebComponent是一系列网络平台API,允许您创建新的可定制、可重用和封装的HTML标签。自定义组件建立在Web组件标准之上,可以在现代浏览器中使用,也可以与任何与HTML交互的JavaScript库和框架一起使用。.它提供了仅使用纯JS/HTML/CSS创建可重用组件的能力。如果HTML还不够,我们可以创建一个Web组件来满足。源码(function(){constselectListDemo=[{name:'test1',value:1},{name:'test2',value:2},{name:'test3',value:3}]classMidociSelectextendsHTMLElement{staticgetobservedAttributes(){return['acitve-title','active-sub-title']}constructor(){super()this.attachShadow({mode:'open'})this.shadowRoot.innerHTML=`<样式>:host{--themeColor:rgb(24,144,255);box-sizing:border-box;font-size:14px;--borderColor:#eee;}.wrapper{position:relative;display:inline-flex;对齐项目:中心;左填充:10px;宽度:95px;高度:36px;边框:1pxsolidvar(--borderColor);颜色:#333;边框半径:2px;用户选择:无;过渡:.3s立方贝塞尔(.12,.4,.29,1.46);大纲:无}.wrapper:悬停{边框:1px实心var(--themeColor);过渡:.3s立方贝塞尔曲线(.12、.4、.29、1.46);}.title{}.arrow-out{位置:绝对;右:12px;顶部:50%;变换:translateY(0px)rotateX(0deg);过渡:.3s立方贝塞尔曲线(.12、.4、.29、1.46);}.wrapper.flip>.arrow-out{转换:translateY(-3px)rotateX(180deg);过渡:.3s立方贝塞尔曲线(.12、.4、.29、1.46);}.arrow{显示:弹性;宽度:6px;高度:6px;边框:无;左边框:1pxsolid#333;border-bottom:1pxsolid#333;变换:translateY(-50%)rotateZ(-45deg);过渡:.3s立方贝塞尔(.12,.4,.29,1.46);}.wrapper:hover.arrow{border-left:1pxsolidvar(--themeColor);border-bottom:1pxsolidvar(--themeColor);过渡:.3s立方贝塞尔曲线(.12、.4、.29、1.46);}.list{z-index:100;位置:绝对;顶部:130%;左:0;背景色:#fff;盒子阴影:0010pxrgba(0,0,0,0.1);可见性:隐藏;最小宽度:100%;边界半径:3px;变换:比例(0);变换原点:顶部;过渡:.3s立方贝塞尔曲线(.12、.4、.29、1.46);}.wrapper.flip>.list{可见性:可见;变换:规模(1);过渡:.3s立方贝塞尔曲线(.12、.4、.29、1.46);}.item{显示:弹性;对齐项目:居中;左填充:10px;宽度:95px;高度:36px;颜色:#333;边界半径:2px;用户选择:无;背景色:#fff;过渡:背景颜色.3s缓入缓出;}.item:hover{背景颜色:rgba(24,144,255,0.1);过渡:背景颜色.3s缓入缓出;}11

2
3
4
`this._wrapperDom=nullthis._listDom=nullthis._titleDom=nullthis._list=[]this._arrowFlip=falsethis._value=nullthis._name=null}connectedCallback(){this._wrapperDom=this.shadowRoot.querySelector('.包装器')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){//constattribute=attr.toLowerCase()//if(attribute==='描述'){//console.log(1)//this.render(newVal)//}}setlist(list){if(!this.shadowRoot)returnthis._list=listthis.render(list)}getlist(){returnthis._list}设置值(值){this._value=value}getvalue(){returnthis._value}setname(name){this._name=name}getname(){returnthis._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)letchangeInfo={细节:{value:this._value,name:this._name},bubbles:true}让changeEvent=newCustomEvent('change',changeInfo)this.dispatchEvent(changeEvent)}changeTitle(list,index){this._value=list[index].valuethis._name=list[index].namethis._titleDom.innerText复制代码=this._name}flipArrow(){if(!this._arrowFlip){this.showList()}else{this.hideList()}}showList(){this._arrowFlip=truethis._wrapperDom.classList='包装翻转'}hideList(){this._arrowFlip=falsethis._wrapperDom.classList='wrapper'}blurWrapper(){this._wrapperDom.addEventListener('blur',(event)=>{event.stopPropagation()this.hideList()})}render(list){if(!listinstanceofArray)returnletlistString=''list.forEach((item)=>{listString+=`${item.name}`})this._listDom.innerHTML=listStringthis.changeTitle(list,0)this.initChangeEvent()}}constFrozenMidociSelect=Object.freeze(MidociSelect);customElements.define('midoci-select',FrozenMidociSelect);})()注意:如果父元素的高度太低,需要关闭父元素的overflow属性,否则下拉列表会被覆盖使用