bootstrap weebox 支持ajax的模态弹出框


Posted in Javascript onFebruary 23, 2017

本篇介绍的bootstrap weebox(支持ajax的模态弹出框),历经多次修改,目前版本已经稳定,整合了bootstrap的响应式,界面简单,功能却无比丰富,支持ajax、图片预览等等。

bootstrap提供了原生的模态框,但是功能很鸡肋,食之无味弃之可惜,满足不了大众的弹出框需求,其主要缺点是不支持在模态框上弹出新的模态框,这很无趣。为了解决这个痛点,我特地研究了一个叫weebox的插件,这个原生的模态弹出框也不怎么样,使用起来有很多bug,尤其是不支持响应式。为了解决这两个痛点,结合我的项目,特地整理出新的bootstrap weebox弹出框,支持响应式。

一、材料准备

bootstrap weebox

我把源码放在了Git上,方便大家下载。

二、效果图(弹出loading,加载页面,确认后弹出error消息)

bootstrap weebox 支持ajax的模态弹出框
bootstrap weebox 支持ajax的模态弹出框
bootstrap weebox 支持ajax的模态弹出框

三、实例讲解

①、加载资源

<!DOCTYPE html>
<html lang="zh-CN">
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ include file="/components/common/taglib.jsp"%>
<head>
<title>云梦-项目回报设置</title>
<link type="text/css" rel="stylesheet" href="${ctx}/components/weebox/css/weebox.css" rel="external nofollow" />
<script type="text/javascript" src="${ctx}/components/weebox/js/bgiframe.js"></script>
<script type="text/javascript" src="${ctx}/components/weebox/js/weebox.js"></script>
</head>
<body>
<div class="btn-toolbar" role="toolbar">
 <div class="btn-group">
  <a href="${ctx}/deal/initAem/${id}" rel="external nofollow" target="dialog" class="btn btn-primary" focus="type" width="600">
   <span class="icon-plus"></span>
   <span>新增项目回报</span>
  </a>
 </div>
</div>
<script type="text/javascript">
<!--
 $(function() {
  $("a[target=dialog]").ajaxTodialog();
 });
$.fn.extend({
  ajaxTodialog : function() {
  return this.each(function() {
   var $this = $(this);
   $this.click(function(event) {
    var title = $this.attr("title") || $this.text();
    var options = {};
    var w = $this.attr("width");
    var h = $this.attr("height");
    var maxh = $this.attr("maxh");
    if (w)
     options.width = w;
    if (h)
     options.height = h;
    if (maxh)
     options.maxheight = maxh;
    var focus = $this.attr("focus");
    if (focus) {
     options.focus = focus;
    }
    options.title = title;
    options.contentType = "ajax";
    options.showButton = eval($this.attr("showButton") || "false");
    options.showCancel = eval($this.attr("showCancel") || "false");
    options.showOk = eval($this.attr("showOk") || "false");
    options.type = "wee";
    options.onopen = eval($this.attr("onopen") || function() {
    });
    options.boxid = "pop_ajax_dialog";
    var url = unescape($this.attr("href")).replaceTmById($(event.target).parents(".unitBox:first"));
    YUNM.debug(url);
    if (!url.isFinishedTm()) {
     $.showErr($this.attr("warn") || YUNM._msg.alertSelectMsg);
     return false;
    }
    $.weeboxs.open(url, options);
    event.preventDefault();
    return false;
   });
  });
 }});
//-->
</script>
</body>
</html>

你可能眨眼一看,怎么没有相关的弹出框呢,只有个a标签?当然了,如果你使用过dwz或者看过我以前的文章(例如Bootstrap summernote,超级漂亮的富文本编辑器),你可能对a标签打开dialog就不会陌生。

通过$.fn.extend加载一个全局的ajaxTodialog 方法,在页面初始化的时候,为a标签执行该方法。

