dialog-plus.js 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648
  1. /*! artDialog v6.0.5 | https://github.com/aui/artDialog */
  2. !(function () {
  3. var __modules__ = {};
  4. function require (id) {
  5. var mod = __modules__[id];
  6. var exports = 'exports';
  7. if (typeof mod === 'object') {
  8. return mod;
  9. }
  10. if (!mod[exports]) {
  11. mod[exports] = {};
  12. mod[exports] = mod.call(mod[exports], require, mod[exports], mod) || mod[exports];
  13. }
  14. return mod[exports];
  15. }
  16. function define (path, fn) {
  17. __modules__[path] = fn;
  18. }
  19. define("jquery", function () {
  20. return jQuery;
  21. });
  22. /*!
  23. * PopupJS
  24. * Date: 2014-11-09
  25. * https://github.com/aui/popupjs
  26. * (c) 2009-2014 TangBin, http://www.planeArt.cn
  27. *
  28. * This is licensed under the GNU LGPL, version 2.1 or later.
  29. * For details, see: http://www.gnu.org/licenses/lgpl-2.1.html
  30. */
  31. define("popup", function (require) {
  32. var $ = require("jquery");
  33. var _count = 0;
  34. var _isIE6 = !('minWidth' in $('html')[0].style);
  35. var _isFixed = !_isIE6;
  36. function Popup () {
  37. this.destroyed = false;
  38. this.__popup = $('<div />')
  39. /*使用 <dialog /> 元素可能导致 z-index 永远置顶的问题(chrome)*/
  40. .css({
  41. display: 'none',
  42. position: 'absolute',
  43. /*
  44. left: 0,
  45. top: 0,
  46. bottom: 'auto',
  47. right: 'auto',
  48. margin: 0,
  49. padding: 0,
  50. border: '0 none',
  51. background: 'transparent'
  52. */
  53. outline: 0
  54. })
  55. .attr('tabindex', '-1')
  56. .html(this.innerHTML)
  57. .appendTo('body');
  58. this.__backdrop = this.__mask = $('<div />')
  59. .css({
  60. opacity: .7,
  61. background: '#000'
  62. });
  63. // 使用 HTMLElement 作为外部接口使用,而不是 jquery 对象
  64. // 统一的接口利于未来 Popup 移植到其他 DOM 库中
  65. this.node = this.__popup[0];
  66. this.backdrop = this.__backdrop[0];
  67. _count ++;
  68. }
  69. $.extend(Popup.prototype, {
  70. /**
  71. * 初始化完毕事件,在 show()、showModal() 执行
  72. * @name Popup.prototype.onshow
  73. * @event
  74. */
  75. /**
  76. * 关闭事件,在 close() 执行
  77. * @name Popup.prototype.onclose
  78. * @event
  79. */
  80. /**
  81. * 销毁前事件,在 remove() 前执行
  82. * @name Popup.prototype.onbeforeremove
  83. * @event
  84. */
  85. /**
  86. * 销毁事件,在 remove() 执行
  87. * @name Popup.prototype.onremove
  88. * @event
  89. */
  90. /**
  91. * 重置事件,在 reset() 执行
  92. * @name Popup.prototype.onreset
  93. * @event
  94. */
  95. /**
  96. * 焦点事件,在 foucs() 执行
  97. * @name Popup.prototype.onfocus
  98. * @event
  99. */
  100. /**
  101. * 失焦事件,在 blur() 执行
  102. * @name Popup.prototype.onblur
  103. * @event
  104. */
  105. /** 浮层 DOM 素节点[*] */
  106. node: null,
  107. /** 遮罩 DOM 节点[*] */
  108. backdrop: null,
  109. /** 是否开启固定定位[*] */
  110. fixed: false,
  111. /** 判断对话框是否删除[*] */
  112. destroyed: true,
  113. /** 判断对话框是否显示 */
  114. open: false,
  115. /** close 返回值 */
  116. returnValue: '',
  117. /** 是否自动聚焦 */
  118. autofocus: true,
  119. /** 对齐方式[*] */
  120. align: 'bottom left',
  121. /** 内部的 HTML 字符串 */
  122. innerHTML: '',
  123. /** CSS 类名 */
  124. className: 'ui-popup',
  125. /**
  126. * 显示浮层
  127. * @param {HTMLElement, Event} 指定位置(可选)
  128. */
  129. show: function (anchor) {
  130. if (this.destroyed) {
  131. return this;
  132. }
  133. var that = this;
  134. var popup = this.__popup;
  135. var backdrop = this.__backdrop;
  136. this.__activeElement = this.__getActive();
  137. this.open = true;
  138. this.follow = anchor || this.follow;
  139. // 初始化 show 方法
  140. if (!this.__ready) {
  141. popup
  142. .addClass(this.className)
  143. .attr('role', this.modal ? 'alertdialog' : 'dialog')
  144. .css('position', this.fixed ? 'fixed' : 'absolute');
  145. if (!_isIE6) {
  146. $(window).on('resize', $.proxy(this.reset, this));
  147. }
  148. // 模态浮层的遮罩
  149. if (this.modal) {
  150. var backdropCss = {
  151. position: 'fixed',
  152. left: 0,
  153. top: 0,
  154. width: '100%',
  155. height: '100%',
  156. overflow: 'hidden',
  157. userSelect: 'none',
  158. zIndex: this.zIndex || Popup.zIndex
  159. };
  160. popup.addClass(this.className + '-modal');
  161. if (!_isFixed) {
  162. $.extend(backdropCss, {
  163. position: 'absolute',
  164. width: $(window).width() + 'px',
  165. height: $(document).height() + 'px'
  166. });
  167. }
  168. backdrop
  169. .css(backdropCss)
  170. .attr({tabindex: '0'})
  171. .on('focus', $.proxy(this.focus, this));
  172. // 锁定 tab 的焦点操作
  173. this.__mask = backdrop
  174. .clone(true)
  175. .attr('style', '')
  176. .insertAfter(popup);
  177. backdrop
  178. .addClass(this.className + '-backdrop')
  179. .insertBefore(popup);
  180. this.__ready = true;
  181. }
  182. if (!popup.html()) {
  183. popup.html(this.innerHTML);
  184. }
  185. }
  186. popup
  187. .addClass(this.className + '-show')
  188. .show();
  189. backdrop.show();
  190. this.reset().focus();
  191. this.__dispatchEvent('show');
  192. return this;
  193. },
  194. /** 显示模态浮层。参数参见 show() */
  195. showModal: function () {
  196. this.modal = true;
  197. return this.show.apply(this, arguments);
  198. },
  199. /** 关闭浮层 */
  200. close: function (result) {
  201. if (!this.destroyed && this.open) {
  202. if (result !== undefined) {
  203. this.returnValue = result;
  204. }
  205. this.__popup.hide().removeClass(this.className + '-show');
  206. this.__backdrop.hide();
  207. this.open = false;
  208. this.blur();// 恢复焦点,照顾键盘操作的用户
  209. this.__dispatchEvent('close');
  210. }
  211. return this;
  212. },
  213. /** 销毁浮层 */
  214. remove: function () {
  215. if (this.destroyed) {
  216. return this;
  217. }
  218. this.__dispatchEvent('beforeremove');
  219. if (Popup.current === this) {
  220. Popup.current = null;
  221. }
  222. // 从 DOM 中移除节点
  223. this.__popup.remove();
  224. this.__backdrop.remove();
  225. this.__mask.remove();
  226. if (!_isIE6) {
  227. $(window).off('resize', this.reset);
  228. }
  229. this.__dispatchEvent('remove');
  230. for (var i in this) {
  231. delete this[i];
  232. }
  233. return this;
  234. },
  235. /** 重置位置 */
  236. reset: function () {
  237. var elem = this.follow;
  238. if (elem) {
  239. this.__follow(elem);
  240. } else {
  241. this.__center();
  242. }
  243. this.__dispatchEvent('reset');
  244. return this;
  245. },
  246. /** 让浮层获取焦点 */
  247. focus: function () {
  248. var node = this.node;
  249. var popup = this.__popup;
  250. var current = Popup.current;
  251. var index = this.zIndex = Popup.zIndex ++;
  252. if (current && current !== this) {
  253. current.blur(false);
  254. }
  255. // 检查焦点是否在浮层里面
  256. if (!$.contains(node, this.__getActive())) {
  257. var autofocus = popup.find('[autofocus]')[0];
  258. if (!this._autofocus && autofocus) {
  259. this._autofocus = true;
  260. } else {
  261. autofocus = node;
  262. }
  263. this.__focus(autofocus);
  264. }
  265. // 设置叠加高度
  266. popup.css('zIndex', index);
  267. //this.__backdrop.css('zIndex', index);
  268. Popup.current = this;
  269. popup.addClass(this.className + '-focus');
  270. this.__dispatchEvent('focus');
  271. return this;
  272. },
  273. /** 让浮层失去焦点。将焦点退还给之前的元素,照顾视力障碍用户 */
  274. blur: function () {
  275. var activeElement = this.__activeElement;
  276. var isBlur = arguments[0];
  277. if (isBlur !== false) {
  278. this.__focus(activeElement);
  279. }
  280. this._autofocus = false;
  281. this.__popup.removeClass(this.className + '-focus');
  282. this.__dispatchEvent('blur');
  283. return this;
  284. },
  285. /**
  286. * 添加事件
  287. * @param {String} 事件类型
  288. * @param {Function} 监听函数
  289. */
  290. addEventListener: function (type, callback) {
  291. this.__getEventListener(type).push(callback);
  292. return this;
  293. },
  294. /**
  295. * 删除事件
  296. * @param {String} 事件类型
  297. * @param {Function} 监听函数
  298. */
  299. removeEventListener: function (type, callback) {
  300. var listeners = this.__getEventListener(type);
  301. for (var i = 0; i < listeners.length; i ++) {
  302. if (callback === listeners[i]) {
  303. listeners.splice(i--, 1);
  304. }
  305. }
  306. return this;
  307. },
  308. // 获取事件缓存
  309. __getEventListener: function (type) {
  310. var listener = this.__listener;
  311. if (!listener) {
  312. listener = this.__listener = {};
  313. }
  314. if (!listener[type]) {
  315. listener[type] = [];
  316. }
  317. return listener[type];
  318. },
  319. // 派发事件
  320. __dispatchEvent: function (type) {
  321. var listeners = this.__getEventListener(type);
  322. if (this['on' + type]) {
  323. this['on' + type]();
  324. }
  325. for (var i = 0; i < listeners.length; i ++) {
  326. listeners[i].call(this);
  327. }
  328. },
  329. // 对元素安全聚焦
  330. __focus: function (elem) {
  331. // 防止 iframe 跨域无权限报错
  332. // 防止 IE 不可见元素报错
  333. try {
  334. // ie11 bug: iframe 页面点击会跳到顶部
  335. if (this.autofocus && !/^iframe$/i.test(elem.nodeName)) {
  336. elem.focus();
  337. }
  338. } catch (e) {}
  339. },
  340. // 获取当前焦点的元素
  341. __getActive: function () {
  342. try {// try: ie8~9, iframe #26
  343. var activeElement = document.activeElement;
  344. var contentDocument = activeElement.contentDocument;
  345. var elem = contentDocument && contentDocument.activeElement || activeElement;
  346. return elem;
  347. } catch (e) {}
  348. },
  349. // 居中浮层
  350. __center: function () {
  351. var popup = this.__popup;
  352. var $window = $(window);
  353. var $document = $(document);
  354. var fixed = this.fixed;
  355. var dl = fixed ? 0 : $document.scrollLeft();
  356. var dt = fixed ? 0 : $document.scrollTop();
  357. var ww = $window.width();
  358. var wh = $window.height();
  359. var ow = popup.width();
  360. var oh = popup.height();
  361. var left = (ww - ow) / 2 + dl;
  362. var top = (wh - oh) * 382 / 1000 + dt;// 黄金比例
  363. var style = popup[0].style;
  364. style.left = Math.max(parseInt(left), dl) + 'px';
  365. style.top = Math.max(parseInt(top), dt) + 'px';
  366. },
  367. // 指定位置 @param {HTMLElement, Event} anchor
  368. __follow: function (anchor) {
  369. var $elem = anchor.parentNode && $(anchor);
  370. var popup = this.__popup;
  371. if (this.__followSkin) {
  372. popup.removeClass(this.__followSkin);
  373. }
  374. // 隐藏元素不可用
  375. if ($elem) {
  376. var o = $elem.offset();
  377. if (o.left * o.top < 0) {
  378. return this.__center();
  379. }
  380. }
  381. var that = this;
  382. var fixed = this.fixed;
  383. var $window = $(window);
  384. var $document = $(document);
  385. var winWidth = $window.width();
  386. var winHeight = $window.height();
  387. var docLeft = $document.scrollLeft();
  388. var docTop = $document.scrollTop();
  389. var popupWidth = popup.width();
  390. var popupHeight = popup.height();
  391. var width = $elem ? $elem.outerWidth() : 0;
  392. var height = $elem ? $elem.outerHeight() : 0;
  393. var offset = this.__offset(anchor);
  394. var x = offset.left;
  395. var y = offset.top;
  396. var left = fixed ? x - docLeft : x;
  397. var top = fixed ? y - docTop : y;
  398. var minLeft = fixed ? 0 : docLeft;
  399. var minTop = fixed ? 0 : docTop;
  400. var maxLeft = minLeft + winWidth - popupWidth;
  401. var maxTop = minTop + winHeight - popupHeight;
  402. var css = {};
  403. var align = this.align.split(' ');
  404. var className = this.className + '-';
  405. var reverse = {top: 'bottom', bottom: 'top', left: 'right', right: 'left'};
  406. var name = {top: 'top', bottom: 'top', left: 'left', right: 'left'};
  407. var temp = [{
  408. top: top - popupHeight,
  409. bottom: top + height,
  410. left: left - popupWidth,
  411. right: left + width
  412. }, {
  413. top: top,
  414. bottom: top - popupHeight + height,
  415. left: left,
  416. right: left - popupWidth + width
  417. }];
  418. var center = {
  419. left: left + width / 2 - popupWidth / 2,
  420. top: top + height / 2 - popupHeight / 2
  421. };
  422. var range = {
  423. left: [minLeft, maxLeft],
  424. top: [minTop, maxTop]
  425. };
  426. // 超出可视区域重新适应位置
  427. $.each(align, function (i, val) {
  428. // 超出右或下边界:使用左或者上边对齐
  429. if (temp[i][val] > range[name[val]][1]) {
  430. val = align[i] = reverse[val];
  431. }
  432. // 超出左或右边界:使用右或者下边对齐
  433. if (temp[i][val] < range[name[val]][0]) {
  434. align[i] = reverse[val];
  435. }
  436. });
  437. // 一个参数的情况
  438. if (!align[1]) {
  439. name[align[1]] = name[align[0]] === 'left' ? 'top' : 'left';
  440. temp[1][align[1]] = center[name[align[1]]];
  441. }
  442. //添加follow的css, 为了给css使用
  443. className += align.join('-') + ' '+ this.className+ '-follow';
  444. that.__followSkin = className;
  445. if ($elem) {
  446. popup.addClass(className);
  447. }
  448. css[name[align[0]]] = parseInt(temp[0][align[0]]);
  449. css[name[align[1]]] = parseInt(temp[1][align[1]]);
  450. popup.css(css);
  451. },
  452. // 获取元素相对于页面的位置(包括iframe内的元素)
  453. // 暂时不支持两层以上的 iframe 套嵌
  454. __offset: function (anchor) {
  455. var isNode = anchor.parentNode;
  456. var offset = isNode ? $(anchor).offset() : {
  457. left: anchor.pageX,
  458. top: anchor.pageY
  459. };
  460. anchor = isNode ? anchor : anchor.target;
  461. var ownerDocument = anchor.ownerDocument;
  462. var defaultView = ownerDocument.defaultView || ownerDocument.parentWindow;
  463. if (defaultView == window) {// IE <= 8 只能使用两个等于号
  464. return offset;
  465. }
  466. // {Element: Ifarme}
  467. var frameElement = defaultView.frameElement;
  468. var $ownerDocument = $(ownerDocument);
  469. var docLeft = $ownerDocument.scrollLeft();
  470. var docTop = $ownerDocument.scrollTop();
  471. var frameOffset = $(frameElement).offset();
  472. var frameLeft = frameOffset.left;
  473. var frameTop = frameOffset.top;
  474. return {
  475. left: offset.left + frameLeft - docLeft,
  476. top: offset.top + frameTop - docTop
  477. };
  478. }
  479. });
  480. /** 当前叠加高度 */
  481. Popup.zIndex = 1024;
  482. /** 顶层浮层的实例 */
  483. Popup.current = null;
  484. return Popup;
  485. });
  486. // artDialog - 默认配置
  487. define("dialog-config", {
  488. /* -----已注释的配置继承自 popup.js,仍可以再这里重新定义它----- */
  489. // 对齐方式
  490. //align: 'bottom left',
  491. // 是否固定定位
  492. //fixed: false,
  493. // 对话框叠加高度值(重要:此值不能超过浏览器最大限制)
  494. //zIndex: 1024,
  495. // 设置遮罩背景颜色
  496. backdropBackground: '#000',
  497. // 设置遮罩透明度
  498. backdropOpacity: 0.7,
  499. // 消息内容
  500. content: '<span class="ui-dialog-loading">Loading..</span>',
  501. // 标题
  502. title: '',
  503. // 对话框状态栏区域 HTML 代码
  504. statusbar: '',
  505. // 自定义按钮
  506. button: null,
  507. // 确定按钮回调函数
  508. ok: null,
  509. // 取消按钮回调函数
  510. cancel: null,
  511. // 确定按钮文本
  512. okValue: 'ok',
  513. // 取消按钮文本
  514. cancelValue: 'cancel',
  515. cancelDisplay: true,
  516. // 内容宽度
  517. width: '',
  518. // 内容高度
  519. height: '',
  520. // 内容与边界填充距离
  521. padding: '',
  522. // 对话框自定义 className
  523. skin: '',
  524. // 对话框最外层自定义 className
  525. boxSkin: '',
  526. // 是否支持快捷关闭(点击遮罩层自动关闭)
  527. quickClose: false,
  528. // css 文件路径,留空则不会使用 js 自动加载样式
  529. // 注意:css 只允许加载一个
  530. cssUri: '../css/ui-dialog.css',
  531. // 模板(使用 table 解决 IE7 宽度自适应的 BUG)
  532. // js 使用 i="***" 属性识别结构,其余的均可自定义
  533. innerHTML:
  534. '<div i="dialog" class="ui-dialog">'
  535. + '<div class="ui-dialog-arrow-a"></div>'
  536. + '<div class="ui-dialog-arrow-b"></div>'
  537. + '<table class="ui-dialog-grid">'
  538. + '<tr>'
  539. + '<td i="header" class="ui-dialog-header">'
  540. + '<button i="close" class="ui-dialog-close">&#215;</button>'
  541. + '<div i="title" class="ui-dialog-title"></div>'
  542. + '</td>'
  543. + '</tr>'
  544. + '<tr>'
  545. + '<td i="body" class="ui-dialog-body">'
  546. + '<div i="content" class="ui-dialog-content"></div>'
  547. + '</td>'
  548. + '</tr>'
  549. + '<tr>'
  550. + '<td i="footer" class="ui-dialog-footer">'
  551. + '<div i="statusbar" class="ui-dialog-statusbar"></div>'
  552. + '<div i="button" class="ui-dialog-button"></div>'
  553. + '</td>'
  554. + '</tr>'
  555. + '</table>'
  556. +'</div>'
  557. });
  558. /*!
  559. * artDialog
  560. * Date: 2014-11-09
  561. * https://github.com/aui/artDialog
  562. * (c) 2009-2014 TangBin, http://www.planeArt.cn
  563. *
  564. * This is licensed under the GNU LGPL, version 2.1 or later.
  565. * For details, see: http://www.gnu.org/licenses/lgpl-2.1.html
  566. */
  567. define("dialog", function (require) {
  568. var $ = require("jquery");
  569. var Popup = require("popup");
  570. var defaults = require("dialog-config");
  571. var css = defaults.cssUri;
  572. // css loader: RequireJS & SeaJS
  573. if (css) {
  574. var fn = require[require.toUrl ? 'toUrl' : 'resolve'];
  575. if (fn) {
  576. css = fn(css);
  577. css = '<link rel="stylesheet" href="' + css + '" />';
  578. if ($('base')[0]) {
  579. $('base').before(css);
  580. } else {
  581. $('head').append(css);
  582. }
  583. }
  584. }
  585. var _count = 0;
  586. var _expando = new Date() - 0; // Date.now()
  587. var _isIE6 = !('minWidth' in $('html')[0].style);
  588. var _isMobile = 'createTouch' in document && !('onmousemove' in document)
  589. || /(iPhone|iPad|iPod)/i.test(navigator.userAgent);
  590. var _isFixed = !_isIE6 && !_isMobile;
  591. var artDialog = function (options, ok, cancel) {
  592. var originalOptions = options = options || {};
  593. if (typeof options === 'string' || options.nodeType === 1) {
  594. options = {content: options, fixed: !_isMobile};
  595. }
  596. options = $.extend(true, {}, artDialog.defaults, options);
  597. options.original = originalOptions;
  598. var id = options.id = options.id || _expando + _count;
  599. var api = artDialog.get(id);
  600. // 如果存在同名的对话框对象,则直接返回
  601. if (api) {
  602. return api.focus();
  603. }
  604. // 目前主流移动设备对fixed支持不好,禁用此特性
  605. if (!_isFixed) {
  606. options.fixed = false;
  607. }
  608. // 快捷关闭支持:点击对话框外快速关闭对话框
  609. if (options.quickClose) {
  610. options.modal = true;
  611. options.backdropOpacity = 0;
  612. }
  613. // 按钮组
  614. if (!$.isArray(options.button)) {
  615. options.button = [];
  616. }
  617. // 取消按钮
  618. if (cancel !== undefined) {
  619. options.cancel = cancel;
  620. }
  621. if (options.cancel) {
  622. options.button.push({
  623. id: 'cancel',
  624. value: options.cancelValue,
  625. callback: options.cancel,
  626. display: options.cancelDisplay
  627. });
  628. }
  629. // 确定按钮
  630. if (ok !== undefined) {
  631. options.ok = ok;
  632. }
  633. if (options.ok) {
  634. options.button.push({
  635. id: 'ok',
  636. value: options.okValue,
  637. callback: options.ok,
  638. autofocus: true
  639. });
  640. }
  641. return artDialog.list[id] = new artDialog.create(options);
  642. };
  643. var popup = function () {};
  644. popup.prototype = Popup.prototype;
  645. var prototype = artDialog.prototype = new popup();
  646. artDialog.create = function (options) {
  647. var that = this;
  648. $.extend(this, new Popup());
  649. var originalOptions = options.original;
  650. var $popup = $(this.node).html(options.innerHTML);
  651. var $backdrop = $(this.backdrop);
  652. this.options = options;
  653. this._popup = $popup;
  654. $.each(options, function (name, value) {
  655. if (typeof that[name] === 'function') {
  656. that[name](value);
  657. } else {
  658. that[name] = value;
  659. }
  660. });
  661. // 更新 zIndex 全局配置
  662. if (options.zIndex) {
  663. Popup.zIndex = options.zIndex;
  664. }
  665. // 设置 ARIA 信息
  666. $popup.attr({
  667. 'aria-labelledby': this._$('title')
  668. .attr('id', 'title:' + this.id).attr('id'),
  669. 'aria-describedby': this._$('content')
  670. .attr('id', 'content:' + this.id).attr('id')
  671. });
  672. // 关闭按钮
  673. this._$('close')
  674. .css('display', this.cancel === false ? 'none' : '')
  675. .attr('title', this.cancelValue)
  676. .on('click', function (event) {
  677. that._trigger('cancel');
  678. event.preventDefault();
  679. });
  680. // 添加视觉参数
  681. this._$('dialog').addClass(this.skin);
  682. $popup.addClass(this.boxSkin);
  683. this._$('body').css('padding', this.padding);
  684. // 点击任意空白处关闭对话框
  685. if (options.quickClose) {
  686. $backdrop
  687. .on(
  688. 'onmousedown' in document ? 'mousedown' : 'click',
  689. function () {
  690. that._trigger('cancel');
  691. return false;// 阻止抢夺焦点
  692. });
  693. }
  694. // 遮罩设置
  695. this.addEventListener('show', function () {
  696. $backdrop.css({
  697. opacity: 0,
  698. background: options.backdropBackground
  699. }).animate(
  700. {opacity: options.backdropOpacity}
  701. , 150);
  702. });
  703. // ESC 快捷键关闭对话框
  704. this._esc = function (event) {
  705. var target = event.target;
  706. var nodeName = target.nodeName;
  707. var rinput = /^input|textarea$/i;
  708. var isTop = Popup.current === that;
  709. var keyCode = event.keyCode;
  710. // 避免输入状态中 ESC 误操作关闭
  711. if (!isTop || rinput.test(nodeName) && target.type !== 'button') {
  712. return;
  713. }
  714. if (keyCode === 27) {
  715. that._trigger('cancel');
  716. }
  717. };
  718. $(document).on('keydown', this._esc);
  719. this.addEventListener('remove', function () {
  720. $(document).off('keydown', this._esc);
  721. delete artDialog.list[this.id];
  722. });
  723. _count ++;
  724. artDialog.oncreate(this);
  725. return this;
  726. };
  727. artDialog.create.prototype = prototype;
  728. $.extend(prototype, {
  729. /**
  730. * 显示对话框
  731. * @name artDialog.prototype.show
  732. * @param {HTMLElement Object, Event Object} 指定位置(可选)
  733. */
  734. /**
  735. * 显示对话框(模态)
  736. * @name artDialog.prototype.showModal
  737. * @param {HTMLElement Object, Event Object} 指定位置(可选)
  738. */
  739. /**
  740. * 关闭对话框
  741. * @name artDialog.prototype.close
  742. * @param {String, Number} 返回值,可被 onclose 事件收取(可选)
  743. */
  744. /**
  745. * 销毁对话框
  746. * @name artDialog.prototype.remove
  747. */
  748. /**
  749. * 重置对话框位置
  750. * @name artDialog.prototype.reset
  751. */
  752. /**
  753. * 让对话框聚焦(同时置顶)
  754. * @name artDialog.prototype.focus
  755. */
  756. /**
  757. * 让对话框失焦(同时置顶)
  758. * @name artDialog.prototype.blur
  759. */
  760. /**
  761. * 添加事件
  762. * @param {String} 事件类型
  763. * @param {Function} 监听函数
  764. * @name artDialog.prototype.addEventListener
  765. */
  766. /**
  767. * 删除事件
  768. * @param {String} 事件类型
  769. * @param {Function} 监听函数
  770. * @name artDialog.prototype.removeEventListener
  771. */
  772. /**
  773. * 对话框显示事件,在 show()、showModal() 执行
  774. * @name artDialog.prototype.onshow
  775. * @event
  776. */
  777. /**
  778. * 关闭事件,在 close() 执行
  779. * @name artDialog.prototype.onclose
  780. * @event
  781. */
  782. /**
  783. * 销毁前事件,在 remove() 前执行
  784. * @name artDialog.prototype.onbeforeremove
  785. * @event
  786. */
  787. /**
  788. * 销毁事件,在 remove() 执行
  789. * @name artDialog.prototype.onremove
  790. * @event
  791. */
  792. /**
  793. * 重置事件,在 reset() 执行
  794. * @name artDialog.prototype.onreset
  795. * @event
  796. */
  797. /**
  798. * 焦点事件,在 foucs() 执行
  799. * @name artDialog.prototype.onfocus
  800. * @event
  801. */
  802. /**
  803. * 失焦事件,在 blur() 执行
  804. * @name artDialog.prototype.onblur
  805. * @event
  806. */
  807. /**
  808. * 设置内容
  809. * @param {String, HTMLElement} 内容
  810. */
  811. content: function (html) {
  812. var $content = this._$('content');
  813. // HTMLElement
  814. if (typeof html === 'object') {
  815. html = $(html);
  816. $content.empty('').append(html.show());
  817. this.addEventListener('beforeremove', function () {
  818. $('body').append(html.hide());
  819. });
  820. // String
  821. } else {
  822. $content.html(html);
  823. }
  824. return this.reset();
  825. },
  826. /**
  827. * 设置标题
  828. * @param {String} 标题内容
  829. */
  830. title: function (text) {
  831. this._$('title').html(text);
  832. this._$('header')[text ? 'show' : 'hide']();
  833. return this;
  834. },
  835. /** 设置宽度 */
  836. width: function (value) {
  837. this._$('content').css('width', value);
  838. return this.reset();
  839. },
  840. /** 设置高度 */
  841. height: function (value) {
  842. this._$('content').css('height', value);
  843. return this.reset();
  844. },
  845. /**
  846. * 设置按钮组
  847. * @param {Array, String}
  848. * Options: value, callback, autofocus, disabled
  849. */
  850. button: function (args) {
  851. args = args || [];
  852. var that = this;
  853. var html = '';
  854. var number = 0;
  855. this.callbacks = {};
  856. if (typeof args === 'string') {
  857. html = args;
  858. number ++;
  859. } else {
  860. $.each(args, function (i, val) {
  861. var id = val.id = val.id || val.value;
  862. var style = '';
  863. that.callbacks[id] = val.callback;
  864. if (val.display === false) {
  865. style = ' style="display:none"';
  866. } else {
  867. number ++;
  868. }
  869. html +=
  870. '<button'
  871. + ' type="button"'
  872. + ' i-id="' + id + '"'
  873. + style
  874. + (val.disabled ? ' disabled' : '')
  875. + (val.autofocus ? ' autofocus class="ui-dialog-autofocus"' : '')
  876. + '>'
  877. + val.value
  878. + '</button>';
  879. that._$('button')
  880. .on('click', '[i-id=' + id +']', function (event) {
  881. var $this = $(this);
  882. if (!$this.attr('disabled')) {// IE BUG
  883. that._trigger(id);
  884. }
  885. event.preventDefault();
  886. });
  887. });
  888. }
  889. this._$('button').html(html);
  890. this._$('footer')[number ? 'show' : 'hide']();
  891. return this;
  892. },
  893. statusbar: function (html) {
  894. this._$('statusbar')
  895. .html(html)[html ? 'show' : 'hide']();
  896. return this;
  897. },
  898. _$: function (i) {
  899. return this._popup.find('[i=' + i + ']');
  900. },
  901. // 触发按钮回调函数
  902. _trigger: function (id) {
  903. var fn = this.callbacks[id];
  904. return typeof fn !== 'function' || fn.call(this) !== false ?
  905. this.close().remove() : this;
  906. }
  907. });
  908. artDialog.oncreate = $.noop;
  909. /** 获取最顶层的对话框API */
  910. artDialog.getCurrent = function () {
  911. return Popup.current;
  912. };
  913. /**
  914. * 根据 ID 获取某对话框 API
  915. * @param {String} 对话框 ID
  916. * @return {Object} 对话框 API (实例)
  917. */
  918. artDialog.get = function (id) {
  919. return id === undefined
  920. ? artDialog.list
  921. : artDialog.list[id];
  922. };
  923. artDialog.list = {};
  924. /**
  925. * 默认配置
  926. */
  927. artDialog.defaults = defaults;
  928. return artDialog;
  929. });
  930. /*!
  931. * drag.js
  932. * Date: 2013-12-06
  933. * https://github.com/aui/artDialog
  934. * (c) 2009-2014 TangBin, http://www.planeArt.cn
  935. *
  936. * This is licensed under the GNU LGPL, version 2.1 or later.
  937. * For details, see: http://www.gnu.org/licenses/lgpl-2.1.html
  938. */
  939. define("drag", function (require) {
  940. var $ = require("jquery");
  941. var $window = $(window);
  942. var $document = $(document);
  943. var isTouch = 'createTouch' in document;
  944. var html = document.documentElement;
  945. var isIE6 = !('minWidth' in html.style);
  946. var isLosecapture = !isIE6 && 'onlosecapture' in html;
  947. var isSetCapture = 'setCapture' in html;
  948. var types = {
  949. start: isTouch ? 'touchstart' : 'mousedown',
  950. over: isTouch ? 'touchmove' : 'mousemove',
  951. end: isTouch ? 'touchend' : 'mouseup'
  952. };
  953. var getEvent = isTouch ? function (event) {
  954. if (!event.touches) {
  955. event = event.originalEvent.touches.item(0);
  956. }
  957. return event;
  958. } : function (event) {
  959. return event;
  960. };
  961. var DragEvent = function () {
  962. this.start = $.proxy(this.start, this);
  963. this.over = $.proxy(this.over, this);
  964. this.end = $.proxy(this.end, this);
  965. this.onstart = this.onover = this.onend = $.noop;
  966. };
  967. DragEvent.types = types;
  968. DragEvent.prototype = {
  969. start: function (event) {
  970. event = this.startFix(event);
  971. $document
  972. .on(types.over, this.over)
  973. .on(types.end, this.end);
  974. this.onstart(event);
  975. return false;
  976. },
  977. over: function (event) {
  978. event = this.overFix(event);
  979. this.onover(event);
  980. return false;
  981. },
  982. end: function (event) {
  983. event = this.endFix(event);
  984. $document
  985. .off(types.over, this.over)
  986. .off(types.end, this.end);
  987. this.onend(event);
  988. return false;
  989. },
  990. startFix: function (event) {
  991. event = getEvent(event);
  992. this.target = $(event.target);
  993. this.selectstart = function () {
  994. return false;
  995. };
  996. $document
  997. .on('selectstart', this.selectstart)
  998. .on('dblclick', this.end);
  999. if (isLosecapture) {
  1000. this.target.on('losecapture', this.end);
  1001. } else {
  1002. $window.on('blur', this.end);
  1003. }
  1004. if (isSetCapture) {
  1005. this.target[0].setCapture();
  1006. }
  1007. return event;
  1008. },
  1009. overFix: function (event) {
  1010. event = getEvent(event);
  1011. return event;
  1012. },
  1013. endFix: function (event) {
  1014. event = getEvent(event);
  1015. $document
  1016. .off('selectstart', this.selectstart)
  1017. .off('dblclick', this.end);
  1018. if (isLosecapture) {
  1019. this.target.off('losecapture', this.end);
  1020. } else {
  1021. $window.off('blur', this.end);
  1022. }
  1023. if (isSetCapture) {
  1024. this.target[0].releaseCapture();
  1025. }
  1026. return event;
  1027. }
  1028. };
  1029. /**
  1030. * 启动拖拽
  1031. * @param {HTMLElement} 被拖拽的元素
  1032. * @param {Event} 触发拖拽的事件对象。可选,若无则监听 elem 的按下事件启动
  1033. */
  1034. DragEvent.create = function (elem, event) {
  1035. var $elem = $(elem);
  1036. var dragEvent = new DragEvent();
  1037. var startType = DragEvent.types.start;
  1038. var noop = function () {};
  1039. var className = elem.className
  1040. .replace(/^\s|\s.*/g, '') + '-drag-start';
  1041. var minX;
  1042. var minY;
  1043. var maxX;
  1044. var maxY;
  1045. var api = {
  1046. onstart: noop,
  1047. onover: noop,
  1048. onend: noop,
  1049. off: function () {
  1050. $elem.off(startType, dragEvent.start);
  1051. }
  1052. };
  1053. dragEvent.onstart = function (event) {
  1054. var isFixed = $elem.css('position') === 'fixed';
  1055. var dl = $document.scrollLeft();
  1056. var dt = $document.scrollTop();
  1057. var w = $elem.width();
  1058. var h = $elem.height();
  1059. minX = 0;
  1060. minY = 0;
  1061. maxX = isFixed ? $window.width() - w + minX : $document.width() - w;
  1062. maxY = isFixed ? $window.height() - h + minY : $document.height() - h;
  1063. var offset = $elem.offset();
  1064. var left = this.startLeft = isFixed ? offset.left - dl : offset.left;
  1065. var top = this.startTop = isFixed ? offset.top - dt : offset.top;
  1066. this.clientX = event.clientX;
  1067. this.clientY = event.clientY;
  1068. $elem.addClass(className);
  1069. api.onstart.call(elem, event, left, top);
  1070. };
  1071. dragEvent.onover = function (event) {
  1072. var left = event.clientX - this.clientX + this.startLeft;
  1073. var top = event.clientY - this.clientY + this.startTop;
  1074. var style = $elem[0].style;
  1075. left = Math.max(minX, Math.min(maxX, left));
  1076. top = Math.max(minY, Math.min(maxY, top));
  1077. style.left = left + 'px';
  1078. style.top = top + 'px';
  1079. api.onover.call(elem, event, left, top);
  1080. };
  1081. dragEvent.onend = function (event) {
  1082. var position = $elem.position();
  1083. var left = position.left;
  1084. var top = position.top;
  1085. $elem.removeClass(className);
  1086. api.onend.call(elem, event, left, top);
  1087. };
  1088. dragEvent.off = function () {
  1089. $elem.off(startType, dragEvent.start);
  1090. };
  1091. if (event) {
  1092. dragEvent.start(event);
  1093. } else {
  1094. $elem.on(startType, dragEvent.start);
  1095. }
  1096. return api;
  1097. };
  1098. return DragEvent;
  1099. });
  1100. /*!
  1101. * artDialog-plus
  1102. * Date: 2013-11-09
  1103. * https://github.com/aui/artDialog
  1104. * (c) 2009-2014 TangBin, http://www.planeArt.cn
  1105. *
  1106. * This is licensed under the GNU LGPL, version 2.1 or later.
  1107. * For details, see: http://www.gnu.org/licenses/lgpl-2.1.html
  1108. */
  1109. define("dialog-plus", function (require) {
  1110. var $ = require("jquery");
  1111. var dialog = require("dialog");
  1112. var drag = require("drag");
  1113. dialog.oncreate = function (api) {
  1114. var options = api.options;
  1115. var originalOptions = options.original;
  1116. // 页面地址
  1117. var url = options.url;
  1118. // 页面加载完毕的事件
  1119. var oniframeload = options.oniframeload;
  1120. var $iframe;
  1121. if (url) {
  1122. this.padding = options.padding = 0;
  1123. $iframe = $('<iframe />');
  1124. $iframe.attr({
  1125. src: url,
  1126. name: api.id,
  1127. width: '100%',
  1128. height: '100%',
  1129. allowtransparency: 'yes',
  1130. frameborder: 'no',
  1131. scrolling: 'no'
  1132. })
  1133. .on('load', function () {
  1134. var test;
  1135. try {
  1136. // 跨域测试
  1137. test = $iframe[0].contentWindow.frameElement;
  1138. } catch (e) {}
  1139. if (test) {
  1140. if (!options.width) {
  1141. api.width($iframe.contents().width());
  1142. }
  1143. if (!options.height) {
  1144. api.height($iframe.contents().height());
  1145. }
  1146. }
  1147. if (oniframeload) {
  1148. oniframeload.call(api);
  1149. }
  1150. });
  1151. api.addEventListener('beforeremove', function () {
  1152. // 重要!需要重置iframe地址,否则下次出现的对话框在IE6、7无法聚焦input
  1153. // IE删除iframe后,iframe仍然会留在内存中出现上述问题,置换src是最容易解决的方法
  1154. $iframe.attr('src', 'about:blank').remove();
  1155. }, false);
  1156. api.content($iframe[0]);
  1157. api.iframeNode = $iframe[0];
  1158. }
  1159. // 对于子页面呼出的对话框特殊处理
  1160. // 如果对话框配置来自 iframe
  1161. if (!(originalOptions instanceof Object)) {
  1162. var un = function () {
  1163. api.close().remove();
  1164. };
  1165. // 找到那个 iframe
  1166. for (var i = 0; i < frames.length; i ++) {
  1167. try {
  1168. if (originalOptions instanceof frames[i].Object) {
  1169. // 让 iframe 刷新的时候也关闭对话框,
  1170. // 防止要执行的对象被强制收回导致 IE 报错:“不能执行已释放 Script 的代码”
  1171. $(frames[i]).one('unload', un);
  1172. break;
  1173. }
  1174. } catch (e) {}
  1175. }
  1176. }
  1177. // 拖拽支持
  1178. $(api.node).on(drag.types.start, '[i=title]', function (event) {
  1179. // 排除气泡类型的对话框
  1180. if (!api.follow) {
  1181. api.focus();
  1182. drag.create(api.node, event);
  1183. }
  1184. });
  1185. };
  1186. dialog.get = function (id) {
  1187. // 从 iframe 传入 window 对象
  1188. if (id && id.frameElement) {
  1189. var iframe = id.frameElement;
  1190. var list = dialog.list;
  1191. var api;
  1192. for (var i in list) {
  1193. api = list[i];
  1194. if (api.node.getElementsByTagName('iframe')[0] === iframe) {
  1195. return api;
  1196. }
  1197. }
  1198. // 直接传入 id 的情况
  1199. } else if (id) {
  1200. return dialog.list[id];
  1201. }
  1202. };
  1203. return dialog;
  1204. });
  1205. window.dialog = require("dialog-plus");
  1206. })();