jquery.purebox.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /**
  2. * jQuery弹出层插件,简单精致,结构简单,样式简洁,接口丰富,满足轻量应用
  3. * email: tianshaojie@msn.com
  4. * date: 2013-01-15
  5. * version: 1.0.0
  6. */
  7. (function($) {
  8. var
  9. $doc = $(document),
  10. $win = $(window),
  11. ie = /msie/.test(navigator.userAgent.toLowerCase()),
  12. ie6 = ('undefined' == typeof(document.body.style.maxHeight)),
  13. max = Math.max,
  14. min = Math.min,
  15. purebox = function(options) {
  16. return purebox.list[options.id] ? purebox.list[options.id] : new purebox.fn._init(options);
  17. };
  18. purebox.fn = purebox.prototype = {
  19. constructor : purebox,
  20. _init : function(options) {
  21. var opts = $.extend({}, purebox.defaults, options || {}),
  22. template = ['<div id="',opts.id,'" class="pb"><div class="cboxContent">',
  23. opts.head ? ('<div class="pb-hd">' + (opts.xBtn ? '<a class="pb-x">\u2715</a>' : '') + '<span class="pb-title">'+opts.title+'</span></div>') : '',
  24. '<div class="pb-bd"><div class="pb-ct"></div>',
  25. opts.foot ? ('<div class="pb-ft">'+(opts.cBtn ? '<a class="pb-btn pb-ok">' + opts.ok_title + '</a>' : '') + (opts.cl_cBtn ? '<a class="pb-btn pb-cl">' + opts.cl_title + '</a>' : '') + '</div>') : '',
  26. '</div></div></div>'].join(''),
  27. $pb = $(template),
  28. $head = $pb.find('.pb-hd'),
  29. $foot = $pb.find('.pb-ft'),
  30. that = this;
  31. that.$pb = $pb,
  32. that.$head = $head;
  33. that.$foot = $foot;
  34. that.$xBtn = $head.find('.pb-x');
  35. that.$cont = $pb.find('.pb-ct');
  36. that.$cBtn = $foot.find('.pb-cl');
  37. that.$oBtn = $foot.find('.pb-ok');
  38. that.$pb.appendTo(document.body);
  39. that.opts = opts;
  40. that.offsetHeight = $head.outerHeight()+$foot.outerHeight();
  41. that._bindEvent();
  42. that._setPbZindex();
  43. that.resize(opts.width, opts.height);
  44. that.setContent(opts.content);
  45. opts.drag && that._setDrag();
  46. opts.mask && that._setMask();
  47. opts.resize && that.$pb.resizable({
  48. handles: "e, s, se",
  49. onResize:function() {
  50. that.$cont.height(that.$pb.innerHeight() - that.offsetHeight);
  51. },
  52. onStopResize:function() {
  53. that.$cont.height(that.$pb.innerHeight() - that.offsetHeight);
  54. }
  55. });
  56. !opts.fixed && that.$pb.css('position','absolute');
  57. that.setPos(opts.top, opts.left);
  58. purebox.list[opts.id] = that;
  59. that._focus();
  60. return that;
  61. },
  62. //定义全局变量window.zindex,每次Z值加一
  63. _zindex : function() {
  64. window.pb_zindex = window.pb_zindex || 100000;
  65. return ++window.pb_zindex;
  66. },
  67. //设置弹出层Z轴坐标
  68. _setPbZindex : function() {
  69. var that = this;
  70. return that.$pb.css('z-index', that._zindex());
  71. },
  72. //设置遮罩层Z轴坐标
  73. _setMaskZindex : function() {
  74. var that = this;
  75. return $('#pb-mask').css('z-index', that._zindex()).show();
  76. },
  77. //设置遮罩,遮罩的Z轴比最上面弹出层小,比已打开的弹出层大
  78. _setMask : function() {
  79. var that = this;
  80. if($('#pb-mask').length) {
  81. that._setMaskZindex();
  82. that._setPbZindex();
  83. } else {
  84. var css = 'position:fixed;width:100%;height:100%;top:0;left:0;filter: progid:DXImageTransform.Microsoft.Alpha(opacity=40);opacity:0.4;overflow:hidden;background-color:#fff;_position:absolute;left:expression(documentElement.scrollLeft+documentElement.clientWidth-this.offsetWidth);top:expression(documentElement.scrollTop+documentElement.clientHeight-this.offsetHeight);',
  85. iframe = ie6 ? '<iframe src="about:blank" style="width:100%;height:100%;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity=0)"></iframe>' : '';
  86. $('<div id="pb-mask" style="'+css+'">' + iframe + '</div>').css('z-index', that._zindex()).appendTo(document.body);
  87. that._setPbZindex();
  88. }
  89. },
  90. //设置弹出层是否可以拖拽
  91. _setDrag : function() {
  92. return new purebox.dragable(this.$pb, this.$head);
  93. },
  94. //绑定触发事件
  95. _bindEvent : function(opts) {
  96. var that = this,
  97. opts = that.opts;
  98. that.$xBtn.length && that.$xBtn.click(function() {
  99. $.isFunction(opts.onClose) && opts.onClose();
  100. that.dispose();
  101. });
  102. that.$cBtn.length && that.$cBtn.click(function() {
  103. $.isFunction(opts.onCancel) && opts.onCancel();
  104. that.dispose();
  105. });
  106. that.$oBtn.length && that.$oBtn.click(function() {
  107. $.isFunction(opts.onOk) && opts.onOk();
  108. that.dispose();
  109. });
  110. //窗口调整大小事件
  111. var resizeTimer;
  112. $win.resize(function() {
  113. resizeTimer && clearTimeout(resizeTimer);
  114. resizeTimer = setTimeout(function () {
  115. that.setPos(opts.top, opts.left);
  116. }, 40);
  117. });
  118. },
  119. _focus : function() {
  120. var focus = purebox.focus;
  121. this.prev = focus;
  122. purebox.focus = this;
  123. },
  124. //设置尺寸
  125. resize : function(width, height) {
  126. var that = this;
  127. that.$pb.css('width', max.call(Math,150,width) + 'px');
  128. that.$cont.css('height', max.call(Math,50,height) + 'px');
  129. return that;
  130. },
  131. //设置位置
  132. setPos : function(top, left) {
  133. var that = this,
  134. dl = that.opts.fixed ? 0 : $doc.scrollLeft(),
  135. dt = that.opts.fixed ? 0 : $doc.scrollTop();
  136. if(top === 'c') {
  137. top = $win.height() - that.$pb.outerHeight();
  138. top = top > 0 ? dt + (top>>1)-(top>>3) : 0;
  139. }
  140. if(left === 'c') {
  141. left = $win.width() - that.$pb.outerWidth();
  142. left = left > 0 ? dl + (left>>1) : 0;
  143. }
  144. that.$pb.css({top:top,left:left});
  145. return that;
  146. },
  147. center : function() {
  148. return this.setPos('c', 'c');
  149. },
  150. //设置弹出要显示的内容,支持html和jQuery对象,暂不支持URL和Image
  151. setContent : function(c) {
  152. var that = this;
  153. if(typeof(c) === 'string') {
  154. that.$cont.html(c);
  155. } else if(c instanceof jQuery) {
  156. var display = c.css('display'),
  157. prev = c.prev(),
  158. next = c.next(),
  159. parent = c.parent();
  160. that._elemBack = function () {
  161. if (prev.length) {
  162. prev.after(c);
  163. } else if (next.length) {
  164. next.before(c);
  165. } else if (parent.length) {
  166. parent.append(c);
  167. };
  168. c.css('display',display);
  169. that._elemBack = null;
  170. };
  171. that.$cont.append(c);
  172. }
  173. return that;
  174. },
  175. //关闭按钮对应的操作
  176. dispose : function() {
  177. var that = this;
  178. that._elemBack && that._elemBack();
  179. that.$pb.remove();
  180. delete purebox.list[that.opts.id];
  181. purebox.focus = purebox.focus.prev;
  182. if(purebox.focus) {
  183. if(purebox.focus.opts.mask) {
  184. that._setMaskZindex();
  185. } else {
  186. $('#pb-mask').hide();
  187. }
  188. $('.pb').last().css('z-index', that._zindex());
  189. } else {
  190. $('#pb-mask').remove();
  191. }
  192. }
  193. };
  194. purebox.fn._init.prototype = purebox.fn;
  195. purebox.defaults = {
  196. id : 'pb', //弹出层ID
  197. title : '\u6807\u9898', //弹出层标题,默认“标题”
  198. content : '', //弹出层内容,支持html和jQuery对象,暂不支持URL和Image
  199. width : 'auto', //弹出层宽度
  200. height : 'auto', //弹出层高度
  201. left : 'c', //X轴坐标,center默认居中显示
  202. top : 'c', //Y轴坐标,center默认居中显示
  203. fixed : true, //是否静止定位
  204. drag : true, //是否拖拽
  205. mask : true, //是否锁屏
  206. resize : false, //是否可以调节尺寸,需要引入jquery.resizable.js
  207. head : true, //是否显示标题栏
  208. foot : true, //是否显示按钮栏
  209. xBtn : true, //是否显示关闭按钮
  210. cBtn : true, //是否显示取消按钮
  211. cl_cBtn : true,
  212. onClose : null, //关闭回调事件
  213. onOk : null, //确定回调事件
  214. onCancel: null //取消回调事件
  215. };
  216. purebox.focus = null;
  217. purebox.list = {};
  218. //拖拽
  219. purebox.dragable = function() {
  220. return this.initialize.apply(this, arguments);
  221. };
  222. purebox.dragable.prototype = {
  223. //拖放对象
  224. initialize: function($drag, $handle) {
  225. this._drag = $drag;//拖放对象
  226. this._handle = $handle || this._drag;
  227. //事件代理
  228. this.move = $.proxy(this.onMove,this);
  229. this.stop = $.proxy(this.onStop,this);
  230. this._handle.bind("mousedown", $.proxy(this.onStart,this));
  231. },
  232. //准备拖动
  233. onStart: function(event) {
  234. //记录鼠标相对拖放对象的位置
  235. this._x = event.clientX - parseInt(this._drag.css('left'), 10);
  236. this._y = event.clientY - parseInt(this._drag.css('top'), 10);
  237. $doc.bind('mousemove',this.move).bind('mouseup', this.stop);
  238. if(ie){
  239. //焦点丢失
  240. this._handle.bind("losecapture", this.stop);
  241. //设置鼠标捕获
  242. this._handle.get(0).setCapture();
  243. }else{
  244. //焦点丢失
  245. $doc.bind("blur", this.stop);
  246. //阻止默认动作
  247. event.preventDefault();
  248. };
  249. },
  250. //拖动
  251. onMove: function(event) {
  252. //清除选择
  253. window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
  254. //设置移动参数、范围限制,动态的使用$win.width()和$drag.outerWidth()是为了避免窗口大小和弹出层大小改变是对拖动位置的影响
  255. var iLeft = event.clientX - this._x,
  256. iTop = event.clientY - this._y,
  257. fixed = this._drag.css('position') === 'fixed',
  258. dl = fixed ? 0 : $doc.scrollLeft(),
  259. dt = fixed ? 0 : $doc.scrollTop(),
  260. maxLeft = dl + $win.width() - this._drag.outerWidth(),
  261. maxTop = dt + $win.height() - this._drag.outerHeight();
  262. iLeft = max(min(iLeft, maxLeft), dl);
  263. iTop = max(min(iTop, maxTop), dt);
  264. this._drag.css({top:iTop, left:iLeft});
  265. },
  266. //停止拖动
  267. onStop: function() {
  268. //移除事件
  269. $doc.unbind("mousemove", this.move);
  270. $doc.unbind("mouseup", this.stop);
  271. if(ie){
  272. this.unbind("losecapture", this.stop);
  273. this._handle.get(0).releaseCapture();
  274. }else{
  275. $doc.unbind("blur", this.stop);
  276. };
  277. }
  278. };
  279. //扩展到jQuery工具集
  280. window.pb = $.pb = $.purebox = purebox;
  281. //扩展到jQuery包装集
  282. $.fn.pb = $.fn.purebox = function (options) {
  283. return this.bind('click', function() {
  284. $.pb(options);
  285. });
  286. };
  287. //扩展alert
  288. $.pb.alert = function(content, callback) {
  289. return $.pb({
  290. id : 'pb-alert',
  291. title : '\u63d0\u793a',
  292. content : wrapCont(content),
  293. width : 300,
  294. height : 70,
  295. onOk : callback,
  296. cBtn : false,
  297. resize : false
  298. });
  299. };
  300. //扩展confirm
  301. $.pb.confirm = function(content, ok, cancel) {
  302. return $.pb({
  303. id : 'pb-confirm',
  304. title : '\u786e\u8ba4',
  305. content : wrapCont(content),
  306. width : 300,
  307. height : 70,
  308. onOk : ok,
  309. onCancel : cancel,
  310. resize : false
  311. });
  312. };
  313. //居中显示文字Alert,Confirm
  314. function wrapCont(cont) {
  315. return '<div style="text-align:center;padding: 20px 10px 0;">' + cont + '</div>';
  316. }
  317. })(window.jQuery);