前端弹出对话框 js实现ajax交互


Posted in Javascript onSeptember 09, 2016

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

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

实现思路:在窗口铺上蒙板以屏蔽原窗口功能按钮操作,在蒙板上层绝对定位实现弹窗,弹窗中的数据交互采用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>

最后再贴一张效果图吧。

前端弹出对话框 js实现ajax交互

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript入门教程(11) js事件处理
Jan 31 Javascript
jQuery学习总结之jQuery事件
Jun 30 Javascript
分享jQuery插件的学习笔记
Jan 14 Javascript
Bootstrap入门书籍之(四)菜单、按钮及导航
Feb 17 Javascript
深入理解jQuery()方法的构建原理
Dec 05 Javascript
AngularJS入门教程之Helloworld示例
Dec 25 Javascript
jQuery中 DOM节点操作方法大全
Oct 12 jQuery
javascript浏览器用户代理检测脚本实现方法
Oct 27 Javascript
vue初尝试--项目结构(推荐)
Jan 30 Javascript
JS获取动态添加元素的方法详解
Jul 31 Javascript
24个解决实际问题的ES6代码片段(小结)
Feb 02 Javascript
关于uniApp editor微信滑动问题
Jan 15 Javascript
Boostrap基础教程之JavaScript插件篇
Sep 08 #Javascript
jQuery实现邮箱下拉列表自动补全功能
Sep 08 #Javascript
JS图片放大效果简单实现代码
Sep 08 #Javascript
Angularjs 实现一个幻灯片示例代码
Sep 08 #Javascript
利用Vue.js指令实现全选功能
Sep 08 #Javascript
AngularJS 实现JavaScript 动画效果详解
Sep 08 #Javascript
javascript使用 concat 方法对数组进行合并的方法
Sep 08 #Javascript
You might like
php adodb连接带密码access数据库实例,测试成功
2008/05/14 PHP
PHP 导出数据到淘宝助手CSV的方法分享
2010/02/27 PHP
thinkPHP5使用Rabc实现权限管理
2019/08/28 PHP
PHP利用curl发送HTTP请求的实例代码
2020/07/09 PHP
jquery uaMatch源代码
2011/02/14 Javascript
正负小数点后两位浮点数实现原理及代码
2013/09/06 Javascript
JavaScript去除数组里重复值的方法
2015/07/13 Javascript
AngularJS向后端ASP.NET API控制器上传文件
2016/02/03 Javascript
picLazyLoad 实现图片延时加载(包含背景图片)
2016/07/21 Javascript
JS根据生日月份和日期计算星座的简单实现方法
2016/11/24 Javascript
JS实现的找零张数最小问题示例
2017/11/28 Javascript
React 组件间的通信示例
2018/06/14 Javascript
解决vue A对象赋值给B对象,修改B属性会影响到A的问题
2018/09/25 Javascript
一文看懂如何简单实现节流函数和防抖函数
2019/09/05 Javascript
JavaScript的一些小技巧分享
2021/01/06 Javascript
在CentOS上配置Nginx+Gunicorn+Python+Flask环境的教程
2016/06/07 Python
python 列表删除所有指定元素的方法
2018/04/19 Python
Flask-Mail用法实例分析
2018/07/21 Python
python设置代理和添加镜像源的方法
2020/02/14 Python
django ORM之values和annotate使用详解
2020/05/19 Python
Python读取yaml文件的详细教程
2020/07/21 Python
python使用建议与技巧分享(二)
2020/08/17 Python
关于Python 解决Python3.9 pandas.read_excel(‘xxx.xlsx‘)报错的问题
2020/11/28 Python
HTML5中Localstorage的使用教程
2015/07/09 HTML / CSS
澳大利亚男士西服品牌:M.J.Bale
2018/02/06 全球购物
英国品牌男装折扣网站:Brown Bag
2018/03/08 全球购物
荷兰美妆护肤品海淘网站:Beautinow(中文)
2020/11/22 全球购物
学院书画协会部门职责
2013/11/28 职场文书
给分销商的致歉信
2014/01/14 职场文书
二年级语文教学反思
2014/02/02 职场文书
水利公司纪检监察自我鉴定
2014/02/25 职场文书
药店采购员岗位职责
2014/09/30 职场文书
二手车交易协议书标准版
2014/11/16 职场文书
Java9新特性对HTTP2协议支持与非阻塞HTTP API
2022/03/16 Java/Android
mysql中DCL常用的用户和权限控制
2022/03/31 MySQL
我家女友可不止可爱呢 公开OP主题曲无字幕动画MV
2022/04/11 日漫