纯js模态框

/**
 * @class Model
 * @author 吹懜到汐州
 * @description Model Frame
 * @param options:Object => [title:string, content:string, confirm:string, cancel:string, showModel:boolean, showMask:boolean, 
 *         showConfirm:boolean, showCancel:boolean, isDrag:boolean, skin:color, confirmCallbak:function, cancelCallbak:function]
 */
class Model {
    constructor(option) {
        this.width = option.width || 260;
        this.height = option.height || 160;
        this.pos = option.pos || {
            x: 0,
            y: 0
        }
        this.title = option.title || '提示';
        this.content = option.content || '内容';
        this.confirm = option.confirm || '确认';
        this.cancel = option.cancel || '取消';
        this.showModel = option.showModel === undefined ? true : option.showModel; /* 是否显示弹窗 */
        this.showMask = option.showMask === undefined ? true : option.showMask; /* 是否显示遮罩 */
        this.showConfirm = option.showConfirm === undefined ? true : option.showConfirm; /* 是否显示确认按钮 */
        this.showCancel = option.showCancel === undefined ? true : option.showCancel; /* 是否显示确认按钮 */
        this.isDrag = option.isDrag === undefined ? false : option.isDrag;; /* 是否可拖拽 */
        this.skin = option.skin || ''; /* 主题色 "#20222A"|"#1E9FFF"|"tan"|"409EFF" */
        /* 确认回调 */
        this.confirmCallbak = option.confirmCallbak === undefined ? function () {
            console.log('%c confirmCallBack showModel=>' + this.close(), 'color:blue')
        } : option.confirmCallbak;
        /* 取消回调 */
        this.cancelCallbak = option.cancelCallbak === undefined ? function () {
            console.log('%c cancelCallbak showModel=>' + this.close(), 'color:red')
        } : option.cancelCallbak;
    };
    init() {
        /* 创建一个弹框容器 */
        this.gyModel = document.createElement('article');
        this.gyModel.classList.add("gy-model");
        this.gyModel.innerHTML = this.getCss() + this.getModel();
        document.getElementsByTagName("body")[0].appendChild(this.gyModel);
        this.setAttribute();
    };
    getCss() {
        return '<style>*{margin:0;padding:0}.gy-bj{width:100vw;height:100vh;position:fixed;top:0;left:0;z-index:999;background-color:rgb(0,0,0,0.2)}.gy-container{min-width:200px;min-height:160px;position:fixed;left:50%;top:50%;z-index:1000;background-color:#fff;transform:translate(-50%,-50%);border-radius:2px;font-size:14px;box-shadow:1px 1px 5px rgb(0,0,0,0.2)}.gy-close{width:42px;height:42px;line-height:42px;text-align:center;display:inline-block;position:absolute;right:0;top:0;font-size:20px;font-weight:bold;cursor:pointer;user-select:none}.gy-dialog{width:100%;height:100%;display:flex;flex-direction:column}.gy-header{height:42px;line-height:42px;color:#333;padding:0 20px;border-bottom:1px solid #eee;cursor:auto;overflow:auto;text-overflow:ellipsis;white-space:nowrap;user-select:none}.gy-content{flex:1;padding:20px;font-size:14px;text-align:left;color:#666;overflow:hidden;word-break:break-all;overflow-x:hidden;overflow-y:auto}.gy-footer{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none}.gy-footer .btn{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.gy-footer .btn.confirm{border-color:#1e9fff;background-color:#1e9fff;color:#fff}</style>';
    };
    getModel() {
        return '<div class="gy-bj"></div><div class="gy-container"><span class="gy-close">&times</span><div class="gy-dialog"><div class="gy-header">提示</div><div class="gy-content">内容</div><div class="gy-footer"><button class="btn confirm">确认</button><button class="btn cancel">关闭</button></div></div></div>';
    };
    setAttribute() {
        this.gyBj = this.gyModel.querySelector('.gy-bj');
        this.gyContainer = this.gyModel.querySelector('.gy-container');
        this.gyClose = this.gyContainer.querySelector('.gy-close');
        this.gyHeader = this.gyContainer.querySelector('.gy-header');
        this.gyContent = this.gyContainer.querySelector('.gy-content');
        this.gyConfirm = this.gyContainer.querySelector('.btn.confirm');
        this.gyCancel = this.gyContainer.querySelector('.btn.cancel');

        this.gyContainer.style.width = this.width + 'px';
        this.gyContainer.style.height = this.height + 'px';
        this.gyHeader.innerHTML = this.title;
        this.gyContent.innerHTML = this.content;
        this.gyConfirm.innerHTML = this.confirm;
        this.gyCancel.innerHTML = this.cancel;
        this.showModel ? this.open() : this.close();
        this.gyBj.style.display = this.showMask ? "block" : "none";
        this.gyConfirm.style.display = this.showConfirm ? "inline-block" : "none";
        this.gyCancel.style.display = this.showCancel ? "inline-block" : "none";
        if (this.skin) {
            this.gyHeader.style.backgroundColor = this.skin;
            this.gyHeader.style.color = '#fff';
            this.gyClose.style.color = '#fff';
            this.gyConfirm.style.backgroundColor = this.skin;
            this.gyConfirm.style.borderColor = this.skin;
        }
        if (this.pos.x && this.pos.x !== -1) this.gyContainer.style.left = this.pos.x +
            this.gyContainer.offsetWidth / 2 + 'px';
        if (this.pos.y && this.pos.y !== -1) this.gyContainer.style.top = this.pos.y +
            this.gyContainer.offsetHeight / 2 + 'px';
        this.bindEvent();
    };
    bindEvent() {
        if (this.isDrag) {
            this.gyHeader.style.cursor = "move";
            let _gyContainer = this.gyContainer;
            /* 样式中用了这个属性居中, 影响拖拽定位, 还原位置 */
            _gyContainer.style.transform = "translate(0%, 0%)";
            _gyContainer.style.left = _gyContainer.offsetLeft - _gyContainer.offsetWidth / 2 + 'px';
            _gyContainer.style.top = _gyContainer.offsetTop - _gyContainer.offsetHeight / 2 + 'px';
            this.gyHeader.addEventListener('mousedown', function (e) {
                e.preventDefault();
                let x = e.pageX - _gyContainer.offsetLeft; /* 鼠标距离左边的位置 减去 模态框距离父元素左边的距离 */
                let y = e.pageY - _gyContainer.offsetTop; /* 鼠标距离上边的位置 减去 模态框距离父元素上边的距离 */
                document.addEventListener('mousemove', move);

                function move(e) {
                    e.preventDefault();
                    let left = e.pageX - x;
                    let top = e.pageY - y;

                    left = left < 0 ? 0 : left;
                    top = top < 0 ? 0 : top;

                    left = left > innerWidth - _gyContainer.offsetWidth ? innerWidth - _gyContainer
                        .offsetWidth : left;
                    top = top > innerHeight - _gyContainer.offsetHeight ? innerHeight -
                        _gyContainer.offsetHeight : top;

                    _gyContainer.style.left = left + 'px'; /* 鼠标的位置减去鼠标距离模态框左边的位置设置为模态框距离父元素左边的距离 */
                    _gyContainer.style.top = top + 'px'; /* 鼠标的位置减去鼠标距离模态框上边的位置设置为模态框距离父元素上边的距离 */
                }
                document.addEventListener('mouseup', function () {
                    document.removeEventListener('mousemove', move);
                });
            });
        };
        /* this.gyBj.onclick = this.gyClose.onclick = ()=>{this.close();}; */
        this.gyBj.onclick = this.gyClose.onclick = this.gyCancel.onclick = () => {
            this.cancelCallbak && this.cancelCallbak();
        };
        this.gyConfirm.onclick = () => {
            this.confirmCallbak && this.confirmCallbak();
        };
    }
    open() {
        this.gyModel.style.display = "block";
        return this.showModel = true;
    };
    close() {
        /* this.gyBj.style.display = "none";
        this.gyModel.style.transform = "translate(0%, 0%) scale(0)";
        this.gyModel.style.transition = "transform 0.5s linear";
        setTimeout(() => this.gyModel.remove(), 500); */
        this.gyModel.remove()
        return this.showModel = false;
    };
    getStyle(e, attr) {
        return window.getComputedStyle ?
            getComputedStyle(e).getPropertyValue(attr) :
            e.currentStyle[attr];
    };
    move(dom, option, time, callback) {
        let len = 0;
        for (const key in option) {
            len++;
            clearInterval(dom[key]);
            dom[key] = setInterval(() => {
                let attrValue = parseInt(this.getStyle(dom, key));
                var speed = (option[key] - attrValue) / 10;
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                attrValue += speed;
                dom.style[key] = attrValue + "px";
                if (attrValue == option[key]) {
                    clearInterval(dom[key]);
                    len--;
                    if (len == 0) callback && callback();
                }
            }, time);
        }
    };
}
class AdPopModel extends Model {
    constructor(option) {
        option.width = 200;
        option.height = 280;
        option.showMask = false;
        option.showConfirm = false;
        option.showCancel = false;
        option.isDrag = false;
        option.pos = {
            x: innerWidth - option.width,
            y: innerHeight - option.height
        }
        super(option);

        /* 十秒后自动关闭 */
        this.timeout = setTimeout(() => {
            /* super.colse(); */
            this.close();
        }, 5000);
    }
    close() {
        super.move(this.gyContainer, {
            'top': innerHeight
        }, 100, () => {
            super.close();
        });
        // 清除5s后关闭延迟
        clearTimeout(this.timeout);
    }
}
/*
<!-- 使用方式 -->
<script src="./js/model.js"></script>
<script>
      new Model({
        title: "信息",
        content: res.msg,
        showCancel: false,
        isDrag: true,
        skin: "tan",
        confirmCallbak: function () {
          this.close();
        },
    }).init();
</script>
*/
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值