You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

858 lines
29 KiB
JavaScript

5 years ago
/**
+-------------------------------------------------------------------
* jQuery thinkbox - 弹出层插件 - http://zjzit.cn/thinkbox
+-------------------------------------------------------------------
* @version 1.0.0 beta2
* @since 2013.05.10
* @author 麦当苗儿 <zuojiazi@vip.qq.com> <http://www.zjzit.cn>
* @github https://github.com/Aoiujz/thinkbox.git
+-------------------------------------------------------------------
*/
(function($){
var
/* 当前脚本文件名 */
__FILE__ = $("script").last().attr("src"),
/* 弹出层对象 */
ThinkBox,
/* 弹出层默认选项 */
defaults = {
"style" : "default", //弹出层样式
"title" : null, // 弹出层标题
"fixed" : true, // 是否使用固定定位(fixed)而不是绝对定位(absolute)IE6不支持。
"center" : true, // 弹出层是否屏幕中心显示
"display" : true, // 创建后是否立即显示
"x" : 0, // 弹出层 x 坐标。 当 center 属性为 true 时此属性无效
"y" : 0, // 弹出层 y 坐标。 当 center 属性为 true 时此属性无效
"modal" : true, // 弹出层是否设置为模态。设置为 true 将显示遮罩背景
"modalClose" : true, // 点击模态背景是否关闭弹出层
"resize" : true, // 是否在窗口大小改变时重新定位弹出层位置
"unload" : false, // 关闭后是否卸载
"escHide" : true, // 按ESC是否关闭弹出层
"delayClose" : 0, // 延时自动关闭弹出层 0表示不自动关闭
"drag" : false, // 点击标题框是否允许拖动
"width" : "", // 弹出层内容区域宽度 空表示自适应
"height" : "", // 弹出层内容区域高度 空表示自适应
"dataEle" : "", // 弹出层绑定到的元素,设置此属性的弹出层只允许同时存在一个
"locate" : ["left", "top"], //弹出层位置属性
"show" : ["fadeIn", "normal"], //显示效果
"hide" : ["fadeOut", "normal"], //关闭效果
"actions" : ["minimize", "maximize", "close"], //窗口操作按钮
"tools" : false, //是否创建工具栏
"buttons" : {}, //工具栏默认按钮 仅tools为true时有效
"beforeShow" : $.noop, //显示前的回调方法
"afterShow" : $.noop, //显示后的回调方法
"afterHide" : $.noop, //隐藏后的回调方法
"beforeUnload": $.noop, //卸载前的回调方法
"afterDrag" : $.noop //拖动停止后的回调方法
},
/* 弹出层层叠高度 */
zIndex = 2013,
/* 弹出层语言包 */
lang = {},
/* 弹出层列表 */
lists = {},
/* 弹出层容器 */
wrapper = [
"<div class=\"thinkbox\" style=\"position:fixed\">",
//使用表格,可以做到良好的宽高自适应,而且方便低版本浏览器做圆角样式
"<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">",
"<tr>",
"<td class=\"thinkbox-top-left\"></td>", //左上角
"<td class=\"thinkbox-top\"></td>", //上边
"<td class=\"thinkbox-top-right\"></td>", //右上角
"</tr>",
"<tr>",
"<td class=\"thinkbox-left\"></td>", //左边
"<td class=\"thinkbox-inner\">", //弹出层inner
"<div class=\"thinkbox-title\"></div>", //弹出层标题栏
"<div class=\"thinkbox-body\"></div>", //弹出层body
"<div class=\"thinkbox-tools\"></div>", //弹出层工具栏
"</td>",
"<td class=\"thinkbox-right\"></td>", //右边
"</tr>",
"<tr>",
"<td class=\"thinkbox-bottom-left\"></td>", //左下角
"<td class=\"thinkbox-bottom\"></td>", //下边
"<td class=\"thinkbox-bottom-right\"></td>", //右下角
"</tr>",
"</table>",
"</div>"].join(""),
/* document和window对象分别对应的jQuery对象 */
_doc = $(document), _win = $(window);
/* 加载指定的CSS文件 */
function includeCss(css, onload){
var path = __FILE__.slice(0, __FILE__.lastIndexOf("/"));
if($("link[href='" + path + css + "']").length){
fire(onload);
return;
};
//加载CSS文件
$("<link/>")
.load(function(){fire(onload)})
.attr({
"href" : path + css + "?" + Math.random(),
"type" : "text/css",
"rel" : "stylesheet"
}).appendTo("head");
}
/* 获取屏幕可视区域的大小和位置 */
function viewport(){
return {
"width" : _win.width(),
"height" : _win.height(),
"left" : _win.scrollLeft(),
"top" : _win.scrollTop()
};
}
/* 调用回调函数 */
function fire(event, data){
if($.isFunction(event))
return event.call(this, data);
}
/* 删除options中不必要的参数 */
function del(keys, options){
if($.isArray(keys)){ //删除多个
for(i in keys){
_(keys[i]);
}
} else { //删除一个
_(keys);
}
//从options中删除一个指定的元素
function _(key){
if(key in options) delete options[key];
}
}
/* 禁止选中文字 */
function unselect(){
var element = $("body")[0];
element.onselectstart = function() {return false}; //ie
element.unselectable = "on"; // ie
element.style.MozUserSelect = "none"; // firefox
element.style.WebkitUserSelect = "none"; // chrome
}
/* 允许选中文字 */
function onselect(){
var element = $("body")[0];
element.onselectstart = function() {return true}; //ie
element.unselectable = "off"; // ie
element.style.MozUserSelect = ""; // firefox
element.style.WebkitUserSelect = ""; // chrome
}
/* 设置为当前选中的弹出层对象 */
function setCurrent(){
var options = lists[this.key][0], box = lists[this.key][1];
if(lists.current != this.key){
lists.current = this.key;
options.modal && box.data("ThinkBoxModal").css({"zIndex": zIndex-1})
box.css({"zIndex": zIndex++});
}
}
/* 卸载弹出层容器 */
function unload(){
var options = lists[this.key][0], box = lists[this.key][1];
fire.call(this, options.beforeUnload); //卸载前的回调方法
options.modal && box.data("ThinkBoxModal").remove();
box.remove();
_win.off("resize." + this.key);
delete lists[this.key];
options.dataEle && $(options.dataEle).removeData("ThinkBox");
}
/* 安装模态背景 */
function setupModal(){
var self = this,
options = lists[this.key][0],
box = lists[this.key][1],
modal = box.data("ThinkBoxModal");
//存在隐藏的遮罩层则直接显示
if(modal){
modal.show();
return;
}
modal = $("<div class=\"thinkbox-modal-blackout-" + options.style + "\"></div>")
.css({
"zIndex" : zIndex++,
"position" : "fixed",
"left" : 0,
"top" : 0,
"right" : 0,
"bottom" : 0
})
.click(function(event){
options.modalClose && lists.current == self.key && self.hide();
event.stopPropagation();
})
.mousedown(function(event){event.stopPropagation()})
.appendTo($("body"));
box.data("ThinkBoxModal", modal);
}
/* 安装标题栏 */
function setupTitleBar() {
var title = $(".thinkbox-title", lists[this.key][1]), options = lists[this.key][0];
if(options.title){
//拖动弹出层
if (options.drag) {
title.addClass("thinkbox-draging");
drag.call(this, title);
}
this.setTitle(options.title);
//安装窗口操作按钮
setupWindowActions.call(this, title);
} else {
title.remove();
}
}
/* 安装弹出层操作按钮 */
function setupWindowActions(title){
var actions, button, action, options = lists[this.key][0], self = this;
if(options.actions && $.isArray(options.actions)){
actions = $("<div/>").addClass("thinkbox-window-actions").appendTo(title)
.on("click", "button", function(){
if(!$(this).hasClass("disabled")){
switch(this.name){
case "minimize": //最小化
self.minimize(this);
break;
case "maximize": //最大化
self.maximize(this);
break;
case "close": //关闭
self.hide();
break;
}
}
})
.on("mousedown mouseup", function(event){event.stopPropagation()});
for(i in options.actions){
button = options.actions[i];
action = $("<button/>").appendTo(actions).addClass("thinkbox-actions-" + button)
.attr("name", button) //设置名称
.attr("title", button) //设置title
.text(lang[button] || button); //设置显示文本
}
}
}
/* 拖动弹出层 */
function drag(title){
var draging = null, self = this, options = lists[this.key][0], box = lists[this.key][1];
_doc.mousemove(function(event){
draging &&
box.css({left: event.pageX - draging[0], top: event.pageY - draging[1]});
});
title.mousedown(function(event) {
var offset = box.offset();
if(options.fixed){
offset.left -= _win.scrollLeft();
offset.top -= _win.scrollTop();
}
unselect(); //禁止选中文字
draging = [event.pageX - offset.left, event.pageY - offset.top];
}).mouseup(function() {
draging = null;
onselect(); //允许选中文字
fire.call(self, options.afterDrag); //拖动后的回调函数
});
}
/* 安装工具栏 */
function setupToolsBar() {
var tools = $(".thinkbox-tools", lists[this.key][1]),
options = lists[this.key][0], button, self = this;
if(options.tools){
if(options.buttons && $.isPlainObject(options.buttons)){
for(name in options.buttons){
this.addToolsButton(name, options.buttons[name]);
}
/* 绑定按钮点击事件 */
tools.on("click", "button", function(){
if(!$(this).hasClass("disabled")){
if(false === options.buttons[this.name][2].call(self)){
return;
}
/* 执行默认事件 */
switch(this.name){
case "close":
case "cancel":
self.hide(false);
break;
case "submit":
self.find("form").submit();
break;
}
}
});
}
} else {
tools.remove();
}
}
/**
* 构造方法用于实例化一个新的弹出层对象
+----------------------------------------------------------
* element 弹出层内容元素
* options 弹出层选项
+----------------------------------------------------------
*/
ThinkBox = function(element, options){
var self = this, options, box, boxLeft; //初始化变量
options = $.extend({}, defaults, options || {}); //合并配置选项
/* 创建弹出层容器 */
box = $(wrapper).addClass("thinkbox-" + options.style).data("thinkbox", self);
/* 保存弹出层基本信息到全局变量 */
this.key = "thinkbox_" + new Date().getTime() + (Math.random() + "").substr(2,12);
lists[this.key] = [options, box];
/* 缓存弹出层,防止弹出多个 */
options.dataEle && $(options.dataEle).data("thinkbox", self);
/**
* 给box绑定事件
* 鼠标按下记录当前弹出层对象
* 鼠标点击阻止事件冒泡
*/
box.on("click mousedown", function(event){
setCurrent.call(self);
event.stopPropagation();
});
/* 设置弹出层位置属性 */
options.fixed || box.css("position", "absolute");
/* 安装弹出层相关组件 */
setupTitleBar.call(self); // 安装标题栏
setupToolsBar.call(self);// 安装工具栏
/* 自动加载css文件并显示弹出层 */
includeCss("/skin/" + options.style + "/style.css", function(){
box.hide().appendTo("body"); //放入body
/* 解决拖动出浏览器时左边不显示的BUG */
boxLeft = $(".thinkbox-left", box).width();
boxLeft && $(".thinkbox-left", box).append($("<div/>").css("width", boxLeft));
self.setSize(options.width, options.height);
self.setContent(element || "<div></div>"); //设置内容
options.display && self.show();
});
}; //END ThinkBox
/**
* 注册ThinkBox开放API接口
*/
ThinkBox.prototype = {
/* 显示弹出层 */
"show" : function(){
var self = this, options = lists[this.key][0], box = lists[this.key][1];
if(box.is(":visible")) return this;
options.modal && setupModal.call(this); // 安装模态背景
fire.call(this, options.beforeShow); //调用显示之前回调函数
//显示效果
switch(options.show[0]){
case "slideDown":
box.stop(true, true).slideDown(options.show[1], _);
break;
case "fadeIn":
box.stop(true, true).fadeIn(options.show[1], _);
break;
default:
box.show(options.show[1], _);
}
//窗口大小改变后重设位置和大小
options.resize && _win.on("resize." + self.key, function(){
self.setSize(options.width, options.height);
self.resetLocate();
});
setCurrent.call(this);
return this;
function _(){
options.delayClose &&
$.isNumeric(options.delayClose) &&
setTimeout(function(){
self.hide();
}, options.delayClose);
//调用显示后的回调方法
fire.call(self, options.afterShow);
}
},
/* 关闭弹出层 data 为传递给关闭后回调函数的额外数据 */
"hide" : function(data){
var self = this, options = lists[this.key][0], box = lists[this.key][1], modal;
if(!box.is(":visible")) return this;
//隐藏遮罩层
modal = box.data("ThinkBoxModal");
modal && modal.fadeOut();
//影藏效果
switch(options.hide[0]){
case "slideUp":
box.stop(true, true).slideUp(options.hide[1], _);
break;
case "fadeOut":
box.stop(true, true).fadeOut(options.hide[1], _);
break;
default:
box.hide(options.hide[1], _);
}
return this;
function _() {
fire.call(self, options.afterHide, data); //隐藏后的回调方法
options.unload && unload.call(self);
}
},
/* 显示或隐藏弹出层 */
"toggle" : function(){
return lists[this.key][1].is(":visible") ? self.hide() : self.show();
},
/* 在弹出层内容中查找 */
"find" : function(selector){
var content = $(".thinkbox-body", lists[this.key][1]);
return selector ? $(selector, content) : content.children();
},
/* 获取弹出层内容 */
"getContent" : function(){
return $(".thinkbox-body", lists[this.key][1]).html()
},
/* 设置弹出层内容 */
"setContent" : function(content){ //设置弹出层内容
var options = lists[this.key][0];
$(".thinkbox-body", lists[this.key][1]).empty().append($(content).show()); // 添加新内容
this.resetLocate(); //设置弹出层显示位置
return this;
},
/* 设置弹出层内容区域大小 */
"setSize" : function(width, height){
var width = $.isFunction(width) ? width.call(this) : width,
height = $.isFunction(height) ? height.call(this) : height;
$(".thinkbox-body", lists[this.key][1]).css({"width" : width, "height" : height});
return this;
},
/* 移动弹出层到屏幕中间 */
"moveToCenter" : function() {
var size = this.getSize(),
view = viewport(),
overflow = lists[this.key][1].css("position") == "fixed" ? [0, 0] : [view.left, view.top],
x = overflow[0] + view.width / 2,
y = overflow[1] + view.height / 2;
this.moveTo(x - size[0] / 2, y - size[1] / 2);
return this;
},
/* 移动弹出层到指定坐标 */
"moveTo" : function (x, y) {
var box = lists[this.key][1], options = lists[this.key][0];
$.isNumeric(x) &&
(options.locate[0] == "left" ? box.css({"left" : x}) : box.css({"right" : x}));
$.isNumeric(y) &&
(options.locate[1] == "top" ? box.css({"top" : y}) : box.css({"bottom" : y}));
return this;
},
/* 获取弹出层尺寸 */
"getSize" : function (){
var size = [0, 0], box = lists[this.key][1];
if(box.is(":visible")) //获取显示的弹出层尺寸
size = [box.width(), box.height()];
else { //获取隐藏的弹出层尺寸
box.css({"visibility" : "hidden", "display" : "block"});
size = [box.width(), box.height()];
box.css({"visibility" : "visible", "display" : "none"});
}
return size;
},
/* 设置弹出层标题 */
"setTitle" : function(title){
$(".thinkbox-title", lists[this.key][1]).empty().append("<span>" + title + "</span>");
return this;
},
/* 重置弹出层位置 */
"resetLocate" : function(){
var options = lists[this.key][0];
options.center ?
this.moveToCenter() :
this.moveTo(
$.isNumeric(options.x) ?
options.x :
($.isFunction(options.x) ? options.x.call($(options.dataEle)) : 0),
$.isNumeric(options.y) ?
options.y :
($.isFunction(options.y) ? options.y.call($(options.dataEle)) : 0)
);
return this;
},
/* 设置状态栏信息 */
"setStatus" : function(content, name){
var options = lists[this.key][0],
box = lists[this.key][1],
name = name ? "thinkbox-status-" + name : "", status;
/* 存在工具栏则显示状态信息 */
if(options.tools){
$(".thinkbox-status", box).remove();
status = $("<div class=\"thinkbox-status\">").addClass(name).html(content);
$(".thinkbox-tools", box).prepend(status);
}
return this;
},
/* 添加一个按钮 */
"addToolsButton" : function(name, config){
var options = lists[this.key][0],
box = lists[this.key][1], button;
/* 存在工具栏则创建button */
if(options.tools){
button = $("<button/>").attr("name", name).text(config[0]);
config[1] && button.addClass("thinkbox-button-" + config[1]);
if(!$.isFunction(config[2])){config[2] = $.noop};
$(".thinkbox-tools", box).append(button);
}
return this;
},
/* 重置一个按钮 */
"setToolsButton" : function(oldName, newName, config){
var options = lists[this.key][0],
box = lists[this.key][1], button;
button = $(".thinkbox-tools", box).find("button[name=" + oldName + "]", box)
.attr("name", newName).text(config[0]);
options.buttons[newName] = config;
config[1] && button.removeClass().addClass("thinkbox-button-" + config[1]);
if(!$.isFunction(config[2])){config[2] = $.noop};
return this;
},
/* 卸载一个按钮 */
"removeToolsButton" : function(name){
$(".thinkbox-tools", lists[this.key][1]).find("button[name='" + name + "']").remove();
return this;
},
/* 禁用一个按钮 */
"disableToolsButton" : function(name){
$(".thinkbox-tools", lists[this.key][1]).find("button[name='" + name + "']")
.addClass("disabled").attr("disabled", "disabled");
return this;
},
/* 启用一个按钮 */
"enableToolsButton" : function(name){
$(".thinkbox-tools", lists[this.key][1]).find("button[name='" + name + "']")
.removeClass("disabled").removeAttr("disabled", "disabled");
return this;
},
/* 最小化弹出层 */
"minimize" : function(){
return this;
},
/* 最大化弹出层 */
"maximize" : function(){
return this;
}
}
/* 按ESC关闭弹出层 */
_doc.mousedown(function(){lists.current = null})
.keydown(function(event){
lists.current
&& lists[lists.current][0].escHide
&& event.keyCode == 27
&& lists[lists.current][1].data("thinkbox").hide();
});
/**
* 创建一个新的弹出层对象
+----------------------------------------------------------
* element 弹出层内容元素
* options 弹出层选项
+----------------------------------------------------------
*/
$.thinkbox = function(element, options){
if($.isPlainObject(options) && options.dataEle){
var data = $(options.dataEle).data("thinkbox");
if(data) return options.display === false ? data : data.show();
}
return new ThinkBox(element, options);
}
/**
+----------------------------------------------------------
* 弹出层内置扩展
+----------------------------------------------------------
*/
$.extend($.thinkbox, {
/**
* 设置弹出层默认参数
* @param {string} name 配置名称
* @param {string} value 配置的值
*/
"defaults" : function(name, value){
if($.isPlainObject(name)){
$.extend(defaults, name);
} else {
defaults[name] = value;
}
},
// 以一个URL加载内容并以ThinBox弹出层的形式展现
"load" : function(url, opt){
var options = {
"clone" : false,
"loading" : "加载中...",
"type" : "GET",
"dataType" : "text",
"cache" : false,
"onload" : undefined
}, self, ajax, onload, loading, url = url.split(/\s+/);
$.extend(options, opt || {}); //合并配置项
//保存一些参数
onload = options.onload;
loading = options.loading;
//组装AJAX请求参数
ajax = {
"data" : options.data,
"type" : options.type,
"dataType" : options.dataType,
"cache" : options.cache,
"success" : function(data) {
url[1] && (data = $(data).find(url[1]));
if($.isFunction(onload))
data = fire.call(self, onload, data); //调用onload回调函数
self.setContent(data); //设置内容并显示弹出层
loading || self.show(); //没有loading状态则直接显示弹出层
}
};
//删除ThinkBox不需要的参数
del(["data", "type", "cache", "dataType", "onload", "loading"], options);
self = loading ?
//显示loading信息
$.thinkbox("<div class=\"thinkbox-load-loading\">" + loading + "</div>", options) :
//不显示loading信息则创建后不显示弹出层
$.thinkbox("<div/>", $.extend({}, options, {"display" : false}));
$.ajax(url[0], ajax);
return self;
},
// 弹出一个iframe
"iframe" : function(url, opt){
var options = {
"width" : 500,
"height" : 400,
"scrolling" : "no",
"onload" : undefined
}, self, iframe, onload;
$.extend(options, opt || {}); //合并配置项
onload = options.onload; //设置加载完成后的回调方法
//创建iframe
iframe = $("<iframe/>").attr({
"width" : options.width,
"height" : options.height,
"frameborder" : 0,
"scrolling" : options.scrolling,
"src" : url})
.load(function(){fire.call(self, onload)});
del(["width", "height", "scrolling", "onload"], options);//删除不必要的信息
self = $.thinkbox(iframe, options);
return self;
},
// 提示框 可以配合ThinkPHP的ajaxReturn
"tips" : function(msg, type, opt){
var options = {
"modalClose" : false,
"escHide" : false,
"unload" : true,
"close" : false,
"delayClose" : 1000
}, html;
//数字type转换为字符串type
switch(type){
case 0: type = "error"; break;
case 1: type = "success"; break;
}
html = "<div class=\"thinkbox-tips thinkbox-tips-" + type + "\">" + msg + "</div>";
$.extend(options, opt || {});
return $.thinkbox(html, options);
},
// 成功提示框
"success" : function(msg, opt){
return this.tips(msg, "success", opt);
},
// 错误提示框
"error" : function(msg, opt){
return this.tips(msg, "error", opt);
},
// 数据加载
"loading" : function(msg, opt){
var options = opt || {};
options.delayClose = 0;
return this.tips(msg, "loading", options);
},
//消息框
"msg" : function(msg, opt){
var options = {
"drag" : false,
"escHide" : false,
"delayClose" : 0,
"center" : false,
"title" : "消息",
"x" : 0,
"y" : 0,
"locate" : ["right", "bottom"],
"show" : ["slideDown", "slow"],
"hide" : ["slideUp", "slow"]
}, html;
$.extend(options, opt || {});
html = $("<div/>").addClass("thinkbox-msg").html(msg);
return $.thinkbox(html, options);
},
//提示框
"alert" : function(msg, opt){
var options = {
"title" : lang.alert || "Alert",
"modal" : true,
"modalClose" : false,
"unload" : false,
"tools" : true,
"actions" : ["close"],
"buttons" : {"ok" : [lang.ok || "Ok", "blue", function(){this.hide()}]}
};
$.extend(options, opt || {});
//删除ThinkBox不需要的参数
del("ok", options);
var html = $("<div/>").addClass("thinkbox-alert").html(msg);
return $.thinkbox(html, options);
},
//确认框
"confirm" : function(msg, opt){
var options = {"title" : "确认", "modal" : false, "modalClose" : false},
button = {"ok" : "确定", "cancel" : "取消"};
$.extend(options, opt || {});
options.ok && (button.ok = options.ok);
options.cancel && (button.cancel = options.cancel);
//删除ThinkBox不需要的参数
del(["ok", "cancel"], options);
options.buttons = button;
var html = $("<div/>").addClass("thinkbox-confirm").html(msg);
return $.thinkbox(html, options);
},
//弹出层内部获取弹出层对象
"get" : function(selector){
//TODO:通过弹窗内部元素找
return $(selector).closest(".thinkbox").data("thinkbox");
}
});
$.fn.thinkbox = function(opt){
if(opt == "get") return $(this).data("thinkbox");
return this.each(function(){
var self = $(this), box = self.data("thinkbox"), options, event;
switch(opt){
case "show":
box && box.show();
break;
case "hide":
box && box.hide();
break;
case "toggle":
box && box.toggle();
break;
default:
options = {
"title" : self.attr("title"),
"dataEle" : this,
"fixed" : false,
"center" : false,
"modal" : false,
"drag" : false
};
opt = $.isPlainObject(opt) ? opt : {};
$.extend(options, {
"x" : function(){return $(this).offset().left},
"y" : function(){return $(this).offset().top + $(this).outerHeight()}
}, opt);
if(options.event){
self.on(event, function(){
_.call(self, options);
return false;
});
} else {
_.call(self, options);
}
}
});
function _(options){
var href = this.data("href") || this.attr("href");
if(href.substr(0, 1) == "#"){
$.thinkbox(href, options);
} else if(href.substr(0, 7) == "http://" || href.substr(0, 8) == "https://"){
$.thinkbox.iframe(href, options);
} else {
$.thinkbox.load(href, options);
}
}
}
})(jQuery);