ajaxTodialog 的关键内容就是获取a标签指定的对话框options,比如title(文中为“新增项目回报”)、href(通过该指定的后台请求地址获得remote的view试图,加载到对话框中,后续介绍)、width(为weebox弹出框设置宽度)、foucs(设置打开时的焦点组件)。

当然还有其他的可选属性,是否展示button等,然后将参数和url传递到weebox的open方法(核心,后续详细介绍)。

②、bootstrap.weebox.js(文件偏大,只介绍部分)

var weeboxs = function() {
  var self = this;
  this._onbox = false;
  this._opening = false;
  this.boxs = new Array();
  this.zIndex = 999;
  this.push = function(box) {
   this.boxs.push(box);
  };
  this.pop = function() {
   if (this.boxs.length > 0) {
    return this.boxs.pop();
   } else {
    return false;
   }
  };
  // 提供给外部的open方法
  this.open = function(content, options) {
   self._opening = true;
   if (typeof (options) == "undefined") {
    options = {};
   }
   if (options.boxid) {
    this.close(options.boxid);
   }
   options.zIndex = this.zIndex;
   this.zIndex += 10;
   var box = new weebox(content, options);
   box.dh.click(function() {
    self._onbox = true;
   });
   this.push(box);
   return box;
  };
  // 提供给外部的close方法
  this.close = function(id) {
   if (id) {
    for (var i = 0; i < this.boxs.length; i++) {
     if (this.boxs[i].dh.attr('id') == id) {
      this.boxs[i].close();
      this.boxs.splice(i, 1);
     }
    }
   } else {
    this.pop().close();
   }
  };
  this.length = function() {
   return this.boxs.length;
  };
  this.getTopBox = function() {
   return this.boxs[this.boxs.length - 1];
  };
  this.find = function(selector) {
   return this.getTopBox().dh.find(selector);
  };
  this.setTitle = function(title) {
   this.getTopBox().setTitle(title);
  };
  this.getTitle = function() {
   return this.getTopBox().getTitle();
  };
  this.setContent = function(content) {
   this.getTopBox().setContent(content);
  };
  this.getContent = function() {
   return this.getTopBox().getContent();
  };
  this.hideButton = function(btname) {
   this.getTopBox().hideButton(btname);
  };
  this.showButton = function(btname) {
   this.getTopBox().showButton(btname);
  };
  this.setButtonTitle = function(btname, title) {
   this.getTopBox().setButtonTitle(btname, title);
  };
  $(window).scroll(function() {
   if (self.length() > 0) {
    var box = self.getTopBox();
    if (box.options.position == "center") {
     box.setCenterPosition();
    }
   }
  }).bind("resize", function() {
   // 窗口在resize能够使窗口重新居中,模态层的高度和宽度为当前document的大小
   if (self.length() > 0) {
    // 居中
    var box = self.getTopBox();
    if (box.options.position == "center") {
     box.setCenterPosition();
    }
    if (box.mh) {
     // 模态层先隐藏,使document的高度和宽度得到变化
     box.mh.hide();
     // 设置模态层新的大小
     box.mh.css({
      width : box.bwidth(),
      height : box.bheight(),
     });
     // 展示模态层
     box.mh.show();
    }
   }
  });
  $(document).click(function() {
   if (self.length() > 0) {
    var box = self.getTopBox();
    if (!self._opening && !self._onbox && box.options.clickClose) {
     box.close();
    }
   }
   self._opening = false;
   self._onbox = false;
  });
 };
 $.extend({
  weeboxs : new weeboxs()
 });

这段代码我们可以看得到,页面加载时就会初始化weebox的基础参数、方法。

通过提供open方法,外部可以将基础的参数options还有url传递到weebox对象中。

紧接着,weebox通过new weebox(content, options)创建weebox对象,稍候介绍。

然后呢,为了能够产生响应式,weebox绑定了窗口的resize、scroll,这两个方法很关键,resize是为了窗口在缩放过程中,弹出框的模态层、弹出框能够重新绘制大小和居中,scroll为了弹出矿口始终处于window窗口的中心位置(setCenterPosition,稍候介绍)。

