dialog组件

/**
 * @description Mask 弹层
 * @function
 * @name Mask
 * @param {Object} options 配置项
 */

var passport = passport || {}

passport.page = passport.page || {};




/**
 * @description 获取页面宽度
 * @name passport.page.getWidth
 * @function
 * @grammar passport.page.getWidth()
 * @return {number} 页面宽度
 */
passport.page.getWidth = function () {
    var doc = document,
        body = doc.body,
        html = doc.documentElement,
        client = doc.compatMode == 'BackCompat' ? body : doc.documentElement;

    return Math.max(html.scrollWidth, body.scrollWidth, client.clientWidth);
};


/**
 * @description 获取页面高度
 * @name passport.page.getHeight
 * @function
 * @grammar passport.page.getHeight()
 *             
 * @return {number} 页面高度
 */
passport.page.getHeight = function () {
    var doc = document,
        body = doc.body,
        html = doc.documentElement,
        client = doc.compatMode == 'BackCompat' ? body : doc.documentElement;

    return Math.max(html.scrollHeight, body.scrollHeight, client.clientHeight);
};


/**
 * @description 获取页面视觉区域宽度
 * @name passport.page.getViewWidth
 * @function
 * @grammar passport.page.getViewWidth()
 *             
 * @return {number} 页面视觉区域宽度
 */
passport.page.getViewWidth = function () {
    var doc = document,
        client = doc.compatMode == 'BackCompat' ? doc.body : doc.documentElement;

    return client.clientWidth;
};


/**
 * @description 获取页面视觉区域高度
 * @name passport.page.getViewHeight
 * @function
 * @grammar passport.page.getViewHeight()
 * @return {number} 页面视觉区域高度
 */
passport.page.getViewHeight = function () {
    var doc = document,
        client = doc.compatMode == 'BackCompat' ? doc.body : doc.documentElement;

    return client.clientHeight;
};


/**
 * @description 获取纵向滚动量
 * @name passport.page.getScrollTop
 * @function
 * @grammar passport.page.getScrollTop()
 * @return {number} 纵向滚动量
 */
passport.page.getScrollTop = function () {
    var d = document;
    return window.pageYOffset || d.documentElement.scrollTop || d.body.scrollTop;
};


/*
 * @description 获取横向滚动量
 * 
 * @return {number} 横向滚动量
 */
passport.page.getScrollLeft = function () {
    var d = document;
    return window.pageXOffset || d.documentElement.scrollLeft || d.body.scrollLeft;
};



