我的开源框架之布局组件

需求:

  (1)实现无数量限定列模式布局,仅支持列方式布局即可。

  (2)布局项可以定义是否需要面板(面板依赖于面板组件)。

  (3)可以自定义布局大小或者自适应。

  (4)可以自定义是否可以拖拉改变大小。

  (5)可以自定义是否可以收起。

实现图例:

客户代码:

<body>
    <div id="header" style="height:90px">
     
    </div>
        <div id="layoutContainer"   style="100%;height:500px;">
            <div id="layout_item1"   style="background-color:#ffffff"><div>layout_item1</div></div>
            <div id="layout_item2"   style="background-color:#ffffff">layout_item2</div>
            <div id="layout_item3"  style="background-color:#ffffff">layout_item3</div>
            <div id="layout_item4"  style="background-color:#ffffff">layout_item4</div>
        </div>
    <div id="footer" style="height:30px;background-color:#D2E0F2">       
    </div>
    <script type="text/javascript">
        $(function () {
           var layout= $("#layoutContainer");
           $("#layoutContainer").height($("body").height() - $("#header").innerHeight() - $("#footer").innerHeight()).layout({
                isPanel:false,//布局不需要panel
                items: [{
                            id: 'layout_item1',                       
                             '220px',                          
                            dragable: true,                        
                            isPanel: true, //该项需要panel
                            panelOpts: {    //isPanel= true才有效 可参看 panel的 $.fn.panel.defaults默认值
                                title: '我的标题',
                                iconCls: 'icon-save',
                                collapseable: true //可收缩
                            }
                        }, {
                            id: 'layout_item2',
                             'auto',
                            dragable: true,                         
                            isPanel: true,
                            panelOpts: {    //isPanel= true才有效 可参看 panel的 $.fn.panel.defaults默认值
                                title: '我的标题',
                                iconCls: 'icon-save',
                                collapseable: true //可收缩
                            }
                        }
                        , {
                            id: 'layout_item3',
                            iconCls: '',
                            title: '标题.....',
                            dragable: true
                        }, {
                            id: 'layout_item4',
                            iconCls: '',
                             '220px',
                            title: '标题.....',                           
                            isPanel: true, //该项需要panel
                            panelOpts: {    //isPanel= true才有效 可参看 panel的 $.fn.panel.defaults默认值
                                   title: '我的标题',
                                   iconCls: 'icon-save',
                                   collapseable: true //可收缩
                            }
                        }
                ]
            });
        });
    </script>
</body>

组件代码:

  1 /******************************************
  2 *作者:hjwen
  3 *电邮:hjwen88@126.com
  4 *版本:1.0
  5 *版权许可:中国通用开源许可协议V1.0
  6 *说明:myui-layout定义,布局仅支持列布局,不支持行布局(实际项目中鲜有这个必要)
  7 ******************************************/
  8 (function ($) {
  9     var regionItemArr = [];
 10     /******渲染目标*******/
 11     function renderHtml(target) {
 12         target.addClass('layout-container-background');
 13         var childrens = target.children("div").addClass("layout-item");
 14         var layOpts = target.data('settings');
 15         var isPanel = layOpts.isPanel;
 16         var items = layOpts.items;
 17         var panelItems = [];//需要panel的元素
 18         var panelItemsOpts = [];//panel layOpts
 19         for (var i = 0, len = items.length; i < len; ++i) {
 20             var itemOpt = items[i];
 21             if (typeof itemOpt.isPanel == 'boolean') {
 22                 isPanel = itemOpt.isPanel;
 23             } else {
 24                 isPanel = layOpts.isPanel;
 25             }  
 26             if (typeof itemOpt.width != 'undefined') {
 27                 if (itemOpt.width != 'auto')
 28                     itemOpt.width = typeof itemOpt.width == 'string' ? parseInt(itemOpt.width.replace("px", "")) : itemOpt.width;
 29                 itemOpt.originalWidth = itemOpt.width;//保持原始宽度
 30             }
 31             var id = itemOpt.id;
 32             var itemObj = childrens.filter("#" + id);
 33             itemObj.attr('iscollapsed','0');//设置每一个layout的收缩为false);
 34             var islast = 0;
 35             //添加分割线
 36             if (i < len - 1) {//添加分割条  
 37                 if (i == len - 2 && len > 2) {//最后一个分割线
 38                     id = items[len - 1].id;
 39                     if (typeof items[len - 1].panelOpts != 'undefined') {
 40                         items[len - 1].panelOpts.collapsePostion = 'right';
 41                         items[len - 1].panelOpts.toolbarPostion = 'left';
 42                     }
 43                     islast = 1;                  
 44                 }
 45                 var split = $("<div islast='" + islast + "' foritem="" + id + "" class="layout-item-split"></div>").insertAfter(itemObj);
 46                 if (typeof itemOpt.dragable == 'boolean') {//可拖动
 47                     if (itemOpt.dragable) {
 48                         split.css("cursor", "ew-resize");
 49                         split.mousedown(function (e) {
 50                             var foritem = $(this).attr("foritem");
 51                             if (childrens.filter("#" + foritem).attr("iscollapsed") == '1')//收缩后不可以拖拉
 52                                 return;                           
 53                             var _isLast = $(this).attr("islast");
 54                             var prev = $(this).prev();
 55                             var prevAll = $(this).prevAll();
 56                             var _x = $(this).position().left;
 57                             var w = 0;
 58                             prevAll.each(function (i, o) {
 59                                 var inw = $(o).innerWidth();
 60                                 w = w + inw;
 61                             });
 62                             w = w + 2;
 63                             var dragSplit = $("<div islast='" + _isLast + "' foritem="" + foritem + "" style="height:" + (prev.height() + 1) + "px;left:" + w + "px;position:absolute;top:0px;z-index:9999;background:#AAAAAA;opacity: 0.85;filter:alpha(opacity=85);" class="layout-item-split"></div>").insertAfter(prev);
 64                             dragSplit = dragSplit.draggable({
 65                                 proxy: false,
 66                                 dragArea: target, cursor: 'ew-resize',
 67                                 onStop: function (params) {
 68                                     var item_id = dragSplit.attr("foritem");
 69                                     for (var j in items) {
 70                                         var opt = items[j];
 71                                         if (opt.id === item_id) {
 72                                             if (opt != 'undefined') {
 73                                                 if (typeof opt.width == 'number') {
 74                                                     if (dragSplit.attr("islast") === '0') {
 75                                                         opt.width = opt.width + (params.left - _x);
 76                                                     } else {
 77                                                         opt.width = opt.width - (params.left - _x);
 78                                                     }
 79                                                 } else {
 80                                                     $.each(regionItemArr, function (i, o) {
 81                                                         if ($(o).attr('id') === item_id) {
 82                                                             opt.width = $(o).width() + (params.left - _x);
 83                                                         }
 84                                                     });
 85                                                 }
 86                                                 resizeW(target);
 87                                             }
 88                                             break;
 89                                         }
 90                                     }
 91                                     dragSplit.draggable("destroy");
 92                                     dragSplit.remove();
 93                                 }
 94                             });
 95                             dragSplit.trigger("mousedown", e);
 96                         });
 97                     }
 98                 }                
 99             }
100             //创建内容面板
101             if (isPanel) {
102                 panelItems.push(itemObj);
103                 panelItemsOpts.push(itemOpt);
104             }
105             regionItemArr.push(itemObj);
106         }
107         resizeH(target);
108         resizeW(target);
109         target.append("<div class='clear'/>");
110         $(window).resize(function () {
111             resizeH(target);
112             resizeW(target);
113         });
114         $.each(panelItems, function (i, o) {
115             var itemObj = $(o);
116             var h = itemObj.innerHeight()-1;
117             var itemOpt = panelItemsOpts[i];
118             var defOpts = typeof itemOpt.panelOpts == 'undefined' ? null : itemOpt.panelOpts;
119             var p_id = id + '_panel';
120             itemObj.wrapInner("<div id='" + p_id + "' style='height:" + h + "px;auto'></div>");
121             var panelDiv = itemObj.children("div[id='" + p_id + "']");
122             var panelOpts;
123             if (defOpts != null) {
124                 panelOpts = $.extend({}, $.fn.panel.defaults, defOpts);
125             } else {
126                 panelOpts = $.fn.panel.defaults;
127             }
128             panelOpts.displayBorder = true;
129             panelOpts.maximizable = false;
130             panelOpts.closeable = false;
131             panelOpts.expandable = false;            
132             panelOpts.fillAuto = true;
133             panelOpts.onCollapsed = function (seft, flag) {
134                 if (flag == 0) {//收缩                   
135                     itemObj.attr("iscollapsed",'1');
136                     itemOpt.width = 22;                   
137                 } else {//展开
138                     itemObj.attr("iscollapsed", '0');
139                     itemOpt.width = itemOpt.originalWidth;
140                 }
141                 resizeW(target);
142             };
143             var panelObj = panelDiv.panel(panelOpts);
144         });
145     };
146     //设置高度
147     function resizeH(target) {
148         var h = target.height();
149         target.children("div[class!='clear']").height(h);
150     };
151     //设置宽度
152     function resizeW(target) {
153         var settings = target.data('settings');
154         var opts = target.data('settings').items;
155         var all_w = target.innerWidth();
156         var l_r_w = 0;//
157         var autoDivs = [];
158         for (var i = 0, len = regionItemArr.length; i < len; ++i) {
159             var $item = $(regionItemArr[i]);
160             var id = $item.attr("id");
161             for (var k in opts) {
162                 var opt = opts[k];
163                 if (opt.id === id) {
164                     var _w = opt.width;
165                     if (_w === 'auto' || _w === undefined) {
166                         autoDivs.push($item);
167                     } else if (typeof _w === "string") {
168                         l_r_w = l_r_w + parseInt(_w.replace('px'));
169                     }
170                     else {
171                         l_r_w = l_r_w + _w;
172                     }
173                     if (_w == 0) {
174                         $item.css('display', 'none');
175                     } else {
176                         $item.css('display', 'block');
177                     }
178                     $item.width(_w);
179                     break;
180                 }
181             }
182         }
183         var autoAllWidth = all_w - l_r_w - (regionItemArr.length - 1) * 3;//分割线
184         var w = autoAllWidth / autoDivs.length;
185         for (var i in autoDivs) {
186             var d = autoDivs[i];
187             if (w == 0) {
188                 d.css('display', 'none');
189             } else {
190                 d.css('display', 'block');
191             }
192             d.width(w);
193         }
194     };
195     /********公共函数封装*********/
196     var methods = {
197         init: function (options) {
198             return this.each(function () {
199                 var $this = $(this);
200                 $.fn.layout.defaults.iscollapsed = false;//用于判断是否是收缩到左右侧,默认不收缩
201                 var settings = $this.data('settings');
202                 if (typeof (settings) == 'undefined') {
203                     settings = $.extend({}, $.fn.layout.defaults, options);
204                     $this.data('settings', settings);
205                 } else {
206                     settings = $.extend({}, settings, options);
207                 }
208                 //创建ui布局
209                 renderHtml($this);
210                 if ($.myui.isDebug) {
211                     $.myui.log("jQuery.layout init finish......");
212                 }
213             });
214         },
215         destroy: function (options) {
216             return $(this).each(function () {
217                 var $this = $(this);
218                 $this.removeData('settings');
219             });
220         }
221     };
222     $.fn.layout = function () {
223         var method = arguments[0];
224         if (methods[method]) {
225             method = methods[method];
226             arguments = Array.prototype.slice.call(arguments, 1);
227         } else if (typeof (method) == 'object' || !method) {
228             if ($.myui.isDebug) {
229                 $.myui.log("jQuery.layout init.....");
230             }
231             method = methods.init;
232         } else {
233             $.error('Method ' + method + ' does not exist on jQuery.layout');
234             return this;
235         }
236         return method.apply(this, arguments);
237     };
238     /***默认值
239     options={
240          isPanel: false,//是否需要面板,该值可以被items的设置覆盖
241         items:[ {
242                     id: 'layout_item1',//布局对应的div id                       
243                      '220px', //宽度                         
244                     dragable: true, //是否可以拖拉改变大小                       
245                     isPanel: true, //该项需要panel
246                     panelOpts: {    //isPanel= true才有效 可参看 panel的 $.fn.panel.defaults默认值
247                         title: '我的标题',
248                         iconCls: 'icon-save',
249                         collapseable: true //可收缩
250                     }
251                 }]
252     }******/
253     $.fn.layout.defaults = {
254         isPanel: false,//是否需要面板,该值可以被items的设置覆盖       
255         items: []//布局项的设置
256     };
257 })(jQuery);
View Code
原文地址:https://www.cnblogs.com/hjwen/p/3801316.html