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 相关文章推荐
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
Apr 12 Javascript
兼容IE和Firefox的javascript获取iframe文档内容的函数
Aug 15 Javascript
javascript中对Attr(dom中属性)的操作示例讲解
Dec 02 Javascript
在HTML中插入JavaScript代码的示例
Jun 03 Javascript
分享Javascript实用方法二
Dec 13 Javascript
超实用的JavaScript表单代码段
Feb 26 Javascript
jQuery ajax 当async为false时解决同步操作失败的问题
Nov 18 Javascript
微信小程序 Nginx环境配置详细介绍
Feb 14 Javascript
H5图片压缩与上传实例
Apr 21 Javascript
使用vue-resource进行数据交互的实例
Sep 02 Javascript
vue中的mvvm模式讲解
Jan 31 Javascript
React精髓!一篇全概括小结(急速)
May 23 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中使用XML
2006/10/09 PHP
浅谈web上存漏洞及原理分析、防范方法(安全文件上存方法)
2013/06/29 PHP
ThinkPHP的MVC开发机制实例解析
2014/08/23 PHP
PHP提高编程效率的20个要点
2015/09/23 PHP
php中实现进程锁与多进程的方法
2016/09/18 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
2017/12/21 PHP
PHP join()函数用法与实例讲解
2019/03/11 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
prototype class详解
2006/09/07 Javascript
javascript使用location.search的示例
2013/11/05 Javascript
浅析Node.js中的内存泄漏问题
2015/06/23 Javascript
JS判断输入的字符串是否是数字的方法(正则表达式)
2016/11/29 Javascript
基于JS实现限时抢购倒计时间表代码
2017/05/09 Javascript
原生JS发送异步数据请求
2017/06/08 Javascript
JavaScript中运算符规则和隐式类型转换示例详解
2017/09/06 Javascript
React 组件中的 bind(this)示例代码
2018/09/16 Javascript
vue.extend与vue.component的区别和联系
2018/09/19 Javascript
vue中如何实现后台管理系统的权限控制的方法步骤
2019/09/05 Javascript
JS随机密码生成算法
2019/09/23 Javascript
JavaScript实现HSL拾色器
2020/05/21 Javascript
JavaScript文档加载模式以及元素获取
2020/07/28 Javascript
JS实现audio音频剪裁剪切复制播放与上传(步骤详解)
2020/07/28 Javascript
Python实现抓取页面上链接的简单爬虫分享
2015/01/21 Python
ActiveMQ:使用Python访问ActiveMQ的方法
2019/01/30 Python
opencv-python 读取图像并转换颜色空间实例
2019/12/09 Python
python 的numpy库中的mean()函数用法介绍
2020/03/03 Python
Python3与fastdfs分布式文件系统如何实现交互
2020/06/23 Python
html5视频常用API接口的实战示例
2020/03/20 HTML / CSS
Ibatis如何使用动态表名
2015/07/12 面试题
资产经营总监岗位职责范文
2013/12/01 职场文书
公司总经理助理岗位职责
2014/07/09 职场文书
科长个人四风问题整改措施思想汇报
2014/10/13 职场文书
2014社区健康教育工作总结
2014/12/16 职场文书
2014年生活老师工作总结
2014/12/23 职场文书
2015年档案管理员工作总结
2015/05/13 职场文书
瞿秋白纪念馆观后感
2015/06/10 职场文书