[5/13更新]
1,增加对bootstrap的支持,(仅仅是用了bootstrap的样式,行为还是由本插件接管)2,添加了bootstrap的示例页面
现在这种东西网上一抓一大把,而且也都很成熟,自己做一个一是轻量级,完全自定义,二也就一些人问我要一些轻量级插件的时候我推荐给他们用吧,毕竟出了问题我可以直接改,也不需要读别人的代码了,基本需求:
1,拖拽插件
可对任意元素生效
允许设置元素能否超出窗体可见范围
如果不可拖出窗体外,同时可设置元素距离窗体四周的边距 (考虑到有些元素有投影等,需要留出边距显示投影)
允许设置拖拽手柄(必须是该元素DOM树的子级)
2,弹窗插件
初始设置标题/宽高/遮罩等基本功能
可设置拖拽窗体位置
可设置拖拽窗体大小
支持最大化/还原,支持标题栏双击最大化/还原,与windows使用习惯一致,可禁用最大化
单页面可无限弹窗
多个弹窗初始位置会自动层叠,留出每个窗体的标题栏,与windows窗体行为一致
同个页面多个弹窗之间点击,会自动激活点击的窗体,并将其带到最顶层
激活的窗体关闭,会自动激活下一个窗体
支持传入加载html,同域页面,以及跨域页面,加载完成前只有自定义的加载动画
其中,弹窗插件把css留给了外部,可完全自定义,插件内部只保留了部分必要css。窗体的拖动,就顺便用了拖拽插件的实现,不再另合并代码,
开发和测试版本为jQuery1.8.3,并且绑定事件的方法在拖拽插件用的是live/die, 弹窗插件是on/off,总之你用1.7以前,最好 是1.8,应该是没有问题的。
拖拽源码:
//----------------------------------------------------------------------------------------------------// [作 者] walkerwang
// [邮 箱] walkerwzy@gmail.com
// [作者博客] http://walkerwang.cnblogs.com
// [更新日期] 2013-3-11
// [版 本 号] ver0.1.0
// [使用说明]
// $(element).dragable(options)
// options.namespace(string):命名空间,有默认值
// options.outer(boolean):是否允许弹窗超出屏幕范围,默认不允许
// options.offset({left:0,right:0,top:0,bottom:0}):元素与窗体四边的边距,outer=true时才生效
// options.handler(string/dom/jQuery object):拖动手柄,即元素内的某个元素点击才会触发拖动事件,默认为null,支持css选择器、DOM元素,jQuery对象
//=====================================================================================
(function ($) {
$.fn.dragable = function (conf) {
var options = $.extend({}, $.fn.dragable.defaults, conf),
el = options.namespace + "_onmove",
outer = options.namespace + "_outer";
$(this).each(function (i, m) {
var t = $(this), o = $(this);
if (options.handler) o = $(options.handler, this);
o.die('mousedown').live('mousedown', function (e) {
t.data('position', { offset: o.offset(), eventx: e.pageX, eventy: e.pageY }).addClass(el);
if (options.outer) t.addClass(outer);
}).css('cursor', 'move');;
});
$("*").die("mousemove").die("mouseup")
.live('mousemove', function (e) {
var m = $("." + el);
if (m.length == 0) return;
var mdata = m.data('position'), x, y;
if (m.is('.' + outer)) {
x = e.pageX - (mdata.eventx - mdata.offset.left);
y = e.pageY - (mdata.eventy - mdata.offset.top);
}
else {
x = Math.max(0 + (options.offset.left || 0), e.pageX - (mdata.eventx - mdata.offset.left)),
y = Math.max(0 + (options.offset.top || 0), e.pageY - (mdata.eventy - mdata.offset.top)),
wx = $(window).width() - m.width() - (options.offset.right || 0),
wy = $(window).height() - m.height() - (options.offset.bottom || 0);
if (x > wx) x = wx;
if (y > wy) y = wy;
}
m.css({ position: 'absolute', left: x, top: y, margin: 0 });
})
.live('mouseup', function (e) {
$("." + el).removeClass(el);
});
};
$.fn.dragable.defaults = {
namespace: "mydragableplug",
offset: { top: 0, bottom: 0, left: 0, right: 0 },
handler: null,
outer: false
};
})(jQuery);
弹窗源码:
//----------------------------------------------------------------------------------------------------// [作 者] walkerwang// [邮 箱] walkerwzy@gmail.com// [作者博客] http://walkerwang.cnblogs.com// [更新日期] 2013-4-26// [版 本 号] v 0.1.1// [使用方法]// var d=new dialog(options).show();//=====================================================================================var dialog = function (conf) { var self = this, defaults = { namespace: "mydialogplug_",//命名空间、ID前缀 cover: false,//显示遮罩 dragable: true,//可拖拽 resizable: false,//可更改大小 html: '',//加载html字符串 ajax: '',//加载同域页面 iframe: '',//iframe方式加载本域或跨域页面 title: 'Title',//弹窗标题 width: 600,//弹窗宽度 height: 320,//弹窗高度 outer: false,//允许弹窗被拖到窗体可见区域外 dragMargin: {},//如果outer=false,设定弹窗与窗体四周的边距 maximum: true,//允许最大化 loading: ''//加载页面时的提示//可以传入文字,也可以外部用css来定义.dlg-loading的样式 }; //apply options self.options = $.extend({}, defaults, conf); self.options.dragMargin.top = self.options.dragMargin.top || 0; self.options.dragMargin.bottom = self.options.dragMargin.bottom || 0; self.options.dragMargin.left = self.options.dragMargin.left || 0; self.options.dragMargin.right = self.options.dragMargin.right || 0; //variable var str_dlg = '<div class="dlg-container dlg-zindex">' + '<div class="dlg-header">' + '<div class="dlg-op"><span class="dlg-max" style="display:none;"></span><span class="dlg-restore" style="display:none;"></span><span class="dlg-close"></span></div>' + '<div class="dlg-icon"></div>' + '<div class="dlg-title"></div>' + '</div>' + '<div class="dlg-body"></div>' + '<div class="dlg-footer"><div class="dlg-resize"></div></div>' + '</div>', str_cover = '<div class="dlg-cover dlg-zindex"></div>', zindex_start = 100000, maxed = false, resizeObj = self.options.namespace + "_onresize", css = { cover: { height: '100%', width: '100%', opacity: 0.5, backgroundColor: '#fff', position: 'fixed', top: 0, left: 0, display: 'none', zIndex: 99999 }, container: { position: 'absolute', top: '50%', left: '50%' }, close: { cursor: 'pointer' }, body: { backgroundColor: '#fff', overflow: 'hidden' }, loading: {}, resize: { position: 'absolute', right: 0, bottom: 0, width: 15, height: 15, cursor: 'nw-resize' } }, getActiveDialog = function () { return $($('.dlg-container').get().sort(function (a, b) { return parseInt($(b).css('z-index'), 10) - parseInt($(a).css('z-index'), 10); })[0]); }, getMaxZindex = function () { var exists = $('.dlg-zindex'); if (!exists) return zindex_start; var ids = exists.map(function () { return parseInt($(this).css('z-index'), 10); }).get(); return Math.max.apply(Math, ids); }, getStackedMargin = function () { var exists = $('.dlg-container'); return 24 * exists.length; }, getDialogBody = function () { return self.dialog.find('.dlg-body'); }, setDialogCentral = function () { self.dialog.css({ top: '50%', left: '50%', marginLeft: function () { return 0 - parseInt($(this).width() / 2, 10) + getStackedMargin(); }, marginTop: function () { return 0 - parseInt($(this).height() / 2, 10) + getStackedMargin() - 80; } }); }, setIFrameWH = function () { var body = getDialogBody(); body.find('iframe').css({ width: body.width(), height: body.height() }); }, showLoading = function () { getDialogBody().html('<span class="dlg-loading">' + self.options.loading + '</span>'); }, hideLoading = function () { getDialogBody().find('.dlg-loading').remove(); }; //create cover self.cover = null; if (self.options.cover) { if (!self.cover) { self.cover = $(str_cover).hide().css(css.cover).css({ zIndex: getMaxZindex() + 1 }).appendTo($('body')); } }; //create dialog self.dialog = $(str_dlg).hide().appendTo($('body')); self.id = self.options.namespace + $('.dlg-container').length; self.dialog.attr('id', self.id) .css({ zIndex: function () { return getMaxZindex() + 1; } }) .find('.dlg-title').text(self.options.title); self.dialog = $("#" + self.id); //apply style self.dialog.css(css.container) .find('.dlg-close').css(css.close) .end().find('.dlg-body').css(css.body).css({ width: self.options.width, height: self.options.height }) .end().find('.dlg-resize').css(css.resize) .end().find('.dlg-loading').css(css.loading) //attatch event self.dialog.on('mousedown', function () { var o = $(this), thisindexid = parseInt(o.css('z-index'), 10) || zindex_start, maxid = getMaxZindex(); if (o.is('.dlg-close')) return; if (thisindexid == maxid) return; $('.dlg-active').removeClass('dlg-active'); o.addClass('dlg-active').css('zIndex', maxid + 1); }) .find('.dlg-close').on('click', function () { self.close(); }); if (self.options.maximum) { self.dialog.find('.dlg-header').on('dblclick', function () { if (maxed) self.restoreWindow(); else self.maxWindow(); }) .find('.dlg-max').on('click', function () { self.maxWindow(); }) .css('display', 'inline-block') .next('.dlg-restore').on('click', function () { self.restoreWindow(); }) }; $(window).resize(function () { if (maxed) { maxed = false; self.maxWindow(true); return; } }); //dragable if (self.options.dragable) self.dialog.dragable({ handler: '.dlg-header', offset: self.options.dragMargin, outer: self.options.outer }); //resizable if (self.options.resizable) { self.dialog.find('.dlg-resize') .off('mousedown').on('mousedown', function (e) { var body = getDialogBody(); $("." + resizeObj).removeClass(resizeObj); $(this).data({ startx: e.pageX, starty: e.pageY, width: body.width(), height: body.height() }).addClass(resizeObj); }); $('*').off('mousemove').off('mouseup') .on('mousemove', function (e) { var o = $('.' + resizeObj); if (o.length == 0) return; var x = e.pageX - parseInt(o.data('startx'), 10), y = e.pageY - parseInt(o.data('starty'), 10), body = o.parents('.dlg-container').eq(0).find('.dlg-body').eq(0); body.css({ width: function () { return parseInt(o.data('width'), 10) + x; }, height: function () { return parseInt(o.data('height'), 10) + y; } }); setIFrameWH(); }) .on('mouseup', function () { $('.' + resizeObj).removeClass(resizeObj); }); } else { self.dialog.find('.dlg-resize').css({ cursor: 'default', backgroundImage: 'none' }); }; //methods //load contents and show dialog self.show = function () { var body = getDialogBody(); if (self.options.html) { body.html(self.options.html); } else if (self.options.ajax) { showLoading(); body.load('page1.html', function () { hideLoading(); }); } else if (self.options.iframe) { showLoading(); var iframe = $('<iframe/>', { width: body.width(), height: body.height(), src: self.options.iframe }).css({ border: 'none', opacity: 0 }) .appendTo(body) .load(function () { hideLoading(); iframe.animate({ opacity: 1 }) }); } else body.html('content here'); //position setDialogCentral(); //set active $(".dlg-active").removeClass('dlg-active'); self.dialog.addClass('dlg-active').show(); if (self.options.cover) self.cover.show(); return self; }; //close the dialog self.close = function () { if (self.cover) self.cover.remove(); self.dialog.remove(); $('.dlg-active').removeClass('dlg-active'); getActiveDialog().addClass('dlg-active'); return self; }; //add buttons to the footer self.addBtn = function (name, callback) { if (typeof callback !== 'function') callback = null; $("<a/>", { text: name, click: callback, href: '#', class: 'dlg-btn' }).appendTo(self.dialog.find('.dlg-footer')); return self; }; //maximum //@nocache:是否不缓存调整前窗体的大小 self.maxWindow = function (nocache) { if (!self.options.maximum || maxed) return; self.dialog.find('.dlg-max').hide(); var body = getDialogBody(), width = body.width(), height = body.height(); if (!nocache) body.data('before', { width: width, height: height }); body.css({ width: function () { return $(window).width() - 15; }, height: function () { return $(window).height() - self.dialog.find('.dlg-header').height() - self.dialog.find('.dlg-footer').height() - 15; } }); self.dialog.css({ top: 3, left: 5, margin: 0 }) .find('.dlg-restore').css({ display: 'inline-block' }); setIFrameWH(); maxed = true; }; //restore self.restoreWindow = function () { if (!maxed) return; self.dialog.find('.dlg-restore').hide(); var body = getDialogBody(), original = body.data('before'); if (!original) original = { width: 600, height: 320 }; body.css({ width: original.width, height: original.height }); setDialogCentral(); self.dialog.find('.dlg-max').css({ display: 'inline-block' }); setIFrameWH(); maxed = false; } return self;}
演示(略),要想跑起来直接把源码从svn签下来吧,一直用的googlecode,就不发到github了,
【注1】css文件没有打包,直接写到演示页面了,如果觉得还行,想用到项目中去,自己专门建个文件夹存放:js/css/img,其次,主要是为了实现功能,样式没有做过多的要求,都是一次成型的,图标也是用everything在本机上用关键字,如restore.gif之类的搜出来的,一用也不觉得违和,就没继续深入了,总之默认风格比较极简,不满意只有自定义css了
【注2】代码持续有小改动,以上源码是第一次发布的版本,仅作示例,所以最好是到下面地址签出最新代码来
地址:http://jq-intellisense-autocomplete.googlecode.com/svn/trunk/
你会看到两个项目,第一个是我以前做的智能提示插件,前段时间做过一次代码重写,当然量不大,版本已经更新到0.5.1,第二个是今天介绍的,里面有一个演示页面,介绍了基本使用方式,就不再赘述了,如下截图:
调用方式截图:
<script type="text/javascript"><!--google_ad_client = "ca-pub-1944176156128447";/* cnblogs 首页横幅 */google_ad_slot = "5419468456";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>