前端弹出对话框 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 相关文章推荐
JS动态调用方法名示例介绍
Dec 18 Javascript
浅谈JavaScript函数节流
Dec 09 Javascript
JavaScript将字符串转换为整数的方法
Apr 14 Javascript
js实现点击向下展开的下拉菜单效果代码
Sep 01 Javascript
Google 地图控件集详解及实例代码
Aug 06 Javascript
AngularJS实现注册表单验证功能
Oct 16 Javascript
JS实现分页浏览横向图片(类轮播)实例代码
Nov 06 Javascript
详解基于vue-cli配置移动端自适应
Jan 13 Javascript
karma+webpack搭建vue单元测试环境的方法示例
May 24 Javascript
vue2.0实现音乐/视频播放进度条组件
Jun 06 Javascript
JavaScript命令模式原理与用法实例详解
Mar 10 Javascript
云服务器部署Node.js项目的方法步骤(小白系列)
Mar 23 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
菜鸟修复电子管记
2021/03/02 无线电
php时间不正确的解决方法
2008/04/09 PHP
PHP实现中国公民身份证号码有效性验证示例代码
2017/05/03 PHP
Laravel框架实现的上传图片到七牛功能详解
2019/09/06 PHP
JS日历 推荐
2006/12/03 Javascript
Javascript 通过json自动生成Dom的代码
2010/04/01 Javascript
设置iframe的document.designMode后仅Firefox中其body.innerHTML为br
2012/02/27 Javascript
深入解析contentWindow, contentDocument
2013/07/04 Javascript
JavaScript中使用concat()方法拼接字符串的教程
2015/06/06 Javascript
JS点击缩略图整屏居中放大图片效果
2017/07/04 Javascript
Nodejs 复制文件/文件夹的方法
2017/08/24 NodeJs
浅谈vue,angular,react数据双向绑定原理分析
2017/11/28 Javascript
vue弹窗消息组件的使用方法
2020/09/24 Javascript
Mint-UI时间组件起始时间问题及时间插件使用
2018/08/20 Javascript
浅谈Angular 观察者模式理解
2018/11/01 Javascript
layUI的验证码功能及校验实例
2019/10/25 Javascript
详解vue-router 动态路由下子页面多页共活的解决方案
2019/12/22 Javascript
pycharm远程调试openstack的图文教程
2017/11/21 Python
详解Python中的正则表达式
2018/07/08 Python
简单了解Django应用app及分布式路由
2019/07/24 Python
意大利奢华内衣制造商:Cosabella
2017/08/29 全球购物
FitFlop美国官网:英国符合人体工学的鞋类品牌
2018/10/05 全球购物
某个公司的Java笔面试题
2016/03/11 面试题
C语言基础笔试题
2013/04/27 面试题
SOA面试题:如何在SOA中实现松耦合
2013/07/21 面试题
计算机专业个人求职自荐信
2013/09/21 职场文书
药学专业大学生个人的自我评价
2013/11/04 职场文书
计算机学生求职信范文
2014/01/30 职场文书
《难忘的泼水节》教学反思
2014/02/27 职场文书
股东协议书范本
2014/04/14 职场文书
涉密人员保密承诺书
2014/05/28 职场文书
日语系毕业求职信
2014/07/27 职场文书
北京颐和园导游词
2015/01/30 职场文书
2015年大班保育员工作总结
2015/05/18 职场文书
初中数学教学随笔
2015/08/15 职场文书
CentOS安装Nginx并部署vue
2022/04/12 Servers