封装一个Drop and Drag面板控件,供大家分享

本文介绍了一种仿照Google个性化主页实现的可拖拽布局管理器。通过自定义JavaScript库和.NET Web控件实现了模块化的页面布局,允许用户自由调整面板位置。文中详细解释了布局管理器的工作原理和技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      一直想封装一个像Google个性主页那样的可拖动布局管理器,供管理后台作为默认首页使用。
      在网上搜了一下,找到此篇文章 对google个性主页的拖拽效果的js的完整注释。在此先向原作者致敬,没有这篇文章,我是没法封装此控件的:)
      不用多说,先附上效果图:
     
      DragDrop.js(就是原作者提供的js文件,没有做太多改动)
      
ContractedBlock.gif ExpandedBlockStart.gif Code
  1var Util = new Object();
  2Util.getUserAgent = navigator.userAgent;
  3Util.isGecko = Util.getUserAgent.indexOf("Gecko"!= -1;
  4Util.isOpera = Util.getUserAgent.indexOf("Opera"!= -1;
  5ExpandedBlockStart.gifContractedBlock.gifUtil.getOffset = function(el, isLeft) {
  6    var retValue = 0;
  7ExpandedSubBlockStart.gifContractedSubBlock.gif    while (el != null{
  8        retValue += el["offset" + (isLeft ? "Left" : "Top")];
  9        el = el.offsetParent;
 10    }

 11    return retValue;
 12}
;
 13
 14ExpandedBlockStart.gifContractedBlock.gifUtil.bindFunction = function(el, fucName) {
 15ExpandedSubBlockStart.gifContractedSubBlock.gif    return function() {
 16        return el[fucName].apply(el, arguments);
 17    }
;
 18}
;
 19
 20ExpandedBlockStart.gifContractedBlock.gifUtil.re_calcOff = function(el) {
 21ExpandedSubBlockStart.gifContractedSubBlock.gif    for (var i = 0; i < Util.dragArray.length; i++{
 22        var ele = Util.dragArray[i];
 23        ele.elm.pagePosLeft = Util.getOffset(ele.elm, true);
 24        ele.elm.pagePosTop = Util.getOffset(ele.elm, false);
 25    }

 26    var nextSib = el.elm.nextSibling;
 27ExpandedSubBlockStart.gifContractedSubBlock.gif    while (nextSib) {
 28        nextSib.pagePosTop -= el.elm.offsetHeight;
 29        nextSib = nextSib.nextSibling;
 30    }

 31}
;
 32
 33ExpandedBlockStart.gifContractedBlock.gifUtil.hide = function() {
 34    Util.rootElement.style.display = "none";
 35}
;
 36ExpandedBlockStart.gifContractedBlock.gifUtil.show = function() {
 37    Util.rootElement.style.display = "";
 38}
;
 39
 40ghostElement = null;
 41ExpandedBlockStart.gifContractedBlock.gifgetGhostElement = function() {
 42ExpandedSubBlockStart.gifContractedSubBlock.gif    if (!ghostElement) {
 43        ghostElement = document.createElement("DIV");
 44        ghostElement.backgroundColor = "";
 45        ghostElement.style.border = "2px dashed #aaa";
 46        ghostElement.innerHTML = "&nbsp;";
 47    }

 48    return ghostElement;
 49}
;
 50
 51ExpandedBlockStart.gifContractedBlock.giffunction draggable(el) {
 52    this._dragStart = start_Drag;
 53    this._drag = when_Drag;
 54    this._dragEnd = end_Drag;
 55    this._afterDrag = after_Drag;
 56    this.isDragging = false;
 57    this.elm = el;
 58    this.header = document.getElementById(el.id + "_h");
 59    this.hasIFrame = this.elm.getElementsByTagName("IFRAME").length > 0;
 60ExpandedSubBlockStart.gifContractedSubBlock.gif    if (this.header) {
 61        this.header.style.cursor = "move";
 62        Drag.init(this.header, this.elm);
 63        this.elm.onDragStart = Util.bindFunction(this"_dragStart");
 64        this.elm.onDrag = Util.bindFunction(this"_drag");
 65        this.elm.onDragEnd = Util.bindFunction(this"_dragEnd");
 66    }

 67}
;
 68
 69ExpandedBlockStart.gifContractedBlock.giffunction start_Drag() {
 70    Util.re_calcOff(this);
 71    this.origNextSibling = this.elm.nextSibling;
 72    var _ghostElement = getGhostElement();
 73    var offH = this.elm.offsetHeight;
 74ExpandedSubBlockStart.gifContractedSubBlock.gif    if (Util.isGecko) {
 75        offH -= parseInt(_ghostElement.style.borderTopWidth) * 2;
 76    }

 77    var offW = this.elm.offsetWidth;
 78    var offLeft = Util.getOffset(this.elm, true);
 79    var offTop = Util.getOffset(this.elm, false);
 80    Util.hide();
 81    this.elm.style.width = offW + "px";
 82    _ghostElement.style.height = offH + "px";
 83    this.elm.parentNode.insertBefore(_ghostElement, this.elm.nextSibling);
 84    this.elm.style.position = "absolute";
 85    this.elm.style.zIndex = 100;
 86    this.elm.style.left = offLeft + "px";
 87    this.elm.style.top = offTop + "px";
 88    Util.show();
 89    this.isDragging = false;
 90    return false;
 91}
;
 92ExpandedBlockStart.gifContractedBlock.giffunction when_Drag(clientX, clientY) {
 93ExpandedSubBlockStart.gifContractedSubBlock.gif    if (!this.isDragging) {
 94        this.elm.style.filter = "alpha(opacity=70)";
 95        this.elm.style.opacity = 0.7;
 96        this.isDragging = true;
 97    }

 98    var found = null;
 99    var max_distance = 100000000;
100ExpandedSubBlockStart.gifContractedSubBlock.gif    for (var i = 0; i < Util.dragArray.length; i++{
101        var ele = Util.dragArray[i];
102        var distance = Math.sqrt(Math.pow(clientX - ele.elm.pagePosLeft, 2+ Math.pow(clientY - ele.elm.pagePosTop, 2));
103ExpandedSubBlockStart.gifContractedSubBlock.gif        if (ele == this{
104            continue;
105        }

106ExpandedSubBlockStart.gifContractedSubBlock.gif        if (isNaN(distance)) {
107            continue;
108        }

109ExpandedSubBlockStart.gifContractedSubBlock.gif        if (distance < max_distance) {
110            max_distance = distance;
111            found = ele;
112        }

113    }

114    var _ghostElement = getGhostElement();
115ExpandedSubBlockStart.gifContractedSubBlock.gif    if (found != null && _ghostElement.nextSibling != found.elm) {
116        found.elm.parentNode.insertBefore(_ghostElement, found.elm);
117ExpandedSubBlockStart.gifContractedSubBlock.gif        if (Util.isOpera) {
118            document.body.style.display = "none";
119            document.body.style.display = "";
120        }

121    }

122}
;
123ExpandedBlockStart.gifContractedBlock.giffunction end_Drag() {
124ExpandedSubBlockStart.gifContractedSubBlock.gif    if (this._afterDrag()) {
125    }

126    return true;
127}
;
128ExpandedBlockStart.gifContractedBlock.giffunction after_Drag() {
129    var returnValue = false;
130    Util.hide();
131    this.elm.style.position = "";
132    this.elm.style.width = "";
133    this.elm.style.zIndex = "";
134    this.elm.style.filter = "";
135    this.elm.style.opacity = "";
136    var ele = getGhostElement();
137ExpandedSubBlockStart.gifContractedSubBlock.gif    if (ele.nextSibling != this.origNextSibling) {
138        ele.parentNode.insertBefore(this.elm, ele.nextSibling);
139        returnValue = true;
140    }

141    ele.parentNode.removeChild(ele);
142    Util.show();
143ExpandedSubBlockStart.gifContractedSubBlock.gif    if (Util.isOpera) {
144        document.body.style.display = "none";
145        document.body.style.display = "";
146    }

147    return returnValue;
148}
;
149ExpandedBlockStart.gifContractedBlock.gifvar Drag = {
150    obj: null,
151ExpandedSubBlockStart.gifContractedSubBlock.gif    init: function(elementHeader, element) {
152        elementHeader.onmousedown = Drag.start;
153        elementHeader.obj = element;
154ExpandedSubBlockStart.gifContractedSubBlock.gif        if (isNaN(parseInt(element.style.left))) {
155            element.style.left = "0px";
156        }

157ExpandedSubBlockStart.gifContractedSubBlock.gif        if (isNaN(parseInt(element.style.top))) {
158            element.style.top = "0px";
159        }

160        element.onDragStart = new Function();
161        element.onDragEnd = new Function();
162        element.onDrag = new Function();
163    }
,
164ExpandedSubBlockStart.gifContractedSubBlock.gif    start: function(event) {
165        var element = Drag.obj = this.obj;
166        event = Drag.fixE(event);
167ExpandedSubBlockStart.gifContractedSubBlock.gif        if (event.which != 1{
168            return true;
169        }

170        element.onDragStart();
171        element.lastMouseX = event.clientX;
172        element.lastMouseY = event.clientY;
173        document.onmouseup = Drag.end;
174        document.onmousemove = Drag.drag;
175        return false;
176    }
,
177ExpandedSubBlockStart.gifContractedSubBlock.gif    drag: function(event) {
178        event = Drag.fixE(event);
179ExpandedSubBlockStart.gifContractedSubBlock.gif        if (event.which == 0{
180            return Drag.end();
181        }

182        var element = Drag.obj;
183        var _clientX = event.clientY;
184        var _clientY = event.clientX;
185ExpandedSubBlockStart.gifContractedSubBlock.gif        if (element.lastMouseX == _clientY && element.lastMouseY == _clientX) {
186            return false;
187        }

188        var _lastX = parseInt(element.style.top);
189        var _lastY = parseInt(element.style.left);
190        var newX, newY;
191        newX = _lastY + _clientY - element.lastMouseX;
192        newY = _lastX + _clientX - element.lastMouseY;
193        element.style.left = newX + "px";
194        element.style.top = newY + "px";
195        element.lastMouseX = _clientY;
196        element.lastMouseY = _clientX;
197        element.onDrag(newX, newY);
198        return false;
199    }
,
200ExpandedSubBlockStart.gifContractedSubBlock.gif    end: function(event) {
201        event = Drag.fixE(event);
202        document.onmousemove = null;
203        document.onmouseup = null;
204        var _onDragEndFuc = Drag.obj.onDragEnd();
205        Drag.obj = null;
206        return _onDragEndFuc;
207    }
,
208ExpandedSubBlockStart.gifContractedSubBlock.gif    fixE: function(ig_) {
209ExpandedSubBlockStart.gifContractedSubBlock.gif        if (typeof ig_ == "undefined"{
210            ig_ = window.event;
211        }

212ExpandedSubBlockStart.gifContractedSubBlock.gif        if (typeof ig_.layerX == "undefined"{
213            ig_.layerX = ig_.offsetX;
214        }

215ExpandedSubBlockStart.gifContractedSubBlock.gif        if (typeof ig_.layerY == "undefined"{
216            ig_.layerY = ig_.offsetY;
217        }

218ExpandedSubBlockStart.gifContractedSubBlock.gif        if (typeof ig_.which == "undefined"{
219            ig_.which = ig_.button;
220        }

221        return ig_;
222    }

223}
;
224
225ExpandedBlockStart.gifContractedBlock.gifvar _IG_initDrag = function(el) {
226    Util.rootElement = el;
227    Util._rows = Util.rootElement.rows[0];
228    Util.column = Util._rows.cells;
229    Util.dragArray = new Array();
230    var counter = 0;
231ExpandedSubBlockStart.gifContractedSubBlock.gif    for (var i = 0; i < Util.column.length; i++{
232        var ele = Util.column[i];
233ExpandedSubBlockStart.gifContractedSubBlock.gif        for (var j = 0; j < ele.childNodes.length; j++{
234            var ele1 = ele.childNodes[j];
235ExpandedSubBlockStart.gifContractedSubBlock.gif            if (ele1.tagName == "DIV"{
236                Util.dragArray[counter] = new draggable(ele1);
237                counter++;
238            }

239        }

240    }

241}
;
242
243ExpandedBlockStart.gifContractedBlock.gifvar _IG_closePanel = function(id) {
244    document.getElementById(id).style.display = "none";
245}
;
      控件容器DragDrop.cs
      
ContractedBlock.gif ExpandedBlockStart.gif Code
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.IO;
  6using System.Web;
  7using System.ComponentModel;
  8using System.Web.UI;
  9using System.Web.UI.Design;
 10using System.Web.UI.WebControls;
 11
 12[assembly: WebResource("pqmagic.Common.UI.Resources.DragDrop.js""text/javascript")]
 13namespace pqmagic.Common.UI
 14ExpandedBlockStart.gifContractedBlock.gif{
 15    [
 16        ToolboxData("<{0}:DragDrop runat=\"server\"></{0}:DragDrop>"),
 17        Designer(typeof(SubContainerControlDesigner)),
 18        ParseChildren(typeof(DragDropPanel)),
 19        PersistChildren(true)
 20    ]
 21    public class DragDrop : WebControl
 22ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 23        private int repeatColumns = 3;
 24
 25ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 26        /// 重复数
 27        /// </summary>

 28        [
 29        Browsable(true),
 30        Description("设置/获取重复数"),
 31        Category("Misc"),
 32        DefaultValue("3")
 33        ]
 34        public int RepeatColumns
 35ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 36            get
 37ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 38                return repeatColumns;
 39            }

 40            set
 41ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 42                repeatColumns = value;
 43            }

 44        }

 45
 46        protected override HtmlTextWriterTag TagKey
 47ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 48            get
 49ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 50                return HtmlTextWriterTag.Table;
 51            }

 52        }

 53
 54        protected override void OnPreRender(EventArgs e)
 55ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 56            if (!Page.ClientScript.IsClientScriptIncludeRegistered("DragDrop"))
 57ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 58                Page.ClientScript.RegisterClientScriptInclude("DragDrop", Page.ClientScript.GetWebResourceUrl(this.GetType(), "pqmagic.Common.UI.Resources.DragDrop.js"));
 59            }

 60            Page.ClientScript.RegisterStartupScript(this.GetType(), "InitDragDrop""window.onload=function(){var _table = document.getElementById('"+ID+"');_IG_initDrag(_table);};",true);
 61            base.OnPreRender(e);
 62        }

 63
 64        protected override void AddAttributesToRender(HtmlTextWriter writer)
 65ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 66            writer.AddStyleAttribute(HtmlTextWriterStyle.TextAlign, "center");
 67            base.AddAttributesToRender(writer);
 68        }

 69
 70        protected override void RenderContents(HtmlTextWriter writer)
 71ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 72            writer.Write("<tr>");
 73            for (int i = 0; i < repeatColumns; i++)
 74ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 75ExpandedSubBlockStart.gifContractedSubBlock.gif                writer.Write(string.Format("<td style=\"padding:3px;width:{0};vertical-align:top\">"new Unit(100 / repeatColumns, UnitType.Percentage)));
 76                for (int j = i;j< DragDropPanels.Count; j+=repeatColumns)
 77ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 78                    DragDropPanels[j].RenderControl(writer);
 79                }

 80                writer.Write("</td>");
 81            }

 82            writer.Write("</tr>");
 83        }

 84
 85        protected override ControlCollection CreateControlCollection()
 86ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 87            return new DragDropPanelCollection(this);
 88        }

 89
 90        protected override void AddParsedSubObject(object obj)
 91ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 92            DragDropPanel panel = obj as DragDropPanel;
 93            if (panel != null)
 94ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 95                base.Controls.Add(panel);
 96            }

 97        }

 98
 99        [PersistenceMode(PersistenceMode.InnerDefaultProperty), Browsable(false)]
100        protected DragDropPanelCollection DragDropPanels
101ExpandedSubBlockStart.gifContractedSubBlock.gif        {
102            get
103ExpandedSubBlockStart.gifContractedSubBlock.gif            {
104                return (DragDropPanelCollection)this.Controls;
105            }

106        }

107    }

108}

109
      容器内部可拖动的面板DragDropPanel.cs
      
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
using System.Drawing;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;

[assembly: WebResource(
"pqmagic.Common.UI.Resources.close.gif""image/gif")]
namespace pqmagic.Common.UI
{
    [
        ToolboxData(
"<{0}:DragDropPanel runat=\"server\"></{0}:DragDropPanel>"),
        Designer(
typeof(SubContainerControlDesigner)),
        ParseChildren(
false),
        PersistChildren(
true)
    ]
    
public class DragDropPanel : WebControl
    {
        
private string title = string.Empty;
        
private Unit width = new Unit(100, UnitType.Percentage);
        
private Unit height = new Unit(320, UnitType.Pixel);
        
private Color headerBgColor = Color.FromArgb(0xd30xea0xef);
        
private string headerOnClientClick = string.Empty;

        
/// <summary>
        
/// 面板标题
        
/// </summary>
        [
        Browsable(
true),
        Description(
"设置/获取面板标题"),
        Category(
"Misc")
        ]
        
public string Title
        {
            
get
            {
                
return title;
            }
            
set
            {
                title 
= value;
            }
        }

        
/// <summary>
        
/// 面板高度
        
/// </summary>
        [
        Browsable(
true),
        Description(
"设置/获取面板高度"),
        Category(
"Misc")
        ]
        
public override Unit Height
        {
            
get
            {
                
return height;
            }
            
set
            {
                height 
= value;
            }
        }

        
public override Unit Width
        {
            
get
            {
                
return width;
            }
        }

        
/// <summary>
        
/// 标题背景颜色
        
/// </summary>
        [
        Browsable(
true),
        Description(
"设置/获取标题背景颜色"),
        Category(
"Misc")
        ]
        
public Color HeaderBgColor
        {
            
get
            {
                
return headerBgColor;
            }
            
set
            {
                headerBgColor 
= value;
            }
        }

        
/// <summary>
        
/// 点击标题客户端脚本
        
/// </summary>
        [
        Browsable(
true),
        Description(
"设置/获取点击标题客户端脚本"),
        Category(
"Misc")
        ]
        
public string HeaderOnClientClick
        {
            
get
            {
                
return headerOnClientClick;
            }
            
set
            {
                headerOnClientClick 
= value;
            }
        }

        
protected override HtmlTextWriterTag TagKey
        {
            
get
            {
                
return HtmlTextWriterTag.Div;
            }
        }

        
protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            writer.AddStyleAttribute(HtmlTextWriterStyle.MarginTop, 
"3px");
            writer.AddStyleAttribute(HtmlTextWriterStyle.Height, Height.ToString());
            writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, 
"1px");
            writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, 
"#ccc");
            writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, 
"solid");
            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, width.ToString());
            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, 