1.setCenterPosition 方法

// 居中
this.setCenterPosition = function() {
 var wnd = $(window), doc = $(document);
 // 大小不能超过窗口大小,很关键哦
 var iContentW = wnd.width() - 40;
 var iContentH = self.options.maxheight || wnd.height() - 100 * 2 - 40;
 self.dc.css({
  "max-height" : iContentH + 'px',
  "max-width" : iContentW + 'px',
 });
 self.dheader.css({
  "max-width" : iContentW + 'px',
 });
 self.df.css({
  "max-width" : iContentW + 'px',
 });
 // 设置top和left,使窗口居中
 self.dh.css({
  top : (wnd.height() - self.dh.height()) / 2 + doc.scrollTop(),
  left : (wnd.width() - self.dh.width()) / 2 + doc.scrollLeft()
 });
};

2.initContent 方法,加载窗口内容

// 加载内容
this.initContent = function(content) {
 // ok button的名字
 self.bo.val(self.options.okBtnName);
 // cancel button的名字
 self.bc.val(self.options.cancelBtnName);
 // 窗口标题
 self.setTitle(self.options.title);
 if (!self.options.showTitle) {
  self.dheader.hide();
 }
 if (!self.options.showButton) {
  self.df.hide();
 }
 if (!self.options.showCancel) {
  self.bc.hide();
 }
 if (!self.options.showOk) {
  self.bo.hide();
 }
 if (self.options.contentType == "selector") {
  self.selector = self._content;
  self._content = $(self.selector).html();
  self.setContent(self._content);
  // if have checkbox do
  var cs = $(self.selector).find(':checkbox');
  self.dc.find(':checkbox').each(function(i) {
   this.checked = cs[i].checked;
  });
  $(self.selector).empty();
  self.onopen();
  self.show();
  self.focus();
 } else if (self.options.contentType == "ajax") {// content为ajax时,能够将view视图加载到弹出窗口中
  self.ajaxurl = self._content;
  // loading
  self.setContent('<div class="well well-large well-transparent lead"> <i class="icon-spinner icon-spin icon-2x pull-left"></i> 内容加载中... </div>');
  self.show();
  $.ajax({
   type : "post",
   cache : false,
   url : self.ajaxurl,
   success : function(data) {
    // 处理view视图数据
    var json = YUNM.jsonEval(data);
    // 出现error时,关闭当前窗口,弹出错误消息
    if (json[YUNM.keys.statusCode] == YUNM.statusCode.error) {
     self.close();
     $.showErr(json[YUNM.keys.message]);
    } else {
     // 正常情况下,显示内容
     self._content = data;
     self.setContent(self._content);
     // 设置打开事件
     self.onopen();
     // 设置焦点
     self.focus();
     // 居中显示
     if (self.options.position == 'center') {
      self.setCenterPosition();
     }
    }
   },
   // 通过弹出的对话框显示错误信息
   error : function(xhr, ajaxOptions, thrownError) {
    self.close();
    YUNM.ajaxError(xhr, ajaxOptions, thrownError);
   }
  });
 } else if (self.options.contentType == "image") {// image类型时,弹出图片
  self.setContent('<img src=' + self._content + ' ></div>');
  self.onopen();
  self.show();
  self.focus();
 } else {
  self.setContent(self._content);
  self.onopen();
  self.show();
  self.focus();
 }
};

3.initMask ,加载模态层

// 加载模态层
this.initMask = function() {
 if (self.options.modal) {
  self.mh = $("<div class='dialog-mask'></div>").appendTo('body').hide().css({
   opacity : self.options.overlay / 100,
   filter : 'alpha(opacity=' + self.options.overlay + ')',
   width : self.bwidth(),
   height : self.bheight(),
   zIndex : self.options.zIndex - 1
  });
 }
};

