jQuery.dialog.js 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. //------------------------------
  2. // Dialog plugin for jQuery
  3. // Author : LooseLive@gmail.com
  4. //------------------------------
  5. (function($){
  6. var WIN = $(window),
  7. DOC = $(document),
  8. zIndex = ZINDEX = 2,
  9. F = $.isFunction,
  10. CSS = {
  11. HASICON : 'HasIcon',
  12. TIMER : 'HasTimer',
  13. CURRENT : 'Current',
  14. LOADING : 'Loading',
  15. DISABLED : 'Disabled',
  16. NOTONTOP : 'NotOnTop',
  17. ENTCLICK : 'ENTCLICK'
  18. },
  19. SPACE = ' ',
  20. EVENT = {
  21. A : 'mousedown',
  22. B : 'click',
  23. C : 'keydown',
  24. D : 'resize',
  25. E : 'scroll'
  26. },
  27. //从对象中删除该实例,如果对象的实例被删空,重置ZINDEX,避免无限上增
  28. DELETE = function (id) {
  29. delete $.dialog.list[id];
  30. if ($.isEmptyObject($.dialog.list))
  31. {
  32. ZINDEX = zIndex;
  33. }
  34. };
  35. function toArray() {
  36. var a = arguments,
  37. A = [],
  38. i = 0;
  39. for (; i < a.length; i++)
  40. {
  41. if (a[i] instanceof Array)
  42. {
  43. A = $.merge(A, a[i]);
  44. }
  45. else if (a[i] != null)
  46. {
  47. A.push(a[i]);
  48. }
  49. }
  50. return A;
  51. }
  52. $.dialog = function(o) {
  53. return new $.dialog.fn._init(o);
  54. };
  55. $.dialog.list = {};
  56. //默认设置
  57. $.dialog.defaults = {
  58. //对话框的唯一标识符,用途:无论何时何地都可通过$.dialog.get('xxx')获取对话框对象。
  59. id : null,
  60. //对话框的标识触发器,用途:防止重复弹出,缓存数据。
  61. trigger : null,
  62. /*
  63. [图标] - int | string
  64. 成功:0 | success
  65. 警告:1 | warning
  66. 错误:2 | error,
  67. 异常:3 | exception
  68. 询问:4 | question
  69. */
  70. icon : null,
  71. //[标题]
  72. title : '信息提示',
  73. //[选项卡] - array
  74. tab : null,
  75. /*
  76. [
  77. {
  78. text : string - 选项卡名称,
  79. content : {icon:独立的图标}跟全局content格式一致,
  80. button : 跟全局button格式一致,
  81. active : 是否激活该tab,注意:同时只能激活一个tab,如果定义多个active=true,以最后一个为准
  82. onActive : 当激活该tab时的事件处理函数
  83. icon:
  84. }
  85. ],
  86. tab的全局触发方式(鼠标事件名称)
  87. */
  88. tabType : 'click',
  89. /*
  90. [对话框的内容] - object*/
  91. content : null,
  92. /*
  93. {
  94. //load : {
  95. url:String,
  96. [data] : {},
  97. [success]:Function,
  98. [error]:Function
  99. }
  100. ||
  101. load:string
  102. //text : string
  103. //selector : string(选择器表达式) | jquery(元素)
  104. //iframe : string(框架Url)
  105. ajax : {url:'bb'}//跟jquery的ajax参数格式一致
  106. },
  107. //[按钮] - array
  108. */
  109. button :
  110. [
  111. {
  112. text : '确认'
  113. /*
  114. ,callback : function - 处理函数,
  115. cls : string-自定义样式名称,
  116. url : string,
  117. disabled : Boolean,
  118. bindEnter : Boolean
  119. */
  120. }
  121. ],
  122. padding : '8px',
  123. width : null, //string||number - pixels
  124. height : null, //string||number - pixels
  125. //位置参照元素
  126. refer : null, //jquery||HTMLElement||string(jQuery selector)
  127. offset : {
  128. top : 'middel',
  129. /*
  130. 可使用值枚举:
  131. 字符('top'||'middel'||'bottom'||'xpx'||'%50')
  132. 数字(表示多少像素,与字符值'xpx'同等效果)
  133. */
  134. left : 'center'
  135. /*
  136. 可使用值枚举:
  137. 字符('left'||'center'||'right'||'80px'||'%60')
  138. 数字(表示多少像素,与字符值'xpx'同等效果)
  139. ,*/
  140. },
  141. //是否固定位置
  142. fixed : true,
  143. //遮罩层
  144. mask : {
  145. enabled : false, //是否启用
  146. color : '#999', //颜色
  147. opacity : 0.8, //透明度
  148. duration: 200 //透明度渐变动画的速度
  149. },
  150. draggable : true, //是否可拖动
  151. resizable : false, //是否可调整自身大小
  152. timeout : { second : 0, text : 's% 秒后将自动关闭'},
  153. esc : true, //是否允许用户按 Esc 键关闭对话框
  154. onLoad : $.noop,
  155. onClose : $.noop,
  156. onEnter : $.noop,
  157. err : {
  158. title : 'Error',
  159. content : '<p style="text-align:center">服务器繁忙或发生错误,请稍后再试!<br />The server is busy or unavailable, please try again later!</p>',
  160. button : 'Close'
  161. },
  162. showErr : true //内容加载失败时是否显示错误消息
  163. };
  164. //修改全局默认设置的方法
  165. $.dialog.setup = function (o) {
  166. $.extend(this.defaults, o);
  167. };
  168. $.dialog.get = function (id) {
  169. return $.dialog.list[id];
  170. }
  171. //关闭所有对话框,参数o-布尔值,是否静默关闭
  172. $.dialog.close = function (o) {
  173. for (var i in $.dialog.list) {
  174. $.dialog.list[i].close(o);
  175. };
  176. };
  177. $.dialog.fn = $.dialog.prototype = {
  178. version : '1.0.0',
  179. title : function(v, d) {
  180. d = this.dom().title;
  181. //如果未传入参数,则返回当前标题字符
  182. if (v === undefined) return d.text();
  183. if (v === null)v='';
  184. d.text(v);
  185. return this;
  186. },
  187. tab : function(o) {
  188. var e = this,
  189. d = e.dom(),
  190. x = d.title;
  191. if (o === false)
  192. {
  193. x.siblings().remove();
  194. }
  195. else
  196. {
  197. var v = toArray(o);
  198. if (v.length > 0)
  199. {
  200. var i = 0,
  201. t = $(),
  202. n = -1;
  203. for (; i < v.length; i++)
  204. {
  205. var m = v[i].type ? v[i].type : e.o.tabType,
  206. j = $('<a href="javascript:void(0)" hidefocus="true"></a>').data('_m', m);
  207. if(v[i].icon)
  208. {
  209. j.wrapInner('<b class="' + v[i].icon + '">' + v[i].text + '</b>');
  210. }
  211. else
  212. {
  213. j.text(v[i].text);
  214. }
  215. j.bind(m + SPACE + EVENT.A, {i : i}, function (p) {
  216. if (e.child != null) return;
  217. //避免对话框可拖动时点击tab所带来的反应
  218. if (p.type == EVENT.A) return false;
  219. var o = v[p.data.i],
  220. b = toArray(o.button !== undefined ? o.button : [], e.o.button),
  221. c = o.content;
  222. //激活tab事件处理
  223. if (F(o.onActive))
  224. {
  225. if(o.onActive.call(e) == false)return false;
  226. }
  227. //切换tab的样式
  228. $(this).addClass(CSS.CURRENT).siblings().removeClass(CSS.CURRENT);
  229. //预清空隐藏按纽栏
  230. d.button.empty().parent().hide();
  231. if (c)
  232. {
  233. if (typeof c === 'string' && (c.indexOf('#') === 0 || c.indexOf('.') === 0))
  234. {
  235. var w = d.content,
  236. z = w.find(c);
  237. if (!z[0])
  238. {
  239. var y = w.data('c');
  240. z = $(y).find(c);
  241. if (z[0]) w.html(y);
  242. }
  243. if (z[0])
  244. {
  245. z.siblings().hide();
  246. z.fadeIn('fast');
  247. e._ready(b, 1);
  248. }
  249. else
  250. {
  251. e._showErr();
  252. }
  253. }
  254. else
  255. {
  256. e.content(c, b);
  257. //独立的图标处理
  258. e.icon(c.icon || e.o.icon);
  259. }
  260. }
  261. else
  262. {
  263. e.button(b);
  264. }
  265. });
  266. if (v[i].active === true) n = i;
  267. t = t.add(j);
  268. }
  269. x.siblings().remove();
  270. x.parent().append(t);
  271. //如果有需要激活的tab
  272. if (n > -1)
  273. {
  274. var a = t.eq(n);
  275. if (e._isReady)
  276. {
  277. var m = a.data('_m');
  278. a.triggerHandler(m);
  279. }
  280. else
  281. {
  282. a.attr('data-active', 1);
  283. }
  284. }
  285. }
  286. }
  287. return e;
  288. },
  289. icon : function (v) {
  290. var d = this.dom(),
  291. b = d.body,
  292. c = d.icon;
  293. //如果未传入参数,则返回图标容器元素
  294. if (v === undefined) return d;
  295. if (v !== null)
  296. {
  297. if (!isNaN(v))
  298. {
  299. switch(v)
  300. {
  301. case 0: v = 'Success'; break;
  302. case 1: v = 'Warning'; break;
  303. case 2: v = 'Error'; break;
  304. case 3: v = 'Exception'; break;
  305. case 4: v = 'Question'; break;
  306. default : v = null;
  307. }
  308. }
  309. b.addClass(CSS.HASICON);
  310. if (v) c.removeClass().addClass(v).parent().show();
  311. }
  312. else
  313. {
  314. b.removeClass(CSS.HASICON);
  315. c.removeClass().parent().hide();
  316. }
  317. return this;
  318. },
  319. content : function (o, b) {
  320. var e = this,
  321. z = b ? 1 : 0,
  322. c = e.dom().content;
  323. if (o === undefined) return c;
  324. if (o === null)
  325. {
  326. e._ready();
  327. return e;
  328. }
  329. if (typeof o === 'string')
  330. {
  331. o = { text : o }
  332. }
  333. else if(!$.isPlainObject(o))
  334. {
  335. o = { selector : o }
  336. }
  337. b = b ? b : e.o.button;
  338. c.empty().addClass(CSS.LOADING);
  339. $.each(o, function (t, v){
  340. switch (t.toLowerCase())
  341. {
  342. case 'load' :
  343. if (typeof v === 'string') v = {url : v};
  344. c.load(v.url, v.data, function(x,y){
  345. if (y === 'success')
  346. {
  347. c.removeClass(CSS.LOADING);
  348. e._ready(b,z);
  349. if (v.success) v.success.call(e);
  350. }
  351. else
  352. {
  353. e._showErr();
  354. if (v.error) v.error.call(e);
  355. }
  356. });
  357. break;
  358. case 'text' :
  359. c.removeClass(CSS.LOADING).html(v);
  360. e._ready(b,z);
  361. break;
  362. case 'selector' :
  363. //使用API方式设置内容时如果有需要恢复到原始位置的元素,将其恢复
  364. e.recovery && e.recovery();
  365. //如果是选择器字符或HTMLElement,将其转换为jQuery对象
  366. if (typeof v === 'string' || v.nodeType === 1) v = $(v);
  367. if (v[0])
  368. {
  369. //-->恢复处理函数
  370. var display = v[0].style.display,
  371. prev = v.prev(),
  372. next = v.next(),
  373. parent = v.parent();
  374. e.recovery = function () {
  375. if (prev[0]) {
  376. prev.after(v);
  377. } else if (next[0]) {
  378. next.before(v);
  379. } else if (parent[0]) {
  380. parent.append(v);
  381. };
  382. v[0].style.display = display;
  383. e.recovery = null;
  384. };
  385. //<--
  386. c.removeClass(CSS.LOADING).append(v.show());
  387. e._ready(b,z);
  388. }
  389. else
  390. {
  391. e._showErr();
  392. }
  393. break;
  394. case 'iframe' :
  395. var iframe = $('<iframe src="' + v + '" width="100%" height="100%" scrolling="auto" frameborder="0" marginheight="0" marginwidth="0"></iframe>');
  396. c.removeClass(CSS.LOADING).html(iframe);
  397. iframe.bind('load', function () {
  398. var i = $(this),
  399. d = i[0].contentWindow.document,
  400. w = Math.max(d.body.scrollWidth, d.documentElement.scrollWidth),
  401. h = i.contents().find('body').height();
  402. if (!e._w) i.width(w);
  403. if (!e._h) i.height(h);
  404. });
  405. e._ready(b,z);
  406. break;
  407. case 'ajax' :
  408. v.type = v.type || 'get';
  409. $.ajax({
  410. url : v.url,
  411. type : v.type,
  412. data : v.data,
  413. dataType : 'html',
  414. success:function(html){
  415. c.removeClass(CSS.LOADING).html(html);
  416. e._ready(b,z);
  417. if(F(v.success)) v.success.call(e);
  418. },
  419. error : function () {
  420. if(v.error) v.error.call(e);
  421. e._showErr();
  422. }
  423. });
  424. break;
  425. }
  426. });
  427. return e;
  428. },
  429. button : function (o) {
  430. var e = this, a = toArray(o), b = e.dom().button, i = 0;
  431. b.empty().parent().hide();
  432. for (; i < a.length; i++)
  433. {
  434. var c = $('<a href="javascript:void(0)" hidefocus="true" data-id="' + a[i].text + '">' + a[i].text + '</a>').bind(EVENT.B, { e : e, f : a[i].callback }, F(a[i].callback) ? function (e,d) {
  435. if (e.data.e.child != null) return;
  436. if ($(this).hasClass(CSS.DISABLED))
  437. {
  438. return false;
  439. }
  440. else
  441. {
  442. d = e.data;
  443. return d.f.call(d.e);
  444. }
  445. } : $.proxy(e.close, e));
  446. if(typeof a[i].cls === 'string') c.addClass(a[i].cls);
  447. if(typeof a[i].url === 'string') c[0].href = a[i].url;
  448. if(a[i].disabled === true) c.addClass(CSS.DISABLED);
  449. if (a[i].bindEnter) c.addClass(CSS.ENTCLICK);
  450. b.append(c);
  451. }
  452. if (i > 0) b.parent().show();
  453. return e;
  454. },
  455. //改变按钮状态和文本,n-按钮的索引,o-字符或布尔值或纯粹的对象{disabled:Boolean,text:String}
  456. buttonChange : function (n, o) {
  457. var b = this.dom().button;
  458. d = b.children('[data-id="' + n + '"]');
  459. if (d.size() === 0) d = b.children().eq(n);
  460. var disabled = null;
  461. var text = null;
  462. if (typeof o == 'object')
  463. {
  464. disabled = o.disabled;
  465. text = o.text;
  466. }
  467. else
  468. {
  469. if (typeof o == 'boolean')
  470. {
  471. disabled = o;
  472. }
  473. else if (typeof o == 'string')
  474. {
  475. text = o;
  476. }
  477. }
  478. if (disabled !== null)
  479. {
  480. if(disabled)
  481. {
  482. d.addClass(CSS.DISABLED);
  483. }
  484. else
  485. {
  486. d.removeClass(CSS.DISABLED);
  487. }
  488. }
  489. if (text !== null)
  490. {
  491. d.text(text);
  492. }
  493. return this;
  494. },
  495. padding : function (v) {
  496. if (v)
  497. {
  498. var c = this.dom().content;
  499. if (!c.children('iframe')[0])
  500. {
  501. c.css('padding', v);
  502. }
  503. }
  504. return this;
  505. },
  506. width : function (v) {
  507. var e = this;
  508. if (v)
  509. {
  510. e.wrapper.width(v);
  511. e._w = 1;
  512. return e;
  513. }
  514. if (v === null) return e;
  515. return e.wrapper.width();
  516. },
  517. //设置对话框的高度,如果参数没有明确指定单位(如:em或%),使用px。如果不带参数,返回当前对话框的高度
  518. height : function (v) {
  519. var e = this;
  520. if (v)
  521. {
  522. e.wrapper.height(v);
  523. e._h = 1;
  524. return e;
  525. }
  526. if (v === null) return e;
  527. return e.wrapper.height();
  528. },
  529. offset : function(o) {
  530. var e = this;
  531. if (o === undefined) return e.lastOffset || e.o.offset;
  532. var refer = e.o.refer,
  533. windowW = WIN.width(),
  534. windowH = WIN.height(),
  535. width = e.wrapper.outerWidth(),
  536. height = e.wrapper.outerHeight(),
  537. offset = {top : parseInt((windowH - height)/2), left : parseInt((windowW - width) / 2)},
  538. set = true;
  539. if( offset.top <= 0 ) offset.top = 0;
  540. if( offset.left <= 0 ) offset.left = 0;
  541. if (refer)
  542. {
  543. var visibleT = DOC.scrollTop(),
  544. visibleL = DOC.scrollLeft(),
  545. visibleB = visibleT + windowH,
  546. visibleR = visibleL + windowW,
  547. referW = refer.outerWidth(),
  548. referH = refer.outerHeight(),
  549. referOffset = refer.offset(),
  550. referT = referOffset.top,
  551. referL = referOffset.left,
  552. referB = referT + referH,
  553. referR = referL + referW,
  554. invisibleW = 0,
  555. invisibleH = 0,
  556. inViewableArea = referT < visibleB && referB > visibleT && referR > visibleL && referL < visibleR;
  557. if (inViewableArea)
  558. {
  559. if (referL < visibleL)
  560. {
  561. invisibleW = visibleL - referL;
  562. referL = referL + invisibleW;
  563. }
  564. else if (referR > visibleR)
  565. {
  566. invisibleW = referR - visibleR;
  567. }
  568. if (referT < visibleT)
  569. {
  570. invisibleH = visibleT - referT;
  571. referT = referT + invisibleH;
  572. }
  573. else if (referB > visibleB)
  574. {
  575. invisibleH = referB - visibleB;
  576. }
  577. referW = referW - invisibleW,
  578. referH = referH - invisibleH;
  579. o = {
  580. top : referT + ((referH - height) / 2),
  581. left : referL + ((referW - width) / 2)
  582. };
  583. if (o.top < visibleT)
  584. {
  585. o.top = visibleT;
  586. }
  587. else if (o.top + height > visibleB)
  588. {
  589. o.top = visibleB - height;
  590. }
  591. if (o.left < visibleL)
  592. {
  593. o.left = visibleL;
  594. }
  595. else if (o.left + width > visibleR)
  596. {
  597. o.left = visibleR - width;
  598. }
  599. e.fixed(false).draggable(false);
  600. }
  601. else
  602. {
  603. e.fixed(false).draggable(e.o.draggable);
  604. set = false;
  605. }
  606. }
  607. $.each(o, function(n, val){
  608. if((typeof val === 'string' && (val.indexOf('%') > -1 || parseInt(val) > 0 )) || typeof val === 'number')
  609. {
  610. offset[n] = val;
  611. }
  612. else
  613. {
  614. switch(val)
  615. {
  616. case 'left' : offset[n] = 0; break;
  617. case 'right' : offset[n] = windowW-width;break;
  618. case 'top' : offset[n] = 0;break;
  619. case 'bottom' : offset[n] = windowH-height;break;
  620. }
  621. }
  622. });
  623. if (set)
  624. {
  625. e.wrapper.css({
  626. top : offset.top,
  627. left : offset.left
  628. });
  629. e.lastOffset = offset;
  630. }
  631. return e;
  632. },
  633. //开启或关闭固定定位。参数为false时为关闭,不带参数或参数值为非false时为开启
  634. fixed : function (v) {
  635. if (v === false)
  636. {
  637. this.wrapper.css('position','absolute');
  638. }
  639. else
  640. {
  641. this.wrapper.css('position','fixed');
  642. }
  643. return this;
  644. },
  645. //开启或关闭遮罩层。参数为false时为关闭,不带参数或参数值为非false时为开启
  646. mask : function (o) {
  647. var e = this, t = o;
  648. //使用.mask(null)方法关闭遮罩层
  649. if ((o === false || o === null) && e.MaskLayer != null)
  650. {
  651. e.MaskLayer.remove();
  652. e.MaskLayer = null;
  653. e._mask = 0;
  654. }
  655. o = o === true ? $.extend({}, $.dialog.defaults.mask, {enabled : true}) : $.extend({}, e.o.mask, o);
  656. if (t === undefined || o.enabled)
  657. {
  658. if (e.MaskLayer === null)
  659. {
  660. var a,b;
  661. if (e.zIndex === ZINDEX - 1)
  662. {
  663. a = e.zIndex;
  664. b = e.zIndex = ZINDEX++;
  665. }
  666. else
  667. {
  668. a = ZINDEX++;
  669. b = e.zIndex = ZINDEX++;
  670. }
  671. e.MaskLayer = $('<p class="jQ_Dialog_MaskLayer"></p>').css({
  672. backgroundColor : o.color,
  673. opacity : 0,
  674. zIndex : a,
  675. height : '100%',
  676. width : '100%',
  677. left : 0,
  678. top : 0
  679. });
  680. $("body").append(e.MaskLayer);
  681. e.wrapper.css('zIndex', b);
  682. e._mask = 1;
  683. e._setTop();
  684. }
  685. if (e.zIndex < ZINDEX - 1)
  686. {
  687. e.MaskLayer.css('zIndex', ZINDEX++);
  688. e.wrapper.css('zIndex', ZINDEX);
  689. e.zIndex = ZINDEX;
  690. ZINDEX++;
  691. e._mask = 1;
  692. e._setTop();
  693. }
  694. if (e._closed)
  695. {
  696. e.wrapper.show();
  697. e._closed = 0;
  698. }
  699. e.MaskLayer.show().animate({opacity: o.opacity}, o.duration);
  700. }
  701. else if (e.MaskLayer != undefined)
  702. {
  703. e.MaskLayer.remove();
  704. e.MaskLayer = null;
  705. e._mask = 0;
  706. }
  707. return e;
  708. },
  709. //开启或关闭拖动。参数为false时为关闭,不带参数或参数值为非false时为开启
  710. draggable : function (v) {
  711. var e = this,
  712. w = e.wrapper,
  713. d = e.dom().drag;
  714. if (v === false)
  715. {
  716. w.unDrag();
  717. }
  718. else
  719. {
  720. w.Drag(d);
  721. }
  722. return e;
  723. },
  724. //开启或关闭大小缩放。参数为false时为关闭,不带参数或参数值为非false时为开启
  725. resizable : function (v) {
  726. var e = this,
  727. c = e.dom().content,
  728. r = e.dom().resizer;
  729. if (v === false)
  730. {
  731. r.hide();
  732. }
  733. else
  734. {
  735. r.show();
  736. c.resize({ handler : r, wrapper : e.wrapper });
  737. }
  738. return e;
  739. },
  740. //倒计时关闭
  741. timeout : function (s, t) {
  742. var e = this,
  743. o = e.o.timeout,
  744. second, text,
  745. d = e.dom().foot,
  746. f = function () {
  747. if (text)
  748. {
  749. text = text.replace('s%','<b>s%</b>');
  750. d.addClass(CSS.TIMER).eq(1).html(text.replace('s%', second));
  751. }
  752. if(!second) e.close();
  753. second--;
  754. };
  755. if (typeof s === 'object' )
  756. {
  757. second = s.second || o.second;
  758. text = s.text || o.text;
  759. }
  760. else
  761. {
  762. second = s || o.second;
  763. text = t || o.text;
  764. }
  765. d.removeClass(CSS.TIMER).eq(1).empty();
  766. clearInterval(e.timer);
  767. if (second)
  768. {
  769. e.timer = setInterval(f, 1000);
  770. f();
  771. }
  772. return e;
  773. },
  774. //是否开启Esc键关闭
  775. esc : function (v) {
  776. this.o.esc = v;
  777. return this;
  778. },
  779. onLoad : function (f) {
  780. if (F(f)) this.o.onLoad = f;
  781. return this;
  782. },
  783. onClose : function (f) {
  784. if (F(f)) this.o.onClose = f;
  785. return this;
  786. },
  787. onEnter : function (f) {
  788. if (F(f)) this.o.onEnter = f;
  789. return this;
  790. },
  791. show : function () {
  792. this.wrapper.show();
  793. return this.__init();
  794. },
  795. close : function(x) {
  796. var e = this;
  797. if (e.child != null)
  798. {
  799. //忽略鼠标关闭事件
  800. if(typeof x === 'object')
  801. {
  802. return e;
  803. }
  804. else
  805. {
  806. //手动模式关闭-静默关闭
  807. x = true;
  808. }
  809. }
  810. if (e._closed) return e;
  811. //避免对话框可拖动时点击x所带来的反应
  812. if (typeof x === 'object' && x.type === EVENT.A) return false;
  813. var junior = e.junior();
  814. //静默关闭
  815. if (x === true)
  816. {
  817. //从本窗口的最终子窗口开始关闭
  818. var c = function (o) {
  819. o._close();
  820. if (o.hasOwnProperty('parent') && e != o) arguments.callee(o.parent);
  821. //从对象组中删除该实例
  822. DELETE(o.id);
  823. };
  824. c(junior);
  825. return e;
  826. }
  827. //如果关闭回调函数返回false
  828. if (e.o.onClose.call(e) === false) return e;
  829. //如果有触发器
  830. if (e.o.trigger)
  831. {
  832. e._close(true); //隐藏
  833. }
  834. else
  835. {
  836. e._close(); //移除
  837. DELETE(e.id); //从对象组中删除该实例
  838. }
  839. return e;
  840. },
  841. //获取当前对象的最最终子对象
  842. junior : function () {
  843. if (this.child != null) return this.child.junior();
  844. return this;
  845. },
  846. //创建子窗口的扩展方法
  847. dialog : function (o) {
  848. $.extend(o, {refer:this.wrapper});
  849. var e = this.child = $.dialog(o);
  850. e.parent = this;
  851. return e;
  852. },
  853. //左右晃动的效果
  854. shake : function (){
  855. var e = this,
  856. p = [4, 8, 4, 0, -4, -8, -4, 0, 2, 4, 2, 0, -2, -4, -2 , 0, 1, 2, 1, 0, -1, -2, -1, 0],
  857. t = null,
  858. f = function () {
  859. e.wrapper.css('marginLeft', p.shift() + 'px');
  860. if (p.length <= 0) {
  861. e.wrapper.css('marginLeft', 0);
  862. clearInterval(t);
  863. };
  864. };
  865. t = setInterval(f, 12);
  866. return e;
  867. },
  868. __init : function(){
  869. var e = this,
  870. o = e.o;
  871. e.title(o.title)
  872. .tab(o.tab)
  873. .icon(o.icon)
  874. .content(o.content)
  875. .padding(o.padding)
  876. .width(o.width)
  877. .height(o.height)
  878. .offset(o.offset)
  879. .fixed(o.fixed)
  880. .mask(o.mask)
  881. .draggable(o.draggable)
  882. .resizable(o.resizable)
  883. .timeout(o.timeout)
  884. .esc(o.esc)
  885. .onLoad(o.onLoad)
  886. .onEnter(o.onEnter)
  887. .onClose(o.onClose)
  888. ._event();
  889. e._closed = 0;
  890. return e;
  891. },
  892. //初始化一个对话框实例
  893. _init : function(o) {
  894. var e = this,
  895. exists = false;
  896. e.o = {};
  897. e.wrapper = e.child = e.MaskLayer = null;
  898. e.id = '_dialog' + ZINDEX;
  899. e.dom = function () {
  900. var w = this.wrapper,
  901. d = {
  902. drag : w.children('thead'),
  903. title : w.find('.jQ_Dialog_Title span'),
  904. body : w.find('.jQ_Dialog_Body'),
  905. icon : w.find('.jQ_Dialog_Icon p'),
  906. content : w.find('.jQ_Dialog_Content'),
  907. button : w.find('.jQ_Dialog_Button td'),
  908. X : w.find('.jQ_Dialog_X').children(),
  909. resizer : w.find('.jQ_Dialog_Resizer'),
  910. foot : w.find('tfoot td')
  911. };
  912. return d;
  913. };
  914. $.extend(true, e.o, $.dialog.defaults, o); //扩展默认设置的副本
  915. if (typeof e.o.id === 'string') //如果设置了对话框的唯一标识且为字符
  916. {
  917. e.id = e.o.id;
  918. if (e.o.trigger === null) e.o.trigger = e.id;
  919. }
  920. if ($.type(e.o.trigger) === 'object' && !e.o.trigger.nodeType)
  921. {
  922. //如果是jQuery对象,将其转换为HTMLElement
  923. e.o.trigger = e.o.trigger[0];
  924. }
  925. //遍历所有对话框对象,通过其触发器检测对象是否已经存在
  926. $.each($.dialog.list, function (x, y) {
  927. if (y.o.trigger != null && y.o.trigger === e.o.trigger)
  928. {
  929. y.o = e.o;
  930. e.wrapper = y.wrapper;
  931. e.MaskLayer = y.MaskLayer;
  932. y._isReady = y._onLoadCalled = e._w = e._h = 0;
  933. y.show();
  934. if (y._mask !== 1 && y.zIndex < ZINDEX - 1)
  935. {
  936. y.wrapper.css('zIndex', ZINDEX);
  937. y.zIndex = ZINDEX++;
  938. y._setTop();
  939. }
  940. exists = true;
  941. return false;
  942. }
  943. });
  944. //如果对话框对象不存在
  945. if (!exists)
  946. {
  947. e.wrapper = $($.dialog.template);
  948. $("body").append(e.wrapper);
  949. //将其加入全局对话框对象
  950. $.dialog.list[e.id] = e;
  951. e.__init();
  952. if (e._mask !== 1)
  953. {
  954. e.wrapper.css('zIndex', ZINDEX);
  955. e.zIndex = ZINDEX++;
  956. e._setTop();
  957. }
  958. }
  959. return e;
  960. },
  961. _ready : function (b,z) {
  962. var e = this;
  963. if (!e._isReady)
  964. {
  965. var d = e.dom(),
  966. a = d.title.siblings('[data-active]'),
  967. c = d.content,
  968. t = a.data('_m');
  969. if (a.size() > 0)
  970. {
  971. a.removeAttr('data-active').triggerHandler(t);
  972. return;
  973. }
  974. c.data('c', c.html());
  975. e._isReady = 1;
  976. e.button(b);
  977. setTimeout(function () {
  978. e.offset(1);
  979. }, 5);
  980. if (!e._onLoadCalled)
  981. {
  982. setTimeout(function () {
  983. e.o.onLoad.call(e);
  984. }, 8);
  985. e._onLoadCalled = 1;
  986. }
  987. }
  988. else if (z)
  989. {
  990. e.button(b);
  991. }
  992. },
  993. _close : function (hide) {
  994. var e = this;
  995. e.recovery && e.recovery();
  996. if (hide == true)
  997. {
  998. e.wrapper.hide();
  999. }
  1000. else
  1001. {
  1002. e.wrapper.remove();
  1003. if (e.zIndex === ZINDEX - 1) ZINDEX--;
  1004. }
  1005. if (e.MaskLayer != null)
  1006. {
  1007. e.MaskLayer.animate({opacity: 0}, e.o.mask.duration, function(){
  1008. if (hide == true)
  1009. {
  1010. $(this).hide();
  1011. }
  1012. else
  1013. {
  1014. $(this).remove();
  1015. if (e.zIndex === ZINDEX) ZINDEX--;
  1016. e.MaskLayer = null;
  1017. }
  1018. });
  1019. }
  1020. e._closed = 1;
  1021. e._isReady = 0;
  1022. e._onLoadCalled = 0;
  1023. //如果有父窗口,将父窗口的子窗口赋值为null
  1024. if (e.hasOwnProperty('parent')) e.parent.child = null;
  1025. clearInterval(e.timer);
  1026. //关闭对话框后取消绑定ESC和回车事件
  1027. DOC.unbind(e._eventName(EVENT.C));
  1028. WIN.unbind(e._eventName(EVENT.D, EVENT.E));
  1029. //自动激活最顶层的对象
  1030. var i = 0,
  1031. o = e;
  1032. $.each($.dialog.list, function (x, y) {
  1033. if (e.zIndex > y.zIndex)
  1034. {
  1035. if (i === 0)
  1036. {
  1037. i = y.zIndex;
  1038. o = y;
  1039. }
  1040. else if (y.zIndex > i)
  1041. {
  1042. i = y.zIndex;
  1043. o = y;
  1044. }
  1045. }
  1046. });
  1047. o._setTop();
  1048. },
  1049. _event : function () {
  1050. var e = this,
  1051. a = e._eventName(EVENT.A, EVENT.B),
  1052. c = e._eventName(EVENT.D, EVENT.E),
  1053. b = e._eventName(EVENT.C);
  1054. //置顶事件
  1055. e.wrapper.unbind(EVENT.A).bind(EVENT.A, $.proxy(function () {
  1056. if (this.child != null)
  1057. {
  1058. this.child.shake();
  1059. return false;
  1060. }
  1061. if (ZINDEX - this.zIndex >= 2)
  1062. {
  1063. this.zIndex = ZINDEX;
  1064. $.dialog.list[this.id].wrapper.css('z-index', ZINDEX);
  1065. ZINDEX++;
  1066. this._setTop();
  1067. }
  1068. }, e));
  1069. //关闭按钮事件
  1070. e.dom().X.unbind(a).bind(a, $.proxy(e.close, e));
  1071. //ESC和回车事件
  1072. DOC.unbind(b).bind(b,function(event){
  1073. if (e.child != null) return;
  1074. if(event.which === 27 && e.o.esc !== false && !e.wrapper.hasClass(CSS.NOTONTOP)){
  1075. event.result !== false && e.close();
  1076. return false;
  1077. }
  1078. if(event.which === 13 && !e.wrapper.hasClass(CSS.NOTONTOP))
  1079. {
  1080. e.o.onEnter();
  1081. e.dom().button.children('.' + CSS.ENTCLICK).triggerHandler(EVENT.B);
  1082. return false;
  1083. }
  1084. });
  1085. WIN.unbind(c).bind(c, function () {
  1086. e.offset(1);
  1087. });
  1088. },
  1089. _showErr : function () {
  1090. var e = this,
  1091. s = e.o.err;
  1092. if (e.o.showErr)
  1093. {
  1094. e.icon(3).padding(10).content({text : s.content}).button([{text : s.button}]);
  1095. if (e.dom().title.siblings().size() === 0) e.title(s.title);
  1096. }
  1097. },
  1098. _setTop:function () {
  1099. var e = this;
  1100. e.wrapper.removeClass(CSS.NOTONTOP);
  1101. $.each($.dialog.list, function (x, y) {
  1102. if(y.zIndex < e.zIndex) y.wrapper.addClass(CSS.NOTONTOP);
  1103. });
  1104. },
  1105. _eventName : function () {
  1106. var n = '.', r;
  1107. for (var i = 0; i < arguments.length; i++)
  1108. {
  1109. if (r)
  1110. {
  1111. r = r + SPACE + arguments[i] + n + this.id;
  1112. }
  1113. else
  1114. {
  1115. r = arguments[i] + n + this.id;
  1116. }
  1117. }
  1118. return r;
  1119. }
  1120. };
  1121. $.dialog.fn._init.prototype = $.dialog.fn;
  1122. $.fn.dialog = function (o) {
  1123. if (!$.isPlainObject(o)) o = {};
  1124. o.refer = o.trigger = this;
  1125. return $.dialog(o);
  1126. }
  1127. $.dialog.template =
  1128. '<table class="jQ_Dialog">'
  1129. + '<thead>'
  1130. + '<tr>'
  1131. + '<th class="jQ_Dialog_Header_Left"></th>'
  1132. + '<th class="jQ_Dialog_Title"><span></span></th>'
  1133. + '<th class="jQ_Dialog_X"><a href="javascript:void(0)" hidefocus="true"></a></th>'
  1134. + '<th class="jQ_Dialog_Header_Right"></th>'
  1135. + '</tr>'
  1136. + '</thead>'
  1137. + '<tbody>'
  1138. + '<tr>'
  1139. + '<td class="jQ_Dialog_Body_Left"></td>'
  1140. + '<td colspan="2" height="100%">'
  1141. + '<table class="jQ_Dialog_Body">'
  1142. + '<tr><td class="jQ_Dialog_Icon"><p></p></td><td class="jQ_Dialog_Content Loading"></td></tr>'
  1143. + '<tr class="jQ_Dialog_Button"><td colspan="2"></td></tr>'
  1144. + '</table>'
  1145. + '</td>'
  1146. + '<td class="jQ_Dialog_Body_Right"></td>'
  1147. + '</tr>'
  1148. + '</tbody>'
  1149. + '<tfoot>'
  1150. + '<tr>'
  1151. + '<td class="jQ_Dialog_Footer_Left"></td>'
  1152. + '<td class="jQ_Dialog_Footer" colspan="2"></td>'
  1153. + '<td class="jQ_Dialog_Footer_Right"><p class="jQ_Dialog_Resizer"></p></td>'
  1154. + '</tr>'
  1155. + '</tfoot>'
  1156. + '</table>';
  1157. })($);