成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

寫一個(gè)單例構(gòu)造的對(duì)話框

weknow619 / 2837人閱讀

摘要:前言項(xiàng)目中,當(dāng)需要用戶處理事務(wù),又不希望跳轉(zhuǎn)頁面以致打斷工作流程時(shí),我們會(huì)經(jīng)常使用到對(duì)話框去承載相應(yīng)的操作。雖然用得多,但是很多人其實(shí)并不知道怎么去寫。饒有興趣,自己嘗試寫了一個(gè)。

前言

項(xiàng)目中,當(dāng)需要用戶處理事務(wù),又不希望跳轉(zhuǎn)頁面以致打斷工作流程時(shí),我們會(huì)經(jīng)常使用到對(duì)話框去承載相應(yīng)的操作。雖然用得多,但是很多人其實(shí)并不知道怎么去寫。饒有興趣,自己嘗試寫了一個(gè)。

API
參數(shù) 說明 類型 默認(rèn)值
afterClose Modal 完全關(guān)閉后的回調(diào) function
cancelText 取消按鈕文字 string 取消
closable 是否顯示右上角的關(guān)閉按鈕 boolean true
destroyOnClose 關(guān)閉時(shí)銷毀 Modal boolean false
footer 底部內(nèi)容,當(dāng)不需要默認(rèn)底部按鈕時(shí),可以設(shè)為 false boolean true
maskClosable 點(diǎn)擊蒙層是否允許關(guān)閉 boolean true
okText 確認(rèn)按鈕文字 string 確定
title 標(biāo)題 string|html節(jié)點(diǎn) 標(biāo)題
width 寬度 number 500
zIndex 設(shè)置 Modal 的 z-index number 1000
keyboard 是否支持鍵盤esc關(guān)閉 boolean true
onCancel 點(diǎn)擊遮罩層或右上角叉或取消按鈕的回調(diào) function(e)
onOk 點(diǎn)擊確定回調(diào) function(e)
methods
參數(shù) 說明 使用形式
set 已覆蓋默認(rèn)的形式,設(shè)置新的屬性,內(nèi)部 Object.assign(this.options, newOptions) model.set(newOptions)
open 打開對(duì)話框 model.open()
close 關(guān)閉對(duì)話框 model.close()
destroy 與close的區(qū)別在于,會(huì)從節(jié)點(diǎn)上刪除 model.destroy()
代碼

對(duì)話框全局中使用一個(gè)就夠了,為了防止生成多個(gè)對(duì)話框,我們使用單例構(gòu)造

var Dialog = (function () {
    var instance;
    return function (options) {
        if (!instance) {
            instance = new Modal(options);
        }
        return instance;
    }
})()

這里主要運(yùn)用到了閉包中的特性

modal.js代碼

var Dialog = (function () {
    var instance;
    return function (options) {
        if (!instance) {
            instance = new Modal(options);
        }
        return instance;
    }
})()

class Modal {
    constructor(options) {
        //默認(rèn)屬性
        this.initOptions = {
            title: "標(biāo)題",
            maskClosable: true,
            header: true,
            footer: true,
            closable: true,
            okText: "確 定",
            cancelText: "取 消",
            destroyOnClose: false,
            keyboard: true,
            zIndex: 1000,
            width: 500,
            afterClose: null
        }
        this.options = Object.assign({}, this.initOptions, options);

        this.instance = document.createElement("div");//節(jié)點(diǎn)實(shí)例,因?yàn)橹恍枰粋€(gè)模態(tài)框,這里設(shè)置節(jié)點(diǎn)就可以了
        this.mounted = false; //是否掛載在節(jié)點(diǎn)上
    }

    //處理模態(tài)框的點(diǎn)擊事件
    _modalClick(e) {
        var className = e.target.className;
        //匹配類名,例如 帶有 class="modal-close" 的元素點(diǎn)擊可以關(guān)閉模態(tài)框
        if (new RegExp("(s|^)modal-close(s|$)").test(className)) {
            this.cancel();   //關(guān)閉模態(tài)框
        } else if (new RegExp("(s|^)modal-onOk(s|$)").test(className)) {
            this.onOk();     //執(zhí)行確定按鈕的回調(diào)
        } else if (new RegExp("(s|^)modal-container(s|$)").test(className)) {
            this.outSideClick(); //模態(tài)框外的點(diǎn)擊
        }
    }

    //處理鍵盤ESC關(guān)閉
    _escClose(e) {
        var code = e.keyCode;
        if (code === 27) {
            this.cancel();
        }
    }

    //渲染模態(tài)框節(jié)點(diǎn)
    render() {
        var modal = this.instance;
        modal.style.zIndex = this.options.zIndex;
        modal.className = "modal-container";
        var closeIcon = this.options.closable ? `X` : "";
        var header = this.options.header ?
            (this.options.header === true ?
                `` :
                this.options.header) :
            "";
        var footer = this.options.footer ?
            (this.options.footer === true ?
                `` :
                this.options.footer) :
            "";
        modal.innerHTML = ``;
    }