以上提供的这部分代码很关键,无论你使用何种模态弹出框,其核心方法无非上述列出的内容,当然了,文章开头也说了,你可以通过git下载完整的源码。希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
改变隐藏的input中value值的方法
Mar 19 Javascript
jquery获取节点名称
Apr 26 Javascript
在JavaScript中处理时间之getHours()方法的使用
Jun 10 Javascript
JS实现带圆弧背景渐变效果的导航菜单代码
Oct 13 Javascript
使用bootstrap typeahead插件实现输入框自动补全之问题及解决办法
Jul 07 Javascript
浅谈vue,angular,react数据双向绑定原理分析
Nov 28 Javascript
JavaScript中 ES6变量的结构赋值
Jul 10 Javascript
vue返回上一页面时回到原先滚动的位置的方法
Dec 20 Javascript
可能被忽略的一些JavaScript数组方法细节
Feb 28 Javascript
layUI实现前端分页和后端分页
Jul 27 Javascript
vue实现评价星星功能
Jun 30 Javascript
vue组件中传值EventBus的使用及注意事项说明
Nov 16 Javascript
COM组件中调用JavaScript函数详解及实例
Feb 23 #Javascript
Bootstrap3 多个模态对话框无法显示的解决方案
Feb 23 #Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
Feb 23 #Javascript
JS实现的五级联动菜单效果完整实例
Feb 23 #Javascript
jquery实现焦点轮播效果
Feb 23 #Javascript
SVG描边动画
Feb 23 #Javascript
Angular JS 生成动态二维码的方法
Feb 23 #Javascript
You might like
如何解决CI框架的Disallowed Key Characters错误提示
2013/07/05 PHP
CI(CodeIgniter)框架中的增删改查操作
2014/06/10 PHP
全面解读PHP的人气开发框架Laravel
2015/10/15 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
PHP小程序支付功能完整版【基于thinkPHP】
2019/03/26 PHP
PHP过滤器 filter_has_var() 函数用法实例分析
2020/04/23 PHP
JQuery 技巧和窍门整理(8个)
2010/04/22 Javascript
jquery如何实现锚点链接之间的平滑滚动
2013/12/02 Javascript
DEDECMS如何为文章添加HOT NEW标志图片
2015/08/14 Javascript
JS面向对象编程详解
2016/03/06 Javascript
JS实现点击登录弹出窗口同时背景色渐变动画效果
2016/03/25 Javascript
jQuery实现图片向左向右切换效果的简单实例
2016/05/18 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
vue elementui 实现搜索栏公共组件封装的实例代码
2020/01/20 Javascript
Vue组件化开发之通用型弹出框的实现
2020/02/28 Javascript
[01:19:34]2014 DOTA2国际邀请赛中国区预选赛 New Element VS Dream time
2014/05/22 DOTA
[01:14:55]EG vs Spirit Supermajor 败者组 BO3 第三场 6.4
2018/06/05 DOTA
在Python的Django框架中更新数据库数据的方法
2015/07/17 Python
python 爬取微信文章
2016/01/30 Python
在Python中定义和使用抽象类的方法
2016/06/30 Python
pycharm debug功能实现跳到循环末尾的方法
2018/11/29 Python
在python中pandas读文件,有中文字符的方法
2018/12/12 Python
Scrapy-Redis结合POST请求获取数据的方法示例
2019/05/07 Python
Python Pandas中根据列的值选取多行数据
2019/07/08 Python
python对绑定事件的鼠标、按键的判断实例
2019/07/17 Python
Python获取时间戳代码实例
2019/09/24 Python
深入浅析Python 函数注解与匿名函数
2020/02/24 Python
Pycharm创建python文件自动添加日期作者等信息(步骤详解)
2021/02/03 Python
阿玛尼化妆品美国官网:Giorgio Armani Beauty
2017/02/02 全球购物
广告设计专业自荐信范文
2013/11/14 职场文书
读书伴我成长演讲稿
2014/05/07 职场文书
2014年销售助理工作总结
2014/12/01 职场文书
装修公司管理制度
2015/08/05 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
2021/05/05 Golang
MySQL COUNT函数的使用与优化
2021/05/10 MySQL