jquery.fn.boxy = function(options) { options = options || {}; return this.each(function() { var node = this.nodename.tolowercase(), self = this; if (node == 'a') { jquery(this).click(function() { var active = boxy.linkedto(this), href = this.getattribute('href'), localoptions = jquery.extend({actuator: this, title: this.title}, options); if (active) { active.show(); } else if (href.indexof('#') >= 0) { var content = jquery(href.substr(href.indexof('#'))), newcontent = content.clone(true); content.remove(); localoptions.unloadonhide = false; new boxy(newcontent, localoptions); } else { // fall back to ajax; could do with a same-origin check if (!localoptions.cache) localoptions.unloadonhide = true; boxy.load(this.href, localoptions); } return false; }); } else if (node == 'form') { jquery(this).bind('submit.boxy', function() { boxy.confirm(options.message || '请确认:', function() { jquery(self).unbind('submit.boxy').submit(); }); return false; }); } }); }; // // boxy class function boxy(element, options) { this.boxy = jquery(boxy.wrapper); jquery.data(this.boxy[0], 'boxy', this); this.visible = false; this.options = jquery.extend({}, boxy.defaults, options || {}); //只在ie6下useiframe才起作用 this.options.useiframe = (this.options.useiframe && jquery.browser.msie && jquery.browser.version < 7); if (this.options.useiframe) { this.options = jquery.extend(this.options, {modal: true}); } if (this.options.modal) { this.options = jquery.extend(this.options, {center: true, draggable: false}); } // options.actuator == dom element that opened this boxy // association will be automatically deleted when this boxy is remove()d if (this.options.actuator) { jquery.data(this.options.actuator, 'active.boxy', this); } this.setcontent(element || "
"); this._setuptitlebar(); this.boxy.css('display', 'none').appendto(document.body); this.totop(); if (this.options.fixed) { if (jquery.browser.msie && jquery.browser.version < 7) { this.options.fixed = false; // ie6 doesn't support fixed positioning } else { this.boxy.addclass('fixed'); } } if (this.options.center && boxy._u(this.options.x, this.options.y)) { this.center(); } else { this.moveto( boxy._u(this.options.x) ? this.options.x : boxy.default_x, boxy._u(this.options.y) ? this.options.y : boxy.default_y ); } if (this.options.show) this.show(); }; boxy.ef = function() {}; jquery.extend(boxy, { wrapper: "" + "" + "" + "" + "
", defaults: { title: null, // titlebar text. titlebar will not be visible if not set. closeable: true, // display close link in titlebar? draggable: true, // can this dialog be dragged? clone: false, // clone content prior to insertion into dialog? actuator: null, // element which opened this dialog center: true, // center dialog in viewport? show: true, // show dialog immediately? modal: false, // make dialog modal? fixed: true, // use fixed positioning, if supported? absolute positioning used otherwise closetext: '', // text to use for default close link unloadonhide: false, // should this dialog be removed from the dom after being hidden? clicktofront: false, // bring dialog to foreground on any click (not just titlebar)? behaviours: boxy.ef, // function used to apply behaviours to all content embedded in dialog. afterdrop: boxy.ef, // callback fired after dialog is dropped. executes in context of boxy instance. aftershow: boxy.ef, // callback fired after dialog becomes visible. executes in context of boxy instance. afterhide: boxy.ef, // callback fired after dialog is hidden. executed in context of boxy instance. beforeunload: boxy.ef, // callback fired after dialog is unloaded. executed in context of boxy instance. useiframe: false }, default_x: 50, default_y: 50, zindex: 1337, dragconfigured: false, // only set up one drag handler for all boxys resizeconfigured: false, dragging: null, // load a url and display in boxy // url - url to load // options keys (any not listed below are passed to boxy constructor) // type: http method, default: get // cache: cache retrieved content? default: false // filter: jquery selector used to filter remote content load: function(url, options) { options = options || {}; var ajax = { url: url, type: 'get', datatype: 'html', cache: false, success: function(html) { html = jquery(html); if (options.filter) html = jquery(options.filter, html); new boxy(html, options); } }; jquery.each(['type', 'cache'], function() { if (this in options) { ajax[this] = options[this]; delete options[this]; } }); jquery.ajax(ajax); }, // allows you to get a handle to the containing boxy instance of any element // e.g. inspect!. // this returns the actual instance of the boxy 'class', not just a dom element. // boxy.get(this).hide() would be valid, for instance. get: function(ele) { var p = jquery(ele).parents('.boxy-wrapper'); return p.length ? jquery.data(p[0], 'boxy') : null; }, // returns the boxy instance which has been linked to a given element via the // 'actuator' constructor option. linkedto: function(ele) { return jquery.data(ele, 'active.boxy'); }, // displays an alert box with a given message, calling optional callback // after dismissal. alert: function(message, callback, options) { return boxy.ask(message, ['确认'], callback, options); }, // displays an alert box with a given message, calling after callback iff // user selects ok. confirm: function(message, after, options) { return boxy.ask(message, ['确认', '取消'], function(response) { if (response == '确认') after(); }, options); }, // asks a question with multiple responses presented as buttons // selected item is returned to a callback method. // answers may be either an array or a hash. if it's an array, the // the callback will received the selected value. if it's a hash, // you'll get the corresponding key. ask: function(question, answers, callback, options) { options = jquery.extend({modal: true, closeable: false}, options || {}, {show: true, unloadonhide: true}); var body = jquery('
').append(jquery('
').html(question)); // ick var map = {}, answerstrings = []; if (answers instanceof array) { for (var i = 0; i < answers.length; i++) { map[answers[i]] = answers[i]; answerstrings.push(answers[i]); } } else { for (var k in answers) { map[answers[k]] = k; answerstrings.push(answers[k]); } } var buttons = jquery('
'); buttons.html(jquery.map(answerstrings, function(v) { //add 给确认对话框的确认取消按钮添加不同的class var btn_index; if(v === "确认"){ btn_index = 1; }else if(v === "取消"){ btn_index = 2; }else{ btn_index = 3; } //add end. include the 'btn_index' below return ""; }).join(' ')); jquery('input[type=button]', buttons).click(function() { var clicked = this; boxy.get(this).hide(function() { if (callback) callback(map[clicked.value]); }); }); body.append(buttons); new boxy(body, options); }, // returns true if a modal boxy is visible, false otherwise ismodalvisible: function() { return jquery('.boxy-modal-blackout').length > 0; }, _u: function() { for (var i = 0; i < arguments.length; i++) if (typeof arguments[i] != 'undefined') return false; return true; }, _handleresize: function(evt) { var d = jquery(document); jquery('.boxy-modal-blackout').css('display', 'none').css({ width: d.width(), height: d.height() }).css('display', 'block'); }, _handledrag: function(evt) { var d; if (d = boxy.dragging) { d[0].boxy.css({left: evt.pagex - d[1], top: evt.pagey - d[2]}); } }, _nextz: function() { return boxy.zindex++; }, _viewport: function() { var d = document.documentelement, b = document.body, w = window; return jquery.extend( jquery.browser.msie ? { left: b.scrollleft || d.scrollleft, top: b.scrolltop || d.scrolltop } : { left: w.pagexoffset, top: w.pageyoffset }, !boxy._u(w.innerwidth) ? { width: w.innerwidth, height: w.innerheight } : (!boxy._u(d) && !boxy._u(d.clientwidth) && d.clientwidth != 0 ? { width: d.clientwidth, height: d.clientheight } : { width: b.clientwidth, height: b.clientheight }) ); } }); boxy.prototype = { // returns the size of this boxy instance without displaying it. // do not use this method if boxy is already visible, use getsize() instead. estimatesize: function() { this.boxy.css({visibility: 'hidden', display: 'block'}); var dims = this.getsize(); this.boxy.css('display', 'none').css('visibility', 'visible'); return dims; }, // returns the dimensions of the entire boxy dialog as [width,height] getsize: function() { return [this.boxy.width(), this.boxy.height()]; }, // returns the dimensions of the content region as [width,height] getcontentsize: function() { var c = this.getcontent(); return [c.width(), c.height()]; }, // returns the position of this dialog as [x,y] getposition: function() { var b = this.boxy[0]; return [b.offsetleft, b.offsettop]; }, // returns the center point of this dialog as [x,y] getcenter: function() { var p = this.getposition(); var s = this.getsize(); return [math.floor(p[0] + s[0] / 2), math.floor(p[1] + s[1] / 2)]; }, // returns a jquery object wrapping the inner boxy region. // not much reason to use this, you're probably more interested in getcontent() getinner: function() { return jquery('.boxy-inner', this.boxy); }, // returns a jquery object wrapping the boxy content region. // this is the user-editable content area (i.e. excludes titlebar) getcontent: function() { return jquery('.boxy-content', this.boxy); }, // replace dialog content setcontent: function(newcontent) { newcontent = jquery(newcontent).css({display: 'block'}).addclass('boxy-content'); if (this.options.clone) newcontent = newcontent.clone(true); this.getcontent().remove(); this.getinner().append(newcontent); this._setupdefaultbehaviours(newcontent); this.options.behaviours.call(this, newcontent); return this; }, // move this dialog to some position, funnily enough moveto: function(x, y) { this.movetox(x).movetoy(y); return this; }, // move this dialog (x-coord only) movetox: function(x) { if (typeof x == 'number') this.boxy.css({left: x}); else this.centerx(); return this; }, // move this dialog (y-coord only) movetoy: function(y) { if (typeof y == 'number') this.boxy.css({top: y}); else this.centery(); return this; }, // move this dialog so that it is centered at (x,y) centerat: function(x, y) { var s = this[this.visible ? 'getsize' : 'estimatesize'](); if (typeof x == 'number') this.movetox(x - s[0] / 2); if (typeof y == 'number') this.movetoy(y - s[1] / 2); return this; }, centeratx: function(x) { return this.centerat(x, null); }, centeraty: function(y) { return this.centerat(null, y); }, // center this dialog in the viewport // axis is optional, can be 'x', 'y'. center: function(axis) { var v = boxy._viewport(); var o = this.options.fixed ? [0, 0] : [v.left, v.top]; if (!axis || axis == 'x') this.centerat(o[0] + v.width / 2, null); if (!axis || axis == 'y') this.centerat(null, o[1] + v.height / 2); return this; }, // center this dialog in the viewport (x-coord only) centerx: function() { return this.center('x'); }, // center this dialog in the viewport (y-coord only) centery: function() { return this.center('y'); }, // resize the content region to a specific size resize: function(width, height, after) { if (!this.visible) return; var bounds = this._getboundsforresize(width, height); this.boxy.css({left: bounds[0], top: bounds[1]}); this.getcontent().css({width: bounds[2], height: bounds[3]}); if (after) after(this); return this; }, // tween the content region to a specific size tween: function(width, height, after) { if (!this.visible) return; var bounds = this._getboundsforresize(width, height); var self = this; this.boxy.stop().animate({left: bounds[0], top: bounds[1]}); this.getcontent().stop().animate({width: bounds[2], height: bounds[3]}, function() { if (after) after(self); }); return this; }, // returns true if this dialog is visible, false otherwise isvisible: function() { return this.visible; }, // make this boxy instance visible show: function() { if (this.visible) return; if (this.options.modal) { var self = this; if (!boxy.resizeconfigured) { boxy.resizeconfigured = true; jquery(window).resize(function() { boxy._handleresize(); }); } this.modalblackout = jquery('
') .css({zindex: boxy._nextz(), opacity: 0.2, width: jquery(document).width(), height: jquery(document).height()}) .appendto(document.body); this.totop(); if (this.options.closeable) { jquery(document.body).bind('keypress.boxy', function(evt) { var key = evt.which || evt.keycode; if (key == 27) { self.hide(); jquery(document.body).unbind('keypress.boxy'); } }); } } this.boxy.stop().css({opacity: 1}).show(); this.visible = true; this._fire('aftershow'); if (this.options.useiframe == true) { this.temp_iframe = jquery(""); //this.temp_iframe.width(this.getsize()[0]); //this.temp_iframe.height(this.getsize()[1]); this.temp_iframe.width(window.screen.width); this.temp_iframe.height($(document).height()); this.temp_iframe[0].zindex = - 1; var v = boxy._viewport(); //this.temp_iframe.css("top",this.getposition()[1]); //this.temp_iframe.css("left",this.getposition()[0]); this.temp_iframe.css("top",0); this.temp_iframe.css("left",0); jquery(document.body).append(this.temp_iframe); this.totop(); } return this; }, //弹层大小会改变时会用到这个方法,boxy.get(this).auto_resize(); auto_resize:function(){ if (this.options.useiframe == true) { this.temp_iframe.width(this.getsize()[0]); this.temp_iframe.height(this.getsize()[1]); } }, // hide this boxy instance hide: function(after) { if (!this.visible) return; var self = this; if (this.options.modal) { jquery(document.body).unbind('keypress.boxy'); this.modalblackout.animate({opacity: 0}, function() { jquery(this).remove(); }); } this.boxy.stop().animate({opacity: 0}, 300, function() { self.boxy.css({display: 'none'}); self.visible = false; self._fire('afterhide'); if (after) after(self); if (self.options.unloadonhide) self.unload(); }); if (this.options.useiframe == true) { jquery("iframe").remove(".bg_iframe"); } return this; }, toggle: function() { this[this.visible ? 'hide' : 'show'](); return this; }, hideandunload: function(after) { this.options.unloadonhide = true; this.hide(after); return this; }, unload: function() { this._fire('beforeunload'); this.boxy.remove(); if (this.options.actuator) { jquery.data(this.options.actuator, 'active.boxy', false); } }, // move this dialog box above all other boxy instances totop: function() { this.boxy.css({zindex: boxy._nextz()}); return this; }, // returns the title of this dialog gettitle: function() { return jquery('> .title-bar h2', this.getinner()).html(); }, // sets the title of this dialog settitle: function(t) { jquery('> .title-bar h2', this.getinner()).html(t); return this; }, // // don't touch these privates _getboundsforresize: function(width, height) { var csize = this.getcontentsize(); var delta = [width - csize[0], height - csize[1]]; var p = this.getposition(); return [math.max(p[0] - delta[0] / 2, 0), math.max(p[1] - delta[1] / 2, 0), width, height]; }, _setuptitlebar: function() { if (this.options.title) { var self = this; var tb = jquery("
").html("

" + this.options.title + "

"); if (this.options.closeable) { tb.append(jquery("").html(this.options.closetext)); } if (this.options.draggable) { tb[0].onselectstart = function() { return false; } tb[0].unselectable = 'on'; tb[0].style.mozuserselect = 'none'; if (!boxy.dragconfigured) { jquery(document).mousemove(boxy._handledrag); boxy.dragconfigured = true; } tb.mousedown(function(evt) { self.totop(); boxy.dragging = [self, evt.pagex - self.boxy[0].offsetleft, evt.pagey - self.boxy[0].offsettop]; jquery(this).addclass('dragging'); }).mouseup(function() { jquery(this).removeclass('dragging'); boxy.dragging = null; self._fire('afterdrop'); }); } this.getinner().prepend(tb); this._setupdefaultbehaviours(tb); } }, _setupdefaultbehaviours: function(root) { var self = this; if (this.options.clicktofront) { root.click(function() { self.totop(); }); } jquery('.close', root).click(function() { self.hide(); return false; }).mousedown(function(evt) { evt.stoppropagation(); }); }, _fire: function(event) { this.options[event].call(this); } }; function setboxycenter() { var _ismobile = { android: function() { return navigator.useragent.match(/android/i) ? true : false; }, blackberry: function() { return navigator.useragent.match(/blackberry/i) ? true : false; }, ios: function() { return navigator.useragent.match(/iphone|ipad|ipod/i) ? true : false; }, windows: function() { return navigator.useragent.match(/iemobile/i) ? true : false; }, any: function() { return (_ismobile.android() || _ismobile.blackberry() || _ismobile.ios() || _ismobile.windows()); } }; if (_ismobile.any()) return; //if (jquery.browser.msie && (jquery.browser.version == "6.0") && !jquery.support.style) return; function funsub() { if ($$("boxy-wrapper")) { if (boxy.ismodalvisible()) { var boxy_clientwidth = document.documentelement.clientwidth; var boxy_clientheight = document.documentelement.clientheight; var boxy_width = $("#boxy-wrapper").css("width").replace("px", ""); var boxy_height = $("#boxy-wrapper").css("height").replace("px", ""); var boxy_newwidth = (math.floor((boxy_clientwidth - boxy_width) / 2)); var boxy_newheight = (math.floor((boxy_clientheight - boxy_height) / 2)); $(".boxy-wrapper").css({ "left": "" + (boxy_newwidth + (jquery.browser.msie ? 0 : 8)) + "px" }); if (jquery.browser.msie && jquery.browser.version < 7) { } else { $(".boxy-wrapper").css({ "top": "" + (boxy_newheight + (jquery.browser.msie ? 0 : 1)) + "px" }); } } } } setinterval(funsub, 10); }