轻量级jQuery拖拽插件和弹窗插件

时间:2022-05-22 16:04:23

[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/

轻量级jQuery拖拽插件和弹窗插件

你会看到两个项目,第一个是我以前做的智能提示插件,前段时间做过一次代码重写,当然量不大,版本已经更新到0.5.1,第二个是今天介绍的,里面有一个演示页面,介绍了基本使用方式,就不再赘述了,如下截图:

轻量级jQuery拖拽插件和弹窗插件

调用方式截图:

轻量级jQuery拖拽插件和弹窗插件


<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>