function Mask(options){
    var me = this,
        ua = navigator.userAgent,
        maskHtml = me.toHTMLString(),
        sf = /(d+.d)?(?:.d)?s+safari/?(d+.d+)?/i.test(ua) && !/chrome/i.test(ua) ? + (RegExp['x241'] || RegExp['x242']) : undefined,
        ie = /msie (d+.d+)/i.test(ua) ? (document.documentMode || + RegExp['x241']) : undefined;

    me.zIndex = 999;
    me.opacity = 0.3;
    me.bgColor = "#000000";
    me.coverable = false;
    me.container = document.body;

    

   insertHTML.call(me.container,"afterBegin", maskHtml)

   me.maskDom = document.getElementById('PASSP__DIA__Mask');


    
    if(ie == 6){
        me.maskDom.style.position = "absolute";
    }

    function insertHTML( position, html) {
        var range,begin,element = this;
     
        //在opera中insertAdjacentHTML方法实现不标准,如果DOMNodeInserted方法被监听则无法一次插入多element
        if (element.insertAdjacentHTML) {
            element.insertAdjacentHTML(position, html);
        } else {
            // 这里不做"undefined" != typeof(HTMLElement) && !window.opera判断,其它浏览器将出错?!
            // 但是其实做了判断,其它浏览器下等于这个函数就不能执行了
            range = element.ownerDocument.createRange();
            // FF下range的位置设置错误可能导致创建出来的fragment在插入dom树之后html结构乱掉
            // 改用range.insertNode来插入html, by wenyuxiang @ 2010-12-14.
            position = position.toUpperCase();
            if (position == 'AFTERBEGIN' || position == 'BEFOREEND') {
                range.selectNodeContents(element);
                range.collapse(position == 'AFTERBEGIN');
            } else {
                begin = position == 'BEFOREBEGIN';
                range[begin ? 'setStartBefore' : 'setEndAfter'](element);
                range.collapse(begin);
            }
            range.insertNode(range.createContextualFragment(html));
        }
        return element;
    }
    
    
    function resize(){
        if (me.container == document.body) {
            var ls = me.maskDom.style;

            ls.width = passport.page.getViewWidth() + 'px';

            ls.height = passport.page.getViewHeight() + 'px';

            ls.display = "";
        }
    }
    
    
    function scroll(){
        if (me.container == document.body) {
            var ls = me.maskDom.style;
            ls.display = "none";
            ls.top = passport.page.getScrollTop()  + "px";
            ls.left = passport.page.getScrollLeft() + "px";
            ls.display = "";
        }
    }

    
    function showObjects(bool){
        var objects = document.getElementsByTagName("object");
        var v = bool ? "visible" : "hidden";
        for(var i = 0, o, l = objects.length; i < l; i ++){
            o = objects[i];
            o.style.visibility = v;
        }
    }



    Mask.prototype.show = function(){
        var me = this;
        resize();
        ie == 6 && scroll();
        $(window).on("resize", resize);
        ie == 6 && $(window).on("scroll", scroll);

        var es = me.maskDom.style;
        es.opacity = me.opacity;
        es.zIndex = me.zIndex;
        es.filter = "alpha(opacity=" + me.opacity * 100 + ")";
        es.backgroundColor = me.bgColor;

        es.display = '';

        sf && showObjects(false); 
    }

    Mask.prototype.hide = function(){
        var es = me.maskDom.style;
        es.display = 'none';
        $(window).off("resize", resize);
        ie == 6 && $(window).off("scroll", scroll);
        sf && showObjects(true); 
    }


}

Mask.prototype.toHTMLString = function(){
    return "<div id='PASSP__DIA__Mask' style='top:0px; left:0px; position:fixed; display:none;'>"
        +("<iframe frameborder='0' style='"
        +"filter:progid:DXImageTransform.Microsoft.Alpha(opacity:0);"
        +"position:absolute;top:0px;left:0px;100%;height:100%;z-index:-1' "
        +"src='" + (window.location.protocol.toLowerCase() == "https:" ? "https://passport.passport.com/passApi/html/_blank.html" : "about:blank") + "'></iframe><div style='position:absolute;top:0px;left:0px;100%;height:100%;z-index:-1;'> </div>") +"</div>";
}


/**
 * @description Dialog 弹层
 * @class
 * @name Dialog
 * @param {Object} options 配置项
 * @param {Number} options.width 弹层宽度
 * @param {Number} options.height 弹层高度
 * @param {Boolean} options.mask 是否需要遮罩层
 * @param {String} options.titleText 标题
 */


function Dialog(options){
    this.options = options;
    this._width = this.options.width || "auto";
    this._height = this.options.height || "auto";
    this.dom = this.options.dom;
    this._mask = this.options.mask || true;
    this._titleText = this.options.title;
    this._closeBtn = this.options.closeBtn || true,
    this._eventMng = [];
    this.onRender = this.options.onRender || function(){};
    this._num = 'PASSP__DIA__'+Math.floor(Math.random() * 2147483648).toString(36).toUpperCase()+'_';
    this.init()
}

Dialog.renderMask = function(){
    var me = this;
    if(this._mask) return this;
    this._mask = new Mask()
}


Dialog._createElement = function(id){
    var el = document.createElement('div');
    el.id = id;
    return el
}


Dialog.prototype.setWidth = function(width){
    this.el.style.width = width + 'px' 
}

Dialog.prototype.setHeight = function(height){
    this.el.style.width = height + 'px'

}


Dialog.prototype.setSize = function(size){
    this.setWidth(size.width || size[0])
    this.setHeight(size.height || size[1])
}


Dialog.prototype.setPosition = function(pos){
    if(this.el.style.position == "static"){
        this.el.style.position = 'absolute'
    }

    if(typeof pos.left == "number")
        this.el.style.left = pos.left + 'px' 
    if(typeof pos.top == "number")
        this.el.style.top = pos.top + 'px'
}



Dialog.prototype.show = function(){
    if(this.options.beforeShow && this.options.beforeShow() === false)
        return this;
    this._mask && Dialog._mask.show();
    this.el.style.display = "block";
    this.dom.style.display = 'block';
    this._isShown = true;

     
}

Dialog.prototype.hide = function(){
    if(this.options.beforeHide && this.options.beforeHide() === false)
        return this;
    this._mask && Dialog._mask.hide();
    this.el.style.display = "none";
    this._isShown = false;
}




Dialog.prototype.center = function(){
    var bodyWidth = passport.page.getViewWidth();
    var bodyHeight = passport.page.getViewHeight();
    var left = (((bodyWidth - (this._width || this.el.offsetWidth)) / 2) | 0) + passport.page.getScrollLeft();
    var top = (((bodyHeight - (this._height || this.el.offsetHeight)) / 2) | 0) + passport.page.getScrollTop();
    this.setPosition({left: left,top: top });
}







Dialog.prototype.init = function(){

    this._createContainer()

    if(this._mask){
        Dialog.renderMask()
    }

    if(this._titleText){
        this._createTitle()
    }

    this._createBody();

    this.show();

    this._bind();
}


Dialog.prototype._createContainer = function(){
    this.el = Dialog._createElement(this._num + 'Container');
    this.el.className = 'pass-dialog-container';
    this.el.style.zIndex = this.zIndex || 1000;
    if(this._width){
        this.el.style.width = this._width + 'px';
    }
    if(this._height){
        this.el.style.height = this._height + 'px';
    }
    
}

Dialog.prototype._createTitle = function(){
    var tit = Dialog._createElement(this._num + 'Title');
    tit.className = 'pass-dialog-title';
    var titleText = '<span class="pass-dialog-titText" id="'+this._num + 'titleText">'+this._titleText+'</span>'
    tit.appendChild($(titleText).get(0))
    this.el.appendChild(tit)
    if(this._closeBtn){
        var closeBtn = '<span class="pass-dialog-close" id="'+this._num + 'close">X</span>'
        tit.appendChild($(closeBtn).get(0))
    }

}

/*Dialog.prototype._createMask = function(){
    //var height = Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
    var mask = document.createElement('div'),
        height = Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);
    mask.id = 'PASSP__DIAMASK__'+this._num;
    mask.className = 'pass-dialog-mask';
    mask.style.height = height + 'px';
    this.el.appendChild(mask)
    //$('body').append(this.maskDom)
    //this.maskDom.height(height);
}*/


Dialog.prototype._createBody = function(){
    var body = Dialog._createElement(this._num + 'Body')
    
    body.appendChild(this.dom)

    this.el.appendChild(body)
    
    document.body.appendChild(this.el)
}



Dialog.prototype.addEvent = function(el, event, handler){
    el.on(event, handler);
    this._eventMng.push({
        el: el,
        event: event,
        handler: handler
    });
};


Dialog.prototype._bind = function(){
    var me = this;
    me.action = {
        'close' : function(evt){
            me.hide();
            evt.preventDefault()
        }
    }
    me.addEvent($("#"+me._num + 'close'),'click',me.action['close'])
}


Dialog.prototype.destroy = function(){
    for(var i = 0 , j = this._eventMng.length; i < j; i++){
        var e = this._eventMng[i];
        e.el.off(e.event, e.handler);
    }
    $(el).remove()
}

  

原文地址:https://www.cnblogs.com/xiaohui108/p/4095016.html