[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"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>