jQuery拖拽布局插件Portal

所属分类:UI-布局

 246434  461  查看评论 (27)
分享到微信朋友圈
X
jQuery拖拽布局插件Portal ie兼容8

更新时间:2017/11/15 上午10:23:16

更新说明:修复ie9,10下不能拖拽问题,感谢网友??①脐胗?提供的解决方案。


实现代码

* Jquery - portal.js Jquery Portal layout可拖拽布局Copyright(C) Jh 2012.4.11@author xiaofan * /
var Jh = {	
	Config:{/ / CLASS样式配置tableCls: "form-list",
tdCls: "form-text",
tdCls2: "single",
ulCls: "tag-list",
layCls: "layout-list",
min: "min",
mintext: "收起",
max: "max",
maxtext: "展开",
close: "close",
closetext: "关闭",
refreshtext: "刷新",
refresh: "refresh",
_groupItemContent: "itemContent",
_groupItemHead: "itemHeader",
_groupWrapperClass: "groupWrapper",
_groupItemClass: "groupItem"
}
};Jh.Layout = function(me) {
	var _left = "portal_l",
	_center = "portal_m",
	_right = "portal_r";
	return me = {
		location: { //三列容器
			left: _left,
			center: _center,
			right: _right
		},
		locationId: {
			left: "#" + _left,
			center: "#" + _center,
			right: "#" + _right
		},
		layoutCss: {
			0 : "1:3",
			1 : "3:1",
			2 : "1:2:1",
			3 : "1:1:2",
			4 : "2:1:1",
			5 : "1:1:1"
		},
		layoutText: {
			0 : "w250 w750 wnone",
			1 : "w750 w250 wnone",
			2 : "w250 w500 w250",
			3 : "w250 w250 w500",
			4 : "w500 w250 w250",
			5 : "w250 w250 w250"
		}
	}
} ();

Jh.Util = { //工具类
	format: function(str, model) { //格式化指定键值的模板
		for (var k in model) {
			var re = new RegExp("{" + k + "}", "g");
			str = str.replace(re, model[k])
		}
		return str
	},
	refresh: function() { //刷新3个布局
		$("#" + Jh.Layout.left, "#" + Jh.Layout.center, "#" + Jh.Layout.right).sortable('refresh');
	},
	toBody: function(o) { //往Body添加对象
		$("body").append(o);
	}
};Jh.fn = function(me) { //功能区
	return me = {
		init: function(data) { //初始化
			me._ele = {};
			me._create();
			me._createWrap(data);
			me._bindEvent();
		},

		_create: function() { //创建自己
			var _box = $("<div id='header'/>");
			me.box = _box;
			Jh.Util.toBody(_box); //往Body里添加自己
		},

		_createWrap: function(d) { //创建外层容器
			var _table = me._createTable(Jh.Config.tableCls);
			me._ele.table = _table me._createModuleList(d);
			me._createActionButton();
			me._addPanel(_table);
		},

		_createTable: function(clsName) { //创建表格		
			var _t = $("<table/>").addClass(clsName);
			$("<tbody/>").append(me._createLayoutTr()).append(me._createBaseTr()).append(me._createActionTr()).appendTo(_t);
			return _t;
		},

		_createBaseTr: function() { //创建功能模块tr
			var _td = me._createTd(Jh.Config.tdCls2),
			_tr = $("<tr>").append(me._createTd(Jh.Config.tdCls, "功能模块设置:")).append(_td);
			me._ele.mtd = _td;
			return _tr;
		},

		_createActionTr: function() { //创建按钮tr
			var _td = me._createTd(Jh.Config.tdCls2),
			_tr = $("<tr>").append(me._createTd(Jh.Config.tdCls)).append(_td);
			me._ele.atd = _td;
			return _tr;
		},

		_createLayoutTr: function() { //创建布局
			var _td = me._createTd(Jh.Config.tdCls2),
			_div = $("<div/>").addClass(Jh.Config.layCls).append(me._createA("1:3")).append(me._createA("3:1")).append(me._createA("1:1:2")).append(me._createA("1:2:1")).append(me._createA("2:1:1")).append("<a href='javascript:void(0);' class='active' rel='1:1:1'>默认</a>").appendTo(_td),
			_tr = $("<tr>").append(me._createTd(Jh.Config.tdCls, "布局设置:")).append(_td);

			me._ele.layoutTd = _td;
			return _tr;
		},

		_createModuleList: function(data) { //创建模块list
			var _ul = $("<ul/>").addClass(Jh.Config.ulCls);
			me._createLis(data.appL, _ul);
			me._createLis(data.appM, _ul);
			me._createLis(data.appR, _ul);
			me._ele.ul = _ul;
			_ul.appendTo(me._ele.mtd);
		},

		_createActionButton: function() { //创建功能按钮
			var _add = $("<a class='button b' href='#' >添加模块</a>");
			var _save = $("<a class='button b' href='#' >保存配置</a>");
			me._ele.atd.append(_add).append(_save);
			me._bindAdd(_add);
			me._bindSave(_save);
		},

		_createLis: function(obj, _ul) { //创建li列表
			$.each(obj,
			function(key, name) {
				_ul.append(me._createLi(key, name));
			});
		},

		_createA: function(text) { //创建A
			return $("<a href='javascript:void(0);' rel='" + text + "'>" + text + "</a>");
		},

		_createLi: function(key, name) { //创建li
			return $("<li/>").append("<a href='#' rel='" + key + "'>" + name + "</a>").append("<span class='ok'></span>");
		},

		_createTd: function(clsName, text) { //创建td
			var t = $("<td>").addClass(clsName);
			if (text != undefined) {
				t.text(text);
			}
			return t;
		},
		_addPanel: function(o) {
			me.box.append(o);
		},

		_bindAdd: function(obj) { //添加模块
			obj.click(function() {
				var clicked = function() {
					var form = $(this).children('form'),
					name = form.children('#modulename').val(),
					key = form.children("#modulekey").val(),
					layout = form.children("input[name='modulelayout']:checked").val(),
					position;
					if (layout == 'left') {
						position = $("#" + Jh.Layout.location.left);
					} else if (layout == 'center') {
						position = $("#" + Jh.Layout.location.center);
					} else {
						position = $("#" + Jh.Layout.location.right);
					}
					me._ele.ul.append(me._createLi(key, name)); //添加功能标签
					position.append(Jh.Portal._createPortalOne(key, name)); //添加portal
					$.fallr('hide');
				};
				$.fallr('show', {
					buttons: {
						button1: {
							text: '确定',
							onclick: clicked
						},
						button2: {
							text: '取消'
						}
					},
					content: '<form style="margin-left:20px">' + '<p>模块名:</p><input type="text" size="15" id="modulename" />' + '<p>模块Code:</p><input type="text" size="15" id="modulekey" />' + '<p>模块位置:</p>左:<input type="radio" name="modulelayout" checked="checked" value="left"/>&nbsp&nbsp' + '中:<input type="radio" name="modulelayout" value="center"/>&nbsp&nbsp' + '右:<input type="radio" name="modulelayout" value="right"/>' + '</form>',
					icon: 'add',
					position: 'center'
				});
			});

		},
		_bindSave: function(obj) { //保存模块配置
			obj.click(function() {
				var _l = $("#" + Jh.Layout.location.left).sortable('toArray'),
				_m = $("#" + Jh.Layout.location.center).sortable('toArray'),
				_r = $("#" + Jh.Layout.location.right).sortable('toArray'),
				_a = $("." + Jh.Config.layCls + " a"),
				_layout = "";
				_a.each(function() {
					if ($(this).hasClass("active")) {
						_layout = $(this).attr("rel");
					}
				});

				if (_layout == "1:1:1") {
					_layout = "默认";
				}
				var baseConfig = "<p>left:[" + _l + "]</p><p>center:[" + _m + "]</p><p>right[" + _r + "]</p>" + "<p>当前布局:" + _layout + "</p>";

				$.fallr('show', {
					content: baseConfig,
					position: 'center'
				});

			});

		},

		_bindEvent: function() { //事件绑定
			me._moduleLiClick();
			me._layoutAClick();
		},

		_moduleLiClick: function() { //绑定模块LI单击事件
			$("." + Jh.Config.ulCls + " li").live("click",
			function() {
				var _this = $(this),
				_mName = _this.find("a").attr("rel"),
				//获取模块名
				_m = $("#" + _mName),
				//模块div 
				_d = _this.find(".ok"); //对号
				if (_d.is(":visible")) { //判断是否显示
					_d.hide(); //隐藏对号
					_m.hide(); //隐藏模块	
				} else {
					_d.show(); //显示对号
					_m.show(); //显示模块
				}
				Jh.Util.refresh();

			});
		},

		_layoutAClick: function() { //绑定布局列表A 单击事件
			$("." + Jh.Config.layCls + " a").click(function() {
				var _this = $(this);
				var _v = _this.attr("rel");
				me._ToLayout(_v);
				_this.addClass("active").siblings().removeClass("active");
			});
		},

		_ToLayout: function(v) { //刷新布局
			var CssMode = Jh.Layout.layoutCss,
			//布局模式  
			CssText = Jh.Layout.layoutText,
			//css 
			ModulesId = Jh.Layout.locationId,
			//模块id
			CssTextId = 0,
			//默认css数组编号
			ModuleItems = ""; //模块数组
			$.each(CssMode,
			function(m, mn) {
				if (v == mn) CssTextId = m; //css 赋值
			});

			$.each(ModulesId,
			function(s, sn) {
				var currentModule = $(sn),
				cssName = CssText[CssTextId],
				ary = cssName.split(/s+/); //得到当前布局css数组
				switch (s) {
				case "left":
					s = 0;
					break;
				case "center":
					s = 1;
					break;
				case "right":
					s = 2;
				}
				if (ary[s] == 'wnone') { //出现布局由3->2的变化	,最右边栏目的内容搬到最左边
					ModuleItems = currentModule.sortable('toArray'); //获取最新的的元素
					$.each(ModuleItems,
					function(m, mn) {
						$("#" + Jh.Layout.location.left).append($("#" + mn)); 
						//注意在两栏三栏间切换的时候 返回已经丢失的模块,而且只能够逐个添加元素,不可以一次添加多个
					});
					currentModule.empty(); //摧毁原有的元素,以免重复出现冲突
				}
				currentModule.removeClass("w250 w750 w500 wnone").addClass(ary[s]); //增加css
			});

		}

	}

} ();Jh.Portal = function(me) { //Portal对象
	var _box = "<div id='portal'></div>",
	_template = { //模板
		l: "<div id='" + Jh.Layout.location.left + "' class='" + Jh.Config._groupWrapperClass + " w250'/>",
		m: "<div id='" + Jh.Layout.location.center + "' class='" + Jh.Config._groupWrapperClass + " w250'/>",
		r: "<div id='" + Jh.Layout.location.right + "' class='" + Jh.Config._groupWrapperClass + " w250'/>",
		portalWrap: "<div id='{key}' class='" + Jh.Config._groupItemClass + "'/>",
		itemHeader: "<div class='" + Jh.Config._groupItemHead + "'><h3>{name}</h3></div>",
		itemContent: "<div class='" + Jh.Config._groupItemContent + "'/>"
	};
	return me = {
		init: function(op) { //初始化			
			me._create();
			me._bindData(op);
			me._bindEvent();
		},

		_create: function() { //创建
			me.box = $(_box);
			me._elements = {};
			me._createModulesWrap();
			Jh.Util.toBody(me.box);
		},

		_bindData: function(op) { //绑定数据
			$.each(op,
			function(key, item) {
				me._createPortal(key, item);
			});
		},

		_createModulesWrap: function() { //创建模块外层容器
			me._elements.m_l = $(_template.l);
			me._elements.m_m = $(_template.m);
			me._elements.m_r = $(_template.r);
			me._addPanel(me._elements.m_l);
			me._addPanel(me._elements.m_m);
			me._addPanel(me._elements.m_r);
		},

		_addPanel: function(o) { //往容器里添加
			me.box.append(o);
		},

		_createPortal: function(key, item) { //创建portal
			var mWrap;
			switch (key) {
			case "appL":
				mWrap = me._elements.m_l;
				break;
			case "appM":
				mWrap = me._elements.m_m;
				break;
			case "appR":
				mWrap = me._elements.m_r;
				break;
			}

			$.each(item,
			function(k, o) {
				mWrap.append(me._createPortalOne(k, o));
			});

		},

		_createPortalOne: function(key, name) { //创建单个portal item
			var itemHeader = me._createItemHeader(name),
			//header
			itemContent = me._createItemContent(),
			//content
			portalWrap = $(Jh.Util.format(_template.portalWrap, {
				"key": key
			})).append(itemHeader).append(itemContent);

			return portalWrap;
		},

		_createItemHeader: function(name) { //创建Head
			var _itemHeader = $(Jh.Util.format(_template.itemHeader, {
				"name": name
			})),
			//格式化header			
			_actionWrap = me._createDiv("action").hide().appendTo(_itemHeader); //创建一个div
			me._createA(Jh.Config.refresh, Jh.Config.refreshtext, true).appendTo(_actionWrap);
			me._createA(Jh.Config.min, Jh.Config.mintext, true).appendTo(_actionWrap);
			me._createA(Jh.Config.max, Jh.Config.maxtext, false).appendTo(_actionWrap);
			me._createA(Jh.Config.close, Jh.Config.closetext, true).appendTo(_actionWrap);

			_itemHeader.hover(function() { //滑过标题出现删除图标
				$(this).find(".action").show();
			},
			function() {
				$(this).find(".action").hide();

			});
			return _itemHeader;
		},

		_createItemContent: function() { //创建content
			var _content = $(_template.itemContent);
			$("<ul style='width:250px;'><li>xiaofanV587</li><li>xiaofanV587</li><li>xiaofanV587</li><li>xiaofanV587</li></ul>").appendTo(_content);
			return _content;
		},

		_createDiv: function(classname) {
			var _div = $("<div/>").addClass(classname);
			return _div;
		},

		_createA: function(classname, title, isShow) { //创建A 
			var _a = $("<a href='javascript:void(0);' class='" + classname + "' title='" + title + "'/>");
			if (!isShow) {
				_a.hide();
			}
			return _a;
		},

		_eventMin: function() {
			$("." + Jh.Config.min).live("click",
			function() { //关闭面板
				var _me = $(this);
				var _groupItem = _me.parent().parent().parent();
				_groupItem.find("." + Jh.Config._groupItemContent).hide();
				_groupItem.find("." + Jh.Config.max).show();
				_me.hide();
			});
		},

		_eventMax: function() {
			$("." + Jh.Config.max).live("click",
			function() { //展开面板
				var _me = $(this),
				_groupItem = _me.parent().parent().parent();
				_groupItem.find("." + Jh.Config._groupItemContent).show();
				_groupItem.find("." + Jh.Config.min).show();
				_me.hide();
			});
		},

		_eventRemove: function() {
			$("." + Jh.Config.close).live("click",
			function() { //移除面板
				var _this = $(this),
				_p = _this.parent().parent().parent(); //得到当前父级面板				
				_p.fadeOut('500',
				function() { //500毫秒后移除
					var _this = $(this);
					var _id = _this.attr("id"); //得到模块id			
					var _a = $(".tag-list").find("a[rel='" + _id + "']");
					_this.remove();
					_a.parent().remove(); //移除功能列表中的li
				});
			});
		},

		_eventRefresh: function() {
			$("." + Jh.Config.refresh).live("click",
			function() { //刷新
				var _me = $(this),
				_groupItem = _me.parent().parent().parent();
				_groupItem.find("ul").empty().append("<li>刷新了</li>");
			});
		},

		_eventSortable: function() { //绑定排序
			$("." + Jh.Config._groupWrapperClass).sortable({
				connectWith: "." + Jh.Config._groupWrapperClass,
				opacity: "0.6",
				dropOnEmpty: true
			}).disableSelection();
		},

		_bindEvent: function() { //绑定面板所有事件		
			me._eventSortable();
			me._eventRefresh();
			me._eventRemove();
			me._eventMax();
			me._eventMin();
		}

	};
} ();
相关插件-布局

基于BS的后台管理页面

基于BS的后台管理页面
  布局
 69979  603

基于swiper滑动触摸模板

可左右滑动的手机模板.
  布局
 31903  360

响应式后台管理模板Cameo Admin

简洁大方的响应式后台管理模板Cameo Admin
  布局
 71097  591

jQuery bootstrap响应式单页网站模板

jQuery bootstrap响应式简洁的紫色风格单页网站模板
  布局
 20357  253

讨论这个项目(27)回答他人问题或分享插件使用方法奖励jQ币 评论用户自律公约

    crownclownwl 0
    2020/3/19 9:41:43
    感觉写的效果不错呀,享用到公司的项目里,可以商用不呀 作者? 回复
    ? 偏执的想念 0
    2019/9/3 10:57:21
    下载的js跟你这里的不一样 回复
    Mrs白 0
    2018/12/28 17:01:15
    这个添加新模块是有问题吗?为什么添加新的标题可以,内容不对 回复
    Michael 0
    2018/10/11 15:25:15
    IOi 0
    2018/4/18 14:27:59
    不一样の精彩 0
    2018/4/3 10:34:19
    感觉不太好拖拽啊?????? 回复
    Mr・未名 0
    2018/1/9 11:21:34

    把你修改后的代码替换待Jh.js里  什么都出不来了。

        IOi0
        2018/4/18 14:27:02
        非常棒!
    回复
    你听我说 0
    2017/12/1 9:05:17
    ??①脐胗? 3
    2017/11/15 9:59:27

    需要兼容ie9,10的可以看一下这个网页,刚试了一下可以的,IE不兼容是因为监听不到事件。

    在下载的插件包中查找文件 js/ui.core.min.js 并用编辑器打开,ctrl+f 查找

    if (c.browser.msie && !j.button) { //该行代码

    在前面添加

     if ($.browser.msie && document.documentMode >= 9) {
         j.button = 1        
     }
    回复
    gyx_jq 0
    2017/10/11 15:45:55

    升级了jquery库,就不能用了

    回复
😃
  • 😀
  • 😉
  • 😥
  • 😵
  • 😫
  • 😘
  • 😡
  • 👍
  • 🌹
  • 👏
  • 🍺
  • 🍉
  • 🌙
  • 💖
  • 💔
😃
  • 😀
  • 😉
  • 😥
  • 😵
  • 😫
  • 😘
  • 😡
  • 👍
  • 🌹
  • 👏
  • 🍺
  • 🍉
  • 🌙
  • 💖
  • 💔
取消回复