前端彈出對話框 js實現 ajax交互

  本來計劃實現這樣一個需求: 前臺點擊觸發某業務動做,須要用戶補充信息,不作跳轉頁面,彈窗的形式進行補充信息。 折騰出來了,可是最終沒有用到。javascript

  代碼還有些毛躁,提供大概實現邏輯。css

實現思路:  在窗口鋪上蒙板以屏蔽原窗口功能按鈕操做,在蒙板上層絕對定位實現彈窗,彈窗中的數據交互採用ajax方式。 出發彈窗事件用onclick.html

關鍵細節:  彈窗和原窗體本質是同頁面,爲了描述方便,姑且稱底層窗體爲父窗體,彈窗爲子窗體。爲了實現字父窗體的交互,須要在父窗體中作一些特別標籤,以便選擇器選擇,並操做插入新的dom對象。java

 

如此,首先看下父窗體的代碼,關鍵部分我是有註釋的。jquery

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <title>測試彈窗</title>
    
    <script type="text/javascript" src="script/jquery/jquery.js" charset="utf-8"></script>
  
    <script type="text/javascript" src="script/js/outil.js" charset="utf-8"></script>    
    <script charset="utf-8" type="text/javascript" src="script/jquery/jquery.ui.js"></script>    
    <link rel="stylesheet" type="text/css" href="script/jquery/themes/ui-lightness/jquery.ui.css">
    
    <script charset="utf-8" type="text/javascript" src="script/dialog/dialog.js" id="dialog_js"></script>
    <link href="script/dialog/dialog.css" rel="stylesheet" type="text/css">   
    
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
            text-align: center;
            text-decoration: none;
        }
        body{
            font: 12px/1.5 宋體,Tahoma, Arial,sans-serif;
            font-family: "微軟雅黑";
            width:320px;
            height: auto;
            margin:0 auto;
        }
        .content{
            border: #ccc solid 1px;
            margin:60px 10px 10px;
            background:#fff;
            overflow:hidden;
            color:#6b6b6b;
            font-size:14px;
            border-radius:5px;
        }
        
    </style>
    
</head>

<body> 
    <!-- 選擇器是經過ectype="dialog"來進行選擇的 -->
  <div class="content">
      <a href="javascript:void(0);" ectype="dialog" dialog_id="dialog_test" dialog_title="對話測試" dialog_width="300" uri="pop_son.html" >
       對話測試
    </a>
  </div>
   
</body>
</html>

 

接着給出選擇器部分代碼,也就是outil.js的代碼,固然以前的jquery以及jquery ui就不說了。 其核心是綁定click事件。web

 

jQuery.extend({
  getCookie : function(sName) {
    var aCookie = document.cookie.split("; ");
    for (var i=0; i < aCookie.length; i++){
      var aCrumb = aCookie[i].split("=");
      if (sName == aCrumb[0]) return decodeURIComponent(aCrumb[1]);
    }
    return '';
  },
  setCookie : function(sName, sValue, sExpires) {
    var sCookie = sName + "=" + encodeURIComponent(sValue);
    if (sExpires != null) sCookie += "; expires=" + sExpires;
    document.cookie = sCookie;
  },
  removeCookie : function(sName) {
    document.cookie = sName + "=; expires=Fri, 31 Dec 1999 23:59:59 GMT;";
  }
});


$(function(){
    /* dialog 選擇並綁定一個新的click事件 */
    $('*[ectype="dialog"]').click(function(){
        var id = $(this).attr('dialog_id');
        var title = $(this).attr('dialog_title') ? $(this).attr('dialog_title') : '';
        var url = $(this).attr('uri');
        var width = $(this).attr('dialog_width');
        ajax_form(id, title, url, width);
        return false;
    });

});

function drop_confirm(msg, url){
    if(confirm(msg)){
        window.location = url;
    }
}

/* 顯示Ajax表單 */
function ajax_form(id, title, url, width)
{
    if (!width)
    {
        width = 400;
    }
    var d = DialogManager.create(id);
    d.setTitle(title);
    d.setContents('ajax', url);
    d.setWidth(width);
    d.show('center');

    return d;
}

function go(url){
    window.location = url;
}


function set_zindex(parents, index){
    $.each(parents,function(i,n){
        if($(n).css('position') == 'relative'){//alert('relative');
            //alert($(n).css('z-index'));
            $(n).css('z-index',index);
        }
    });
}


