angular6 填坑之cdk

技術背景:angular + ant zorrojavascript

最爲大型前端團隊首選的前端技術框架,angular,在國內多少仍是有些水土不服。本人將針對angular作個一系列的填坑分享。css

坑一:cdk前端

angular的cdk不屬於各個模塊,直接掛載在body下面, ant design直接使用cdk,致使任何的彈出層,如select,dropdown,picker等在彈出來的時候自動建立覆蓋全局的cdk,須要點擊cdk才能關閉已打開的下拉。java

明顯須要點擊兩次才能出現一個下拉是產品們不能接受的。架構

解決方案有兩個,一個是修改底層源碼,拋棄cdk,明顯成本巨大,並且bug會層出不窮,考慮不周全,建議缺乏前端架構組的團隊就不用考慮了。框架

本人選擇了另一個方案,有點取巧,可是能快速解決問題。dom

 

步奏一:ide

將cdk縮小至1x1px,讓鼠標能夠點擊網頁中任意地方。this

.cdk-overlay-backdrop {
    width: 1px!important;
    height: 1px!important;
}

步奏二:監聽document點擊事件blog

document.addEventListener('click', (e) => {
    this.prepareHideModal(e);
});

步奏三:獲取當前點擊的select等的惟一標識

使用cdk的組件比較多,有的有惟一標識,沒有的特殊處理

getSign(e) {
        for (const v of e['path']) {
            if (v.tagName == 'NZ-SELECT' || v.tagName == 'APP-SUBJECTPICKER') {
                // 下拉框獲取sign
                if (v.classList[0].includes('ng-tns-')) {
                    this.sign = v.classList[0];
                } else {
                    this.sign = v.classList[1];
                }
                this.signType = 'NZ-NORMAL';
                break;
            } else if (v.tagName == 'NZ-PICKER') {
                // picker 獲取sign
                this.sign = v.classList[0];
                this.signType = 'NZ-PICKER';
                break;
            }
            // popover 獲取sign
            if (v.getAttributeNode && v.getAttributeNode('nz-popover') && v.getAttribute('nz-popover') == '') {
                this.sign = 'NZ-POPOVER';
                this.signType = 'NZ-POPOVER';
                break;
            }
        }
    }

步奏四:關閉已打開的下拉組件

爲何叫prepareHideModal,這是獲取sign前的操做,先關閉再去獲取點擊下拉的sign

getSign方法在關閉後執行

prepareHideModal(e) {
        let doClose = true;
        if (window['globalSignType']) {
            this.hideAllmodal();
            window['globalSignType'] = null;
            return;
        }
        // 若是有sign,關閉已打開的
        if (this.sign) {
            let _sign = this.sign;
            // 判斷某些狀況下不關閉彈框
            if (_sign == 'NZ-POPOVER') {
                // 解決沒有特使標識時點擊cdk自己不消失
                for (const v of e['path']) {
                    if (v.classList && v.classList.contains('cdk-overlay-container')) {
                        doClose = false;
                    }
                }
            } else {
                // 常規有指定sign時點擊選擇器自身時不消失
                for (const v of e['path']) {
                    if (v.classList && v.classList.contains(_sign)) {
                        doClose = false;
                        break;
                    }

                }
            }
            doClose && this.hideModal(_sign);
        }
        this.getSign(e);
    }

步奏五:最重要的關閉cdk,這邊採用了最簡單的,模擬cdk點擊,徹底使用cdk本身的方法

hideModal(sign) {
        let cdkDom = document.querySelectorAll('.cdk-overlay-backdrop.cdk-overlay-dark-backdrop.cdk-overlay-backdrop-showing');
        let domLen = cdkDom.length;
        // 循環cdk,找到它自身的cdk,模擬點擊隱藏
        for (var i = 0; i < domLen; i++) {
            var v = cdkDom[i];
            if (v['style'].display != 'none') {
                v['click']();
                break;
            }
        }
        this.sign = null;
        this.signType = null;
    }

至此算是解決了使用skd組件須要點擊兩次的坑,可是會引發另一個坑,當頁面出現滾動條時,已打開的下來組件位置不會跟着滾動而去改變。這邊會在另一篇博客中解決

相關文章
相關標籤/搜索