前两天看到了前端的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 排版