前两天看到了前端的Web Components学习了一下。组件是前端的发展方向。而Web Components是浏览器的原生组件。相比第三方框架,其简单直接,不用加载任何外部模块,代码量小。现在其还在不断发展,但已经可用于生产环境。 Web Components 包含的内容很多,我只是做了一个简单的弹框案例。其他的功能则需要你自己去学习、去扩展了。
1、静态弹框(以前的写法)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> body { margin: 0; } .dialog_box { width: 521px; height: 563px; border-radius: 8px; box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.4); background-color: #fff; position: absolute; padding: 0 40px; top: 0; left: 0; right: 0; bottom: 0; margin: auto; } .dialog_box.bg1 { background-image: url("img/bg_03.png"); background-repeat: no-repeat; background-size: 100%; } .dialog_box.bg2 { background-image: url("img/bg_06.png"); background-repeat: no-repeat; background-size: 100%; } .dialog_header { height: 215px; } .dialog_title { height: 57px; font-size: 30px; text-align: center; line-height: 57px; } .dialog_content { height: 130px; text-align: center; font-size: 24px; line-height: 29px; padding: 30px 52px 0; } .btn_line { height: 110px; display: flex; justify-content: center; } .btn { width: 221px; height: 74px; border-radius: 4px; box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.3); font-size: 30px; line-height: 74px; text-align: center; cursor: pointer; margin: 0 20px; } .btn.cancel { background: #e7e7e7; } .btn.confirm { background: #e5322e; color: #fff; } .mask { background: rgba(0, 0, 0, 0.5); position: fixed; top: 0; left: 0; right: 0; bottom: 0; } </style></head><body> <div class="mask"></div> <div class="dialog_box bg2"> <div class="dialog_header"></div> <div class="dialog_title">标题</div> <div class="dialog_content">内容</div> <div class="btn_line"> <div class="btn cancel">知道了</div> <div class="btn confirm">马上来抢</div> </div> </div></body></html>
效果:
二、利用Web Components
主要是利用DOM HTMLElement对象和windows属性customElements来实现。
<my-com></my-com><script type="module"> class myCom extends HTMLElement{ constructor(){ super(); this.render(); //初始化弹框 } render(){ this.obj = document.createElement('div'); this.obj.innerHTML = ` <div class="mask"></div> <div class="dialog_box bg2"> <div class="dialog_header"></div> <div class="dialog_title">标题</div> <div class="dialog_content">内容</div> <div class="btn_line"> <div class="btn cancel">知道了</div> <div class="btn confirm">马上来抢</div> </div> </div> ` this.append(this.obj); } } customElements.define('my-com',myCom)</script>
三、添加组件属性,修改弹框内容
给my-com组件添加title和content属性,在再js中修改获取到属性值,更改相应的数据。
<my-com title='这里是自定义的标题' content='这里是我们自定义的内容'></my-com>constructor(){ super(); let attr = this.attributes; this._data = { title:attr.title?attr.title.value:'默认标题', content:attr.content?attr.content.value:'默认内容' } this.render(); //初始化弹框}render(){ this.obj = document.createElement('div'); this.obj.innerHTML = ` <div class="mask"></div> <div class="dialog_box bg2"> <div class="dialog_header"></div> <div class="dialog_title">${this._data.title}</div> <div class="dialog_content">${this._data.content}</div> <div class="btn_line"> <div class="btn cancel">知道了</div> <div class="btn confirm">马上来抢</div> </div> </div> ` this.append(this.obj);}
四、添加事件
先新写一个事件构造函数。在利用弹框相应的元素上添加data-[事件名]的属性。 点击相应的元素,会触发响应。
class popEvent { constructor(option) { /* * 接收四个参数: * 1,对象的this * 2,要监听的元素, 不传则为对象this * 3,要监听的事件,默认监听点击事件 * 4,是否冒泡, 默认冒泡 * */ this.eventObj = option.obj; console.log(this.eventObj.__proto__['hide']) this.target = option.target || this.eventObj; this.eventType = option.eventType || 'click'; this.popup = option.popup || true; this.bindEvent(); } bindEvent() { let _this = this; _this.target.addEventListener(_this.eventType, function (ev) { let target = ev.target; let dataset, parent, num, b; popup(target); function popup(obj) { if (obj === document) { return false; } dataset = obj.dataset; num = Object.keys(dataset).length; parent = obj.parentNode; if (num < 1) { popup(parent); num = 0; } else { for (b in dataset) { console.log(b); if (_this.eventObj.__proto__[b]) { _this.eventObj.__proto__[b].call(_this.eventObj, { obj: obj, ev: ev, target: dataset[b], data: _this.eventObj }); } } _this.popup && popup(parent); } } }) } constructor(){ super(); let attr = this.attributes; this._data = { title:attr.title?attr.title.value:'默认标题', content:attr.content?attr.content.value:'默认内容' } this.render(); //初始化弹框 this.event = new popEvent({ obj: this });}hide(){ console.log("点击了hide") this.obj.style.display = 'none';}cancle(){ console.log("点击了concle")}confirm(){ console.log("点击了confirm")}render(){ this.obj = document.createElement('div'); this.obj.innerHTML = ` <div class="mask" data-hide='true'></div> <div class="dialog_box bg2"> <div class="dialog_header"></div> <div class="dialog_title">${this._data.title}</div> <div class="dialog_content">${this._data.content}</div> <div class="btn_line"> <div class="btn cancel" data-hide='true' data-cancel='true'>知道了</div> <div class="btn confirm" data-confirm='true'>马上来抢</div> </div> </div> ` this.append(this.obj);}
创建img标签时注意因素
在img标签上添加is属性,利用HTMLImageElement 对象和customElements来实现。
<img is="my-img" src="" alt=""> <script> class myIMG extends HTMLImageElement { constructor() { super(); setTimeout(() => { this.src = 'https://hbimg.huabanimg.com/67bcf019c3aba12abc19624e1afe3418a03fb2021cf00-iDEjac_fw658/format/webp'; }, 2000); } } customElements.define('my-img', myIMG, { extends: 'img' }); </script>
欢迎关注公众号(web学习吧),一起学习进步:
本文使用 mdnice 排版