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 相关文章推荐
图片上传即时显示缩略图的js代码
May 27 Javascript
jquery mobile的触控点击事件会多次触发问题的解决方法
May 08 Javascript
一个css与js结合的下拉菜单支持主流浏览器
Oct 08 Javascript
javascript面向对象之共享成员属性与方法及prototype关键字用法
Jan 13 Javascript
jquery validate和jquery form 插件组合实现验证表单后AJAX提交
Aug 26 Javascript
使用JS正则表达式 替换括号,尖括号等
Nov 29 Javascript
浅谈js中几种实用的跨域方法原理详解
Dec 02 Javascript
微信小程序开发之相册选择和拍照详解及实例代码
Feb 22 Javascript
JavaScript数组push方法使用注意事项
Oct 30 Javascript
vue中的$emit 与$on父子组件与兄弟组件的之间通信方式
May 13 Javascript
JS document内容及样式操作完整示例
Jan 14 Javascript
JS实现放烟花效果
Mar 10 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
PHP数组无限分级数据的层级化处理代码
2012/12/29 PHP
ThinkPHP标签制作教程
2014/07/10 PHP
Yii数据读取与跳转参数传递用法实例分析
2016/07/12 PHP
模仿百度三维地图的js数据分享
2011/05/12 Javascript
seajs1.3.0源码解析之module依赖有序加载
2012/11/07 Javascript
jQuery学习笔记(3)--用jquery(插件)实现多选项卡功能
2013/04/08 Javascript
返回页面顶部top按钮通过锚点实现(自写)
2013/08/30 Javascript
JavaScript实现的一个计算数字步数的算法分享
2014/12/06 Javascript
JS事件添加和移出的兼容写法示例
2016/06/20 Javascript
BootStrap入门教程(一)之可视化布局
2016/09/19 Javascript
浅谈js中几种实用的跨域方法原理详解
2016/12/02 Javascript
jQuery点击头像上传并预览图片
2017/02/23 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
2017/04/26 Javascript
微信小程序之网络请求简单封装实例详解
2017/06/28 Javascript
vue router2.0二级路由的简单使用
2017/07/05 Javascript
JS实现上传图片的三种方法并实现预览图片功能
2017/07/14 Javascript
Angular实现响应式表单
2017/08/04 Javascript
React中使用async validator进行表单验证的实例代码
2018/08/17 Javascript
vue界面发送表情的实现代码
2020/09/11 Javascript
Selenium执行JavaScript脚本的方法示例
2020/12/31 Javascript
[45:06]完美世界DOTA2联赛PWL S2 Magma vs InkIce 第二场 11.28
2020/12/02 DOTA
Python基于百度云文字识别API
2018/12/13 Python
python面向对象实现名片管理系统文件版
2019/04/26 Python
python 实现list或string按指定分段
2019/12/25 Python
Windows下实现将Pascal VOC转化为TFRecords
2020/02/17 Python
Python实现Appium端口检测与释放的实现
2020/12/31 Python
捷克街头、运动和滑板一站式商店:BoardStar.cz
2019/10/06 全球购物
T3官网:头发造型工具
2019/12/26 全球购物
澳大利亚有机化妆品网上商店:The Well Store
2020/02/20 全球购物
Java中的类包括什么内容?设计时要注意哪些方面
2012/05/23 面试题
自我反省检讨书
2014/01/23 职场文书
项目经理任命书
2014/06/04 职场文书
环保公益策划方案
2014/08/15 职场文书
服装店员工管理制度
2015/08/07 职场文书
小学生教师节广播稿
2015/08/19 职场文书
纯CSS3实现div按照顺序出入效果
2021/07/15 HTML / CSS