使用面向对象/继承等实现dialog组件

  1. HTML部分只有两个按钮,用于唤起dialog弹窗
	<!-- 
		按钮1打开的是不带input的弹窗
		按钮2打开的是在按钮1调用基础上继承的类并带input框的弹窗
 	-->
	<button class="dailog1">点击</button>
    <button class="dailog2">点击2</button>
  1. js部分涉及到ES6相关的部分包括,class语法,ES5版本的继承,ES6相关的继承,事件委托,自定义事件
    // 对内:封闭;对外:开放(api、配置)
    /*
    这部分的参数也就是目前组件支持的参数
    {
        width: "30%",
        height: "250px",
        title: "测试标题",
        content: "测试内容",
        dragable: true, //是否可拖拽
        maskable: true, //是否有遮罩
        isCancel:false //是否有取消
    }
    */
    
    /*
	* 构造函数
	* 1. 约定俗成:首字母大写
	* 2. 属性放到构造函数,方法放在原型里面
	* 方法之所以放原型是因为可以实现公共空间,节省内存
	*/
    class MyDialog extends EventTarget {
        constructor (options) {
            super()
            this.opts = Object.assign({
                width: "30%",
                height: "250px",
                title: "测试标题",
                content: "测试内容",
                dragable: true, //是否可拖拽
                maskable: true, //是否有遮罩
                isCancel:false, //是否有取消
                success: () => {
                    console.log('点击了默认确认');
                },
                close: () => {
                    console.log('点击了默认关闭');
                }
            }, options)
            this.init()
        }
        
		// 组件初始化时调用的方法
        init() {
            this.renderShow()
            
            // 自定义事件,通过自定义事件实现事件监听
            let close = new Event('close')
            this.addEventListener('success', this.opts.success)
            this.addEventListener('cancel', this.opts.cancel)
            
            // 1. 采用这种方式进行按钮的处理,会出现按钮不存在的时候报错的问题,所以使用事件委托的机制,也就是备注1.1涉及到的代码
            // this.dialogHtml.querySelector('.k-close').onclick = () => {
            //     this.close()
            // }
            // this.dialogHtml.querySelector('.k-cancel').onclick = () => {
            //     this.close()
            // }
            // this.dialogHtml.querySelector('.k-primary').onclick = () => {
            //     this.close()
            // }
			
			// 1.1 使用事件委托实现
			// 事件委托:子节点个数不固定,或者说子节点是动态渲染,不一定会存在时,如果想要给某个时间加节点事件,是无法直接获取到节点的,这时候可以通过获取到父节点,通过事件的e.target获取到当前点击的节点
			// 在此处的应用实例是取消按钮是可以动态控制展示与否的,如果不进行事件委托,直接绑定事件会导致页面报错
            this.dialogHtml.onclick = e => {
                switch(e.target.className) {
                    case 'k-close':
                        this.close();
                        // 事件注入
                        this.dispatchEvent(close)
                        // this.opts.close()
                        break
                    case 'k-cancel':
                        this.close();
                        this.dispatchEvent(close)
                        // this.opts.close()
                        break
                    case 'k-primary':
                        this.close();
                        this.comfirm()
                        // this.opts.success()
                        break
                }
            }
        }
        
        // 点击确认时,调用的方法
        comfirm(value) {
            let success = new CustomEvent('success', {
                detail: value
            })
            this.dispatchEvent(success)
        }
        
        // 点击页面按钮时,调用这个方法
        show() {
            if(this.opts.maskable) {
                this.dialogHtml.querySelector('.k-wrapper').style.display = 'block'
            }
            this.dialogHtml.querySelector('.k-dialog').style.display = 'block'
        }
        
        // 点击取消获取关闭时调用页面的这个方法
        close() {
            this.dialogHtml.querySelector('.k-wrapper').style.display = 'none'
            this.dialogHtml.querySelector('.k-dialog').style.display = 'none'
        }

		// 页面通过Js动态渲染
        renderShow() {
            this.dialogHtml = document.createElement('div')
            this.dialogHtml.innerHTML = `
                <div class="k-wrapper"></div>
                <div class="k-dialog" style="width: ${this.opts.width}; height: ${this.opts.height}">
                    <div class="k-header">
                        <span class="k-title">${this.opts.title}</span><span class="k-close">X</span>
                    </div>
                    <div class="k-body">
                        <span>${this.opts.content}</span> 
                    </div>
                    <div class="k-footer">
                        ${this.opts.isCancel ? '<span class="k-cancel">取消</span>' : ''}
                        <span class="k-primary">确定</span>
                    </div>
                </div>
            `
            document.body.append(this.dialogHtml)
        }
    }

	// 通过类的继承,在原有的MyDialog增加或者修改方法
    class inputDialog extends MyDialog {
        constructor(options) {
        	// 继承的时候一定要调用super,传参也是通过super进行传递
            super(options)
            this.inputRender()
        }
		
		// 在原有的MyDialog基础上插入一个input框
        inputRender() {
            let input = document.createElement('input')
            input.className = 'input-inner'
            input.type = 'text'
            this.dialogHtml.querySelector('.k-body').append(input)
        }
		
		// 点击确认时,可以获取到输入框的内容
        comfirm() {
            const value = this.dialogHtml.querySelector('.input-inner').value
            // super.comfirm方法可以实现修改原方法的基础上继承原方法
            super.comfirm(value)
        }
    }
    let dialog1 = new MyDialog({
        width: '300px',
        height: '250px',
        isCancel: true,
        success() {
            console.log('点击了确认');
        },
        close() {
            console.log('点击了关闭');
        }
    })

    document.querySelector('.dailog1').onclick = function() {
        dialog1.show()
    }

	// new 进行实例化对象
	/*
	* new 运算符有如下几个作用
	* 1. 执行函数
	* 2. 自动创建一个空对象
	* 3. 把创建的对象指向另一个对象,也就是调用的对象
	* 4. 把空对象和函数里的this衔接起来
	* 5. 隐式返还this
	*/

    let dialog2 = new inputDialog({
        width: '300px',
        height: '250px',
        isCancel: true,
        success(e) {
            console.log('点击了确认', e.detail);
        },
        close() {
            console.log('点击了关闭');
        }
    })

    document.querySelector('.dailog2').onclick = function() {
        dialog2.show()
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值