zoukankan      html  css  js  c++  java
  • 前端弹出对话框 js实现 ajax交互

      原本计划实现这样一个需求: 前台点击触发某业务动作,需要用户补充信息,不做跳转页面,弹窗的形式进行补充信息。 折腾出来了,但是最终没有用到。

      代码还有些毛躁,提供大概实现逻辑。

    实现思路:  在窗口铺上蒙板以屏蔽原窗口功能按钮操作,在蒙板上层绝对定位实现弹窗,弹窗中的数据交互采用ajax方式。 出发弹窗事件用onclick.

    关键细节:  弹窗和原窗体本质是同页面,为了描述方便,姑且称底层窗体为父窗体,弹窗为子窗体。为了实现字父窗体的交互,需要在父窗体中做一些特别标签,以便选择器选择,并操作插入新的dom对象。

    如此,首先看下父窗体的代码,关键部分我是有注释的。

    <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事件。

     

    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)了,这个是在网上找到的,在此感谢,代码如下所示:

     

    __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();


      好了,以上就是核心逻辑及代码实现,代码很好的解释了整个过程,没必要浪费文字了。这里面把子窗体我再贴下。

    <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>

    最后再贴一张效果图吧。

      

  • 相关阅读:
    模板元编程实现素数判定
    JDBC开发
    4.9 当相应行存在时更新
    QT5中如何使用QFtp类(这个类虽然没有被收录,但一直在更新)
    gcc和g++的区别
    Awesome C/C++(图像部分)
    Ubuntu更新源
    GO的GDB调试
    内核探测工具systemtap简介
    列举一下项目中使用的产品和技术
  • 原文地址:https://www.cnblogs.com/wildfox/p/5852998.html
Copyright © 2011-2022 走看看