    //蒙層點(diǎn)擊關(guān)閉
    outSideClick() {
        if (this.options.maskClosable) {
            this.close();
        }
    }

    //處理監(jiān)聽
    listen() {
        this._modalClick = this._modalClick.bind(this);
        this.instance.addEventListener("click", this._modalClick);
        
        if(this.options.keyboard){
            this._escClose = this._escClose.bind(this);
            window.addEventListener("keyup", this._escClose);
        }
    }

    cancel(){
        if(typeof this.options.onCancel === "function"){
            this.options.onCancel();
        }
        this.close();
    }

    //點(diǎn)擊確定回調(diào)
    onOk() {
        this
            .options
            .onOkFn();
        this.close();
    }


    /****************** 提供的方法  ********************* */
    //設(shè)置屬性
    set(options) {
        Object.assign(this.options, options)
        this.render()
    }

    //打開模態(tài)框
    open() {
        var modal = this.instance;
        //實(shí)例如果沒掛載
        if (!this.mounted) {
            this.mounted = true;
            this.render();
            document.body.appendChild(modal);
            this.listen()
        }
        removeClass(modal, "close");
        addClass(modal, "open");
    }

    //關(guān)閉模態(tài)框
    close() {
        var modal = this.instance
        removeClass(modal, "open");
        addClass(modal, "close");
        if (this.options.destroyOnClose === true) {
            this.destroy();
        }
        if (typeof this.options.afterClose === "function") {
            var afterClose = this.options.afterClose.bind(this);
            setTimeout(afterClose, 0);
        }
    }
    //從節(jié)點(diǎn)上移除模態(tài)框
    destroy() {
        this.instance.removeEventListener("click", this._modalClick);//移除click監(jiān)聽
        window.removeEventListener("keyup", this._escClose);//移除keyup監(jiān)聽
        document.body.removeChild(this.instance);//移除模態(tài)框節(jié)點(diǎn)
        this.mounted = false;
    }

}

function hasClass(elements, cName) {
    return !!elements
        .className
        .match(new RegExp("(s|^)" + cName + "(s|$)"));
};
function addClass(elements, cName) {
    if (!hasClass(elements, cName)) {
        elements.className += " " + cName;
    };
};
function removeClass(elements, cName) {
    if (hasClass(elements, cName)) {
        elements.className = elements
            .className
            .replace(new RegExp("(s|^)" + cName + "(s|$)"), "");
    };
};

modal.css

@keyframes openAnimate {
    0% {
        opacity: 0;
    }
    100%{
        opacity: 1;
    }
}

.open{
    display: block !important;
    animation: openAnimate .8s;
}
.close{
    display: none;
}
.modal-container {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    background-color: #373737;
    background-color: rgba(0,0,0,.65);
    margin: auto;
    filter: alpha(opacity=50);
    text-align: center;
    font-size: 0;
    white-space: nowrap;
    overflow: auto;
    display: none;
}

.modal-container:after {
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}

.modal {
    display: inline-block;
    vertical-align: middle;
    text-align: left;
    font-size: 14px;
    background-color: #fff;
    border: 0;
    border-radius: 4px;
    background-clip: padding-box;
    box-shadow: 0 4px 12px rgba(0,0,0,.15);
}

.modal-header{
    padding: 16px 24px;
    border-radius: 4px 4px 0 0;
    background: #fff;
    color: rgba(0,0,0,.65);
    border-bottom: 1px solid #e8e8e8;
}
.modal-close{
    float: right;
    cursor: pointer;
}
.modal-content{
    padding: 24px;
    font-size: 14px;
    line-height: 1.5;
    word-wrap: break-word;
    min-height: 200px;
}

.modal-footer {
    border-top: 1px solid #e8e8e8;
    padding: 10px 16px;
    text-align: right;
    border-radius: 0 0 4px 4px;
}

.modal-btn{
    line-height: 32px;
    display: inline-block;
    font-weight: 400;
    text-align: center;
    touch-action: manipulation;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    white-space: nowrap;
    padding: 0 15px;
    font-size: 14px;
    border-radius: 4px;
    height: 32px;
    user-select: none;
    transition: all .3s cubic-bezier(.645,.045,.355,1);
    position: relative;
    color: rgba(0,0,0,.65);
    background-color: #fff;
    border-color: #d9d9d9;
    cursor: pointer;
}

.modal-btn-primary{
    color: #fff;
    background-color: #1890ff;
    border-color: #1890ff;
}
如何使用



    
        
        
        
        Document
        
    

    
        
        
        
        
        
    

index.js

var config = {
    title: "模態(tài)框標(biāo)題",
    content: "",
    header: true,
    footer: true,
    destroyOnClose: true,
    onOkFn: function () {
        alert("提交成功")
    },
    afterClose: function(){
        alert("已經(jīng)關(guān)閉")
    }
}
var modal = new Dialog(config);
var openBtns = document.querySelectorAll(".open");
openBtns.forEach(function (item, index) {
    item.onclick = function () {
        var option = {
            content: "這是第" + (index + 1) + "個(gè)"
        }
        modal.set(option)
        modal.open();
    }

})

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95423.html

相關(guān)文章

  • Java基礎(chǔ)學(xué)習(xí)——多線程之單例設(shè)計(jì)模式(轉(zhuǎn))

    摘要:總之,選擇單例模式就是為了避免不一致狀態(tài),避免政出多頭。二餓漢式單例餓漢式單例類在類初始化時(shí),已經(jīng)自行實(shí)例化靜態(tài)工廠方法餓漢式在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用,以后不再改變,所以天生是線程安全的。 概念:  Java中單例模式是一種常見的設(shè)計(jì)模式,單例模式的寫法有好幾種,這里主要介紹兩種:懶漢式單例、餓漢式單例?! 卫J接幸韵绿攸c(diǎn):  1、單例類只能有一個(gè)實(shí)例。 ...

    dendoink 評(píng)論0 收藏0
  • PHP設(shè)計(jì)模式之單例模式

    摘要:簡介單例模式是指整個(gè)應(yīng)用中類只有一個(gè)對(duì)象實(shí)例的設(shè)計(jì)模式。它是一種常見的設(shè)計(jì)模式,在計(jì)算機(jī)系統(tǒng)中,線程池緩存日志對(duì)象對(duì)話框打印機(jī)數(shù)據(jù)庫操作顯卡的驅(qū)動(dòng)程序常被設(shè)計(jì)成單例。 簡介 單例模式是指整個(gè)應(yīng)用中類只有一個(gè)對(duì)象實(shí)例的設(shè)計(jì)模式。它通常被用來創(chuàng)建對(duì)象,確保某個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。 它是一種常見的設(shè)計(jì)模式,在計(jì)算機(jī)系統(tǒng)中,線程池、緩存、日志對(duì)象、對(duì)話框、打...

    OnlyLing 評(píng)論0 收藏0
  • 常用設(shè)計(jì)模式——單例模式

    摘要:一單例模式定義單例模式確保某個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。技術(shù)實(shí)現(xiàn)單例模式靜態(tài)內(nèi)部類評(píng)價(jià)使用靜態(tài)內(nèi)部類的方式,只有在使用該實(shí)例的時(shí)候,才去加載靜態(tài)內(nèi)部類,從而實(shí)現(xiàn)延時(shí)加載。 一、單例模式定義:單例模式確保某個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。在計(jì)算機(jī)系統(tǒng)中,線程池、緩存、日志對(duì)象、對(duì)話框、打印機(jī)、顯卡的驅(qū)動(dòng)程序?qū)ο蟪1辉O(shè)計(jì)成單例。這些應(yīng)...

    stormgens 評(píng)論0 收藏0
  • 面試官:“談?wù)凷pring中都用到了那些設(shè)計(jì)模式?”。

    摘要:會(huì)一直完善下去,歡迎建議和指導(dǎo),同時(shí)也歡迎中用到了那些設(shè)計(jì)模式中用到了那些設(shè)計(jì)模式這兩個(gè)問題,在面試中比較常見。工廠設(shè)計(jì)模式使用工廠模式可以通過或創(chuàng)建對(duì)象。 我自己總結(jié)的Java學(xué)習(xí)的系統(tǒng)知識(shí)點(diǎn)以及面試問題,已經(jīng)開源,目前已經(jīng) 41k+ Star。會(huì)一直完善下去,歡迎建議和指導(dǎo),同時(shí)也歡迎Star: https://github.com/Snailclimb... JDK 中用到了那...

    Astrian 評(píng)論0 收藏0
  • 深入理解單例模式

    摘要:總結(jié)我們主要介紹到了以下幾種方式實(shí)現(xiàn)單例模式餓漢方式線程安全懶漢式非線程安全和關(guān)鍵字線程安全版本懶漢式雙重檢查加鎖版本枚舉方式參考設(shè)計(jì)模式中文版第二版設(shè)計(jì)模式深入理解單例模式我是一個(gè)以架構(gòu)師為年之內(nèi)目標(biāo)的小小白。 初遇設(shè)計(jì)模式在上個(gè)寒假,當(dāng)時(shí)把每個(gè)設(shè)計(jì)模式過了一遍,對(duì)設(shè)計(jì)模式有了一個(gè)最初級(jí)的了解。這個(gè)學(xué)期借了幾本設(shè)計(jì)模式的書籍看,聽了老師的設(shè)計(jì)模式課,對(duì)設(shè)計(jì)模式算是有個(gè)更進(jìn)一步的認(rèn)識(shí)。...

    FuisonDesign 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<