function js_success(dialog_id)
{
    DialogManager.close(dialog_id);
    var url = window.location.href;
    url =  url.indexOf('#') > 0 ? url.replace(/#/g, '') : url;
    window.location.replace(url);
}

function js_fail(str)
{
    $('#warning').html('<label class="error">' + str + '</label>');
    $('#warning').show();
}

function check_pint(v)
{
    var regu = /^[0-9]{1,}$/;
    if(!regu.test(v))
    {
        alert(lang.only_int);
        return false;
    }
    return true;
}

/* 轉化JS跳轉中的 & */
function transform_char(str)
{
    if(str.indexOf('&'))
    {
        str = str.replace(/&/g, "%26");
    }
    return str;
}


// 複製到剪貼板
function copyToClipboard(txt) {
    if(window.clipboardData) {
        window.clipboardData.clearData();
        window.clipboardData.setData("Text", txt);
    } else if(navigator.userAgent.indexOf("Opera") != -1) {
        window.location = txt;
    } else if (window.netscape) {
        try {
            netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        } catch (e) {
            return false;
        }
    var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
    if (!clip)
        return false;
    var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
    if (!trans)
        return false;
    trans.addDataFlavor('text/unicode');
    var str = new Object();
    var len = new Object();
    var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
    var copytext = txt;
    str.data = copytext;
    trans.setTransferData("text/unicode",str,copytext.length*2);
    var clipid = Components.interfaces.nsIClipboard;
    if (!clip)
        return false;
    clip.setData(trans,null,clipid.kGlobalClipboard);
    }
}

 

幫定事件的相關代碼就是dialog的核心代碼(dialog.js)了,這個是在網上找到的,在此感謝,代碼以下所示:ajax

 

__DIALOG_WRAPPER__ = {};

/* IE6有個Bug,若是不給定對話框的寬度的話,在IE6下,對話框將以100%寬度顯示 */
DialogManager = {
    'create'        :function(id){
        var d = {};
        if (!__DIALOG_WRAPPER__[id])
        {
            d = new Dialog(id);
            __DIALOG_WRAPPER__[id] = d;
        }
        else
        {
            d = DialogManager.get(id);
        }
        return d;
    },
    'get'           :function(id){
        return __DIALOG_WRAPPER__[id];
    },
    'close'         :function(id){
        if (__DIALOG_WRAPPER__[id].close())
        {
            __DIALOG_WRAPPER__[id] = null;
        }

    },
    'onClose'       :function (){
        return true;
    },
    /* 加載對話框樣式 */
    'loadStyle'     :function(){
        var _dialog_js_path = $('#dialog_js').attr('src');
        var _path    = _dialog_js_path.split('/');
        var _dialog_css = _path.slice(0, _path.length - 1).join('/') + '/dialog.css';
        $('#dialog_js').after('<link href="' + _dialog_css + '" rel="stylesheet" type="text/css" />');
    }
};
ScreenLocker = {
    'style'     : {
        'position'          : 'absolute',
        'top'               : '0px',
        'left'              : '0px',
        'backgroundColor'   : '#000',
        'opacity'           : 0.5,
        'zIndex'            : 999
    },
    'masker'    : null,
    'lock'      : function(zIndex){
        if (this.masker !== null)
        {
            this.masker.width($(document).width()).height($(document).height());

            return true;
        }

        this.masker = $('<div></div>');

        /* IE6 Hack */
        if ($.browser.msie)
        {
            $('select').css('visibility', 'hidden');
        }
        //var _iframe = $('<iframe></iframe>').css({'opacity':0, 'width':'100%', 'height':'100%'});
        //this.masker.append(_iframe);

        /* 樣式 */
        this.masker.css(this.style);

        if (zIndex)
        {
            this.masker.css('zIndex', zIndex);
        }

        /* 整個文檔的寬高 */
        this.masker.width($(document).width()).height($(document).height());

        $(document.body).append(this.masker);
    },
    'unlock'    : function(){
        if (this.masker === null)
        {
            return true;
        }
        this.masker.remove();
        this.masker = null;

        /* IE6 Hack */
        if ($.browser.msie)
        {
            $('select').css('visibility', 'visible');
        }
    }
};

Dialog        = function (id){
    /* 構造函數生成對話框代碼,並加入到文檔中 */
    this.id = id;
    this.init();
};
Dialog.prototype = {
    /* 惟一標識 */
    'id'            : null,
    /* 文檔對象 */
    'dom'           : null,
    'lastPos'       : null,
    'status'        : 'complete',
    'onClose'       : function (){
        return true;
    },
    'tmp'           : {},
    /* 初始化 */
    'init'          : function(){
        this.dom = {'wrapper' : null, 'body':null, 'head':null, 'title':null, 'close_button':null, 'content':null};

        /* 建立外層容器 */
        this.dom.wrapper        = $('<div id="dialog_object_' + this.id + '" class="dialog_wrapper"></div>').get(0);

        /* 建立對話框主體 */
        this.dom.body           = $('<div class="dialog_body"></div>').get(0);

        /* 建立標題欄 */
        this.dom.head           = $('<h3 class="dialog_head"></h3>').get(0);

        /* 建立標題文本 */
        this.dom.title          = $('<span class="dialog_title_icon"></span>').get(0);

        /* 建立關閉按鈕 */
        //this.dom.close_button   = $('<span class="dialog_close_button">close</span>').get(0);

        /* 建立內容區域 */
        this.dom.content        = $('<div class="dialog_content"></div>').get(0);

        /* 組合 */
        $(this.dom.head).append('<div class="dialog_ornament1"></div><div class="dialog_ornament2"></div>').append($('<span class="dialog_title"></span>').append(this.dom.title)).append(this.dom.close_button);
        $(this.dom.body).append(this.dom.head).append(this.dom.content);
        $(this.dom.wrapper).append(this.dom.body).append('<div style="clear:both;display:block;"></div>');

        /* 初始化樣式 */
        $(this.dom.wrapper).css({
            'zIndex'            : 9999,
            'display'           : 'none',
            'position'          : 'absolute'
        });
        $(this.dom.body).css({
            'position'  :   'relative'
        });
        $(this.dom.head).css({
            'cursor'     : 'move'
        });
        $(this.dom.close_button).css({
            'position'   : 'absolute',
            'text-indent': '-9999px',
            'cursor'     : 'pointer',
            'overflow'   : 'hidden'
        });
        $(this.dom.content).css({
            'margin'     : '0px',
            'padding'    : '0px'
        });

        var self = this;

        /* 初始化組件事件 */
        $(this.dom.close_button).click(function(){
            DialogManager.close(self.id);
        });

        /* 可拖放 */
        $(this.dom.wrapper).draggable({
            'handle' : this.dom.head
        });

        /* 放入文檔流 */
        $(document.body).append(this.dom.wrapper);
    },

    /* 隱藏 */
    'hide'          : function(){
        $(this.dom.wrapper).hide();
    },

    /* 顯示 */
    'show'          : function(pos){
        if (pos)
        {
            this.setPosition(pos);
        }

        /* 鎖定屏幕 */
        ScreenLocker.lock(999);

        /* 顯示對話框 */
        $(this.dom.wrapper).show();
    },

    /* 關閉 */
    'close'         : function(){
        if (!this.onClose())
        {
            return false;
        }
        /* 關閉對話框 */
        $(this.dom.wrapper).remove();

        /* 解鎖屏幕 */
        ScreenLocker.unlock();

        return true;
    },

    /* 對話框標題 */
    'setTitle'      : function(title){
        $(this.dom.title).html(title);
    },

    /* 改變對話框內容 */
    'setContents'   : function(type, options){

        contents = this.createContents(type, options);
        if (typeof(contents) == 'string')
        {
            $(this.dom.content).html(contents);
        }
        else
        {
            $(this.dom.content).empty();
            $(this.dom.content).append(contents);
        }
    },

    /* 設置對話框樣式 */
    'setStyle'      : function(style){
        if (typeof(style) == 'object')
        {
            /* 不然爲CSS */
            $(this.dom.wrapper).css(style);
        }
        else
        {
            /* 若是是字符串,則認爲是樣式名 */
            $(this.dom.wrapper).addClass(style);
        }
    },
    'setWidth'      : function(width){
        this.setStyle({'width' : width + 'px'});
    },
    'setHeight'     : function(height){
        this.setStyle({'height' : height + 'px'});
    },

    /* 生成對話框內容 */
    'createContents'  : function(type, options){
        
        var _html = '',
            self  = this,
            status= 'complete';
        if (!options)
        {
            /* 若是隻有一個參數,則認爲其傳遞的是HTML字符串 */
            this.setStatus(status);
            return type;
        }
        switch(type){
            case 'ajax':
                /* 經過Ajax取得HTML,顯示到頁面上,此過程是異步的 */
                $.get(options, {ajax:1}, function(data){
                    if(data.substr(0,1) == '{' && data.substr(data.length - 1, 1) == '}'){
                        var JSON = eval('(' + data + ')');
                        if(!JSON.done){
                           self.setContents(JSON.msg);
                           return;
                        }
                    }
                    self.setContents(data);
                    /* 使用上次定位從新定位窗口位置 */
                    self.setPosition(self.lastPos);
                    
                    //>>addByZZY20160909: 根據後臺返回信息決定該窗口是否展現
                    /* 依據返回內容的前五位,值爲close時候不展現 */
                    if(data.substr(0,5) == 'close'){
                        self.close();
                    }
                });
                /* 先提示正在加載 */
                _html = this.createContents('loading', {'text' : 'loading...'});
            break;
            /* 如下是內置的幾種對話框類型 */
            case 'loading':
                _html = '<div class="dialog_loading"><div class="dialog_loading_text">' + options.text + '</div></div>';
                status = 'loading';
            break;
            case 'message':
                var type = 'notice';
                if (options.type)
                {
                    type = options.type;
                }
                _message_body = $('<div class="dialog_message_body"></div>');
                _message_contents = $('<div class="dialog_message_contents dialog_message_' + type + '">' + options.text + '</div>');
                _buttons_bar = $('<div class="dialog_buttons_bar"></div>');
                switch (type){
                    case 'notice':
                    case 'warning':
                        var button_name = lang.confirm;
                        if (options.button_name)
                        {
                            button_name = options.button_name;
                        }
                        _ok_button = $('<input type="button" class="btn1" value="' + button_name + '" />');
                        $(_ok_button).click(function(){
                            if (options.onclick)
                            {
                                if(!options.onclick.call())
                                {
                                    return;
                                }
                            }
                            DialogManager.close(self.id);
                        });
                        $(_buttons_bar).append(_ok_button);
                    break;
                    case 'confirm':
                        var yes_button_name = lang.yes;
                        var no_button_name = lang.no;
                        if (options.yes_button_name)
                        {
                            yes_button_name = options.yes_button_name;
                        }
                        if (options.no_button_name)
                        {
                            no_button_name = options.no_button_name;
                        }
                        _yes_button = $('<input type="button" class="btn1" value="' + yes_button_name + '" />');
                        _no_button = $('<input type="button" class="btn2" value="' + no_button_name + '" />');
                        $(_yes_button).click(function(){
                            if (options.onClickYes)
                            {
                                if (options.onClickYes.call() === false)
                                {
                                    return;
                                }
                            }
                            DialogManager.close(self.id);
                        });
                        $(_no_button).click(function(){
                            if (options.onClickNo)
                            {
                                if (!options.onClickNo.call())
                                {
                                    return;
                                }
                            }
                            DialogManager.close(self.id);
                        });
                        $(_buttons_bar).append(_yes_button).append(_no_button);
                    break;
                }
                _html = $(_message_body).append(_message_contents).append(_buttons_bar);

            break;
        }
        this.setStatus(status);

        return _html;
    },
    /* 定位 */
    'setPosition'   : function(pos){
        /* 上次定位 */
        this.lastPos = pos;
        if (typeof(pos) == 'string')
        {
            switch(pos){
                case 'center':
                    var left = 0;
                    var top  = 0;
                    var dialog_width    = $(this.dom.wrapper).width();
                    var dialog_height   = $(this.dom.wrapper).height();


                    /* left=滾動條的寬度  + (當前可視區的寬度 - 對話框的寬度 ) / 2 */
                    left = $(window).scrollLeft() + ($(window).width() - dialog_width) / 2;

                    /* top =滾動條的高度  + (當前可視區的高度 - 對話框的高度 ) / 2 */
                    top  = $(window).scrollTop()  + ($(window).height() - dialog_height) / 2;

                    $(this.dom.wrapper).css({left:left + 'px', top:top + 'px'});
                break;
            }
        }
        else
        {
            var _pos = {};
            if (typeof(pos.left) != 'undefined')
            {
                _pos.left = pos.left;
            }
            if (typeof(pos.top)  != 'undefined')
            {
                _pos.top  = pos.top;
            }
            $(this.dom.wrapper).css(_pos);
        }

    },
    /* 設置狀態 */
    'setStatus' : function(code){
        this.status = code;
    },
    /* 獲取狀態 */
    'getStatus' : function(){
        return this.status;
    },
    'disableClose' : function(msg){
        this.tmp['oldOnClose'] = this.onClose;
        this.onClose = function(){
            if(msg)alert(msg);
            return false;
        };
    },
    'enableClose'  : function(){
        this.onClose = this.tmp['oldOnClose'];
        this.tmp['oldOnClose'] = null;
    }
};

//RemoveByZZY20160909: 手動引入樣式文件
//DialogManager.loadStyle();


 

  好了,以上就是核心邏輯及代碼實現,代碼很好的解釋了整個過程,不必浪費文字了。這裏面把子窗體我再貼下。cookie

<style>
    .btn{
        margin:10px 5px;
        width: 100px;
    }
</style>
 <form method="post" action="{$MyAction}" id="popupform">
  <div class="content" style="margin-top:10px;" >    
    <p>
      這裏展現的內容能夠是表單或非表單等內容。
      <input type="hidden" name="ret_url" value="{$ret_url}" /> 
     </p>
     <input type="submit" class="btn" value="完成" />
  </div>
 </form>

 

最後再貼一張效果圖吧。app

相關文章
相關標籤/搜索