/*! * artdialog iframetools * date: 2011-11-25 13:54 * http://code.google.com/p/artdialog/ * (c) 2009-2011 tangbin, http://www.planeart.cn * * this is licensed under the gnu lgpl, version 2.1 or later. * for details, see: http://creativecommons.org/licenses/lgpl/2.1/ */ ;(function ($, window, artdialog, undefined) { var _topdialog, _proxydialog, _zindex, _data = '@artdialog.data', _open = '@artdialog.open', _opener = '@artdialog.opener', _winname = window.name = window.name || '@artdialog.winname' + + new date, _isie6 = window.vbarray && !window.xmlhttprequest; $(function () { !window.jquery && document.compatmode === 'backcompat' // 不支持怪异模式,请用主流的xhtml1.0或者html5的doctype申明 && alert('artdialog error: document.compatmode === "backcompat"'); }); /** 获取 artdialog 可跨级调用的最高层的 window 对象 */ var _top = artdialog.top = function () { var top = window, test = function (name) { try { var doc = window[name].document; // 跨域|无权限 doc.getelementsbytagname; // chrome 本地安全限制 } catch (e) { return false; }; return window[name].artdialog // 框架集无法显示第三方元素 && doc.getelementsbytagname('frameset').length === 0; }; if (test('top')) { top = window.top; } else if (test('parent')) { top = window.parent; }; return top; }(); artdialog.parent = _top; // 兼容v4.1之前版本,未来版本将删除此 _topdialog = _top.artdialog; // 获取顶层页面对话框叠加值 _zindex = function () { return _topdialog.defaults.zindex; }; /** * 跨框架数据共享接口 * @see http://www.planeart.cn/?p=1554 * @param {string} 存储的数据名 * @param {any} 将要存储的任意数据(无此项则返回被查询的数据) */ artdialog.data = function (name, value) { var top = artdialog.top, cache = top[_data] || {}; top[_data] = cache; if (value !== undefined) { cache[name] = value; } else { return cache[name]; }; return cache; }; /** * 数据共享删除接口 * @param {string} 删除的数据名 */ artdialog.removedata = function (name) { var cache = artdialog.top[_data]; if (cache && cache[name]) delete cache[name]; }; /** 跨框架普通对话框 */ artdialog.through = _proxydialog = function () { var api = _topdialog.apply(this, arguments); // 缓存从当前 window(可能为iframe)调出所有跨框架对话框, // 以便让当前 window 卸载前去关闭这些对话框。 // 因为iframe注销后也会从内存中删除其创建的对象,这样可以防止回调函数报错 if (_top !== window) artdialog.list[api.config.id] = api; return api; }; // 框架页面卸载前关闭所有穿越的对话框 _top !== window && $(window).bind('unload', function () { var list = artdialog.list, config; for (var i in list) { if (list[i]) { config = list[i].config; if (config) config.duration = 0; // 取消动画 list[i].close(); //delete list[i]; }; }; }); /** * 弹窗 (iframe) * @param {string} 地址 * @param {object} 配置参数. 这里传入的回调函数接收的第1个参数为iframe内部window对象 * @param {boolean} 是否允许缓存. 默认true */ artdialog.open = function (url, options, cache) { options = options || {}; var api, dom, $content, $main, iframe, $iframe, $idoc, iwin, ibody, top = artdialog.top, initcss = 'position:absolute;left:-9999em;top:-9999em;border:none 0;background:transparent', loadcss = 'width:100%;height:100%;border:none 0'; if (cache === false) { var ts = + new date, ret = url.replace(/([?&])_=[^&]*/, "$1_=" + ts ); url = ret + ((ret === url) ? (/\?/.test(url) ? "&" : "?") + "_=" + ts : ""); }; var load = function () { var iwidth, iheight, loading = dom.content.find('.aui_loading'), aconfig = api.config; $content.addclass('aui_state_full'); loading && loading.hide(); try { iwin = iframe.contentwindow; $idoc = $(iwin.document); ibody = iwin.document.body; } catch (e) {// 跨域 iframe.style.csstext = loadcss; aconfig.follow ? api.follow(aconfig.follow) : api.position(aconfig.left, aconfig.top); options.init && options.init.call(api, iwin, top); options.init = null; return; }; // 获取iframe内部尺寸 iwidth = aconfig.width === 'auto' ? $idoc.width() + (_isie6 ? 0 : parseint($(ibody).css('marginleft'))) : aconfig.width; iheight = aconfig.height === 'auto' ? $idoc.height() : aconfig.height; // 适应iframe尺寸 settimeout(function () { iframe.style.csstext = loadcss; }, 0);// settimeout: 防止ie6~7对话框样式渲染异常 api.size(iwidth, iheight); // 调整对话框位置 aconfig.follow ? api.follow(aconfig.follow) : api.position(aconfig.left, aconfig.top); options.init && options.init.call(api, iwin, top); options.init = null; }; var config = { zindex: _zindex(), init: function () { api = this; dom = api.dom; $main = dom.main; $content = dom.content; iframe = api.iframe = top.document.createelement('iframe'); iframe.src = url; iframe.name = 'open' + api.config.id; iframe.style.csstext = initcss; iframe.setattribute('frameborder', 0, 0); iframe.setattribute('allowtransparency', true); $iframe = $(iframe); api.content().appendchild(iframe); iwin = iframe.contentwindow; try { iwin.name = iframe.name; artdialog.data(iframe.name + _open, api); artdialog.data(iframe.name + _opener, window); } catch (e) {}; $iframe.bind('load', load); }, close: function () { $iframe.css('display', 'none').unbind('load', load); if (options.close && options.close.call(this, iframe.contentwindow, top) === false) { return false; }; $content.removeclass('aui_state_full'); // 重要!需要重置iframe地址,否则下次出现的对话框在ie6、7无法聚焦input // ie删除iframe后,iframe仍然会留在内存中出现上述问题,置换src是最容易解决的方法 $iframe[0].src = 'about:blank'; $iframe.remove(); try { artdialog.removedata(iframe.name + _open); artdialog.removedata(iframe.name + _opener); } catch (e) {}; } }; // 回调函数第一个参数指向iframe内部window对象 if (typeof options.ok === 'function') config.ok = function () { return options.ok.call(api, iframe.contentwindow, top); }; if (typeof options.cancel === 'function') config.cancel = function () { return options.cancel.call(api, iframe.contentwindow, top); }; delete options.content; for (var i in options) { if (config[i] === undefined) config[i] = options[i]; }; return _proxydialog(config); }; /** 引用open方法扩展方法(在open打开的iframe内部私有方法) */ artdialog.open.api = artdialog.data(_winname + _open); /** 引用open方法触发来源页面window(在open打开的iframe内部私有方法) */ artdialog.opener = artdialog.data(_winname + _opener) || window; artdialog.open.origin = artdialog.opener; // 兼容v4.1之前版本,未来版本将删除此 /** artdialog.open 打开的iframe页面里关闭对话框快捷方法 */ artdialog.close = function () { var api = artdialog.data(_winname + _open); api && api.close(); return false; }; // 点击iframe内容切换叠加高度 _top != window && $(document).bind('mousedown', function () { var api = artdialog.open.api; api && api.zindex(); }); /** * ajax填充内容 * @param {string} 地址 * @param {object} 配置参数 * @param {boolean} 是否允许缓存. 默认true */ artdialog.load = function(url, options, cache){ cache = cache || false; var opt = options || {}; var config = { zindex: _zindex(), init: function(here){ var api = this, aconfig = api.config; $.ajax({ url: url, success: function (content) { api.content(content); opt.init && opt.init.call(api, here); }, cache: cache }); } }; delete options.content; for (var i in opt) { if (config[i] === undefined) config[i] = opt[i]; }; return _proxydialog(config); }; /** * 警告 * @param {string} 消息内容 */ artdialog.alert = function (content, callback) { return _proxydialog({ id: 'alert', zindex: _zindex(), icon: 'warning', fixed: true, lock: true, content: content, ok: true, close: callback }); }; /** * 确认 * @param {string} 消息内容 * @param {function} 确定按钮回调函数 * @param {function} 取消按钮回调函数 */ artdialog.confirm = function (content, yes, no) { return _proxydialog({ id: 'confirm', zindex: _zindex(), icon: 'question', fixed: true, lock: true, opacity: .1, content: content, ok: function (here) { return yes.call(this, here); }, cancel: function (here) { return no && no.call(this, here); } }); }; /** * 提问 * @param {string} 提问内容 * @param {function} 回调函数. 接收参数:输入值 * @param {string} 默认值 */ artdialog.prompt = function (content, yes, value) { value = value || ''; var input; return _proxydialog({ id: 'prompt', zindex: _zindex(), icon: 'question', fixed: true, lock: true, opacity: .1, content: [ '
', content, '
', '
', '', '
' ].join(''), init: function () { input = this.dom.content.find('input')[0]; input.select(); input.focus(); }, ok: function (here) { return yes && yes.call(this, input.value, here); }, cancel: true }); }; /** * 短暂提示 * @param {string} 提示内容 * @param {number} 显示时间 (默认1.5秒) */ artdialog.tips = function (content, time) { return _proxydialog({ id: 'tips', zindex: _zindex(), title: false, cancel: false, fixed: true, lock: false }) .content('
' + content + '
') .time(time || 1.5); }; // 增强artdialog拖拽体验 // - 防止鼠标落入iframe导致不流畅 // - 对超大对话框拖动优化 $(function () { var event = artdialog.dragevent; if (!event) return; var $window = $(window), $document = $(document), positiontype = _isie6 ? 'absolute' : 'fixed', dragevent = event.prototype, mask = document.createelement('div'), style = mask.style; style.csstext = 'display:none;position:' + positiontype + ';left:0;top:0;width:100%;height:100%;' + 'cursor:move;filter:alpha(opacity=0);opacity:0;background:#fff'; document.body.appendchild(mask); dragevent._start = dragevent.start; dragevent._end = dragevent.end; dragevent.start = function () { var dom = artdialog.focus.dom, main = dom.main[0], iframe = dom.content[0].getelementsbytagname('iframe')[0]; dragevent._start.apply(this, arguments); style.display = 'block'; style.zindex = artdialog.defaults.zindex + 3; if (positiontype === 'absolute') { style.width = $window.width() + 'px'; style.height = $window.height() + 'px'; style.left = $document.scrollleft() + 'px'; style.top = $document.scrolltop() + 'px'; }; if (iframe && main.offsetwidth * main.offsetheight > 307200) { main.style.visibility = 'hidden'; }; }; dragevent.end = function () { var dialog = artdialog.focus; dragevent._end.apply(this, arguments); style.display = 'none'; if (dialog) dialog.dom.main[0].style.visibility = 'visible'; }; }); })(this.art || this.jquery, this, this.artdialog);