"white");
            
base.AddAttributesToRender(writer);
        }

        
protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write(
string.Format("<div id=\"{0}_h\" style=\"height:20px;border-right: #eaf0f6 1px solid; padding-right: 2px; padding-left: 2px;padding-bottom: 2px; margin: 0px; cursor: pointer; padding-top: 2px; border-bottom: #ccc 1px solid;background-color: {1}\">", ID, ColorTranslator.ToHtml(headerBgColor)));
            writer.Write(
"<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%;height:20px\">");
            writer.Write(
string.Format("<tr><td style=\"text-align:left;font-weight:bold;padding-left:3px;padding-top:3px\">{0}</td><td style=\"text-align:right;padding-right:3px\"><img src=\"{1}\" onclick=\"_IG_closePanel('{2}');\" alt=\"关闭\" style=\"cursor:pointer\"/></td></tr>", headerOnClientClick == string.Empty ? Title : "<a href=\"#\" onclick=\"" + headerOnClientClick + "\" style=\"text-decoration:underline\">" + Title + "</a>", Page.ClientScript.GetWebResourceUrl(this.GetType(), "pqmagic.Common.UI.Resources.close.gif"), ID));
            writer.Write(
"</table>");
            writer.Write(
"</div>");
            writer.Write(
"<div style=\"overflow:scroll\">");
            
base.RenderContents(writer);
            writer.Write(
"</div>");
        }
    }
}
      面板集合DragDropPanelCollection.cs
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Reflection;
using System.Security.Permissions;
using System.Web;
using System.Drawing.Design;
using System.Web.UI;

namespace pqmagic.Common.UI
{
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level 
= AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    
public class DragDropPanelCollection : ControlCollection
    {
        
public DragDropPanelCollection(Control owner):base(owner)
        {
        }

        
public override void Add(Control child)
        {
            
if (!(child is DragDropPanel))
            {
                
throw new ArgumentException("该集合只能添加DragDropPanel类型的控件");
            }
            
base.Add(child);
        }

        
public override void AddAt(int index, Control child)
        {
            
if (!(child is DragDropPanel))
            {
                
throw new ArgumentException("该集合只能添加DragDropPanel类型的控件");
            }
            
base.AddAt(index, child);
        }

        
public new DragDropPanel this[int index]
        {
            
get
            {
                
return (DragDropPanel)base[index];
            }
        }
    }
}

转载于:https://www.cnblogs.com/pqmagic/archive/2009/10/04/1577951.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值