js 实现win7任务栏拖动效果

前言

在某个时刻, 我认识了一个朋友.

此人在我的教唆下, 踏上了js的不归路.

前天他问我, Win7任务栏拖动效果怎么实现.

我随口就跟他说, 这简单的一逼.

在我一晚上的折腾之后, 一份潦草的代码总算实现了功能.

PS: 我是搞C++的, js略懂一二..

源码

话不多说, 上源码.

  1 //    常量
  2 var CELL_WIDTH    = 100;
  3 var CELL_HEIGHT = 50;
  4
  5 var Utils = {
  6     pixelToInt: function(str)
  7     {
  8         return parseInt( str.replace("px", "") );
  9     },
 10     getTagLeft: function($tag)
 11     {
 12         return this.pixelToInt( $tag.css("left") );
 13     },
 14     getTagTop: function($tag)
 15     {
 16         return this.pixelToInt( $tag.css("top") );
 17     },
 18     getTagWidth: function($tag)
 19     {
 20         return this.pixelToInt( $tag.css("width") );
 21     },
 22     getTagHeight: function($tag)
 23     {
 24         return this.pixelToInt( $tag.css("height") );
 25     },
 26     setTagLeft: function($tag, x)
 27     {
 28         $tag.css("left", x + "px");
 29     },
 30     setTagTop: function($tag, y)
 31     {
 32         $tag.css("top", y + "px");
 33     },
 34     setTagWidth: function($tag, width)
 35     {
 36         $tag.css("width", width + "px");
 37     },
 38     setTagHeight: function($tag, height)
 39     {
 40         $tag.css("left", height + "px");
 41     },
 42     swapNode: function(ary, idx1, idx2)
 43     {
 44         var t = ary[idx1];
 45         ary[idx1] = ary[idx2];
 46         ary[idx2] = t;
 47     }
 48 };
 49
 50 function Taskbar()
 51 {
 52     this._cells = [];
 53     this._frameTag = null;
 54     this._cellWidth = 0;
 55     this._cellHeight = 0;
 56     this._selNode = null;
 57     this._selIndex = -1;
 58
 59     this._swapQueue = [];
 60     //    考虑优化.
 61     this._offsetPoint = {"x": 0, "y": 0};
 62 }
 63
 64 Taskbar.prototype.getTag = function()
 65 {
 66     return this._frameTag;
 67 }
 68
 69 Taskbar.prototype.init = function(x, y, width, height, rgb)
 70 {
 71     this._frameTag = $("<div></div>");
 72     this.setPosition(x, y);
 73     this.setContentSize(width, height);
 74     this.setBackgroundColor(rgb);
 75
 76     var self = this;
 77     this._frameTag.bind("mousedown", {"bar": self}, this.mouseDown);
 78     this._frameTag.bind("mouseup", {"bar": self}, this.mouseUp);
 79     this._frameTag.bind("mousemove", {"bar": self}, this.mouseMove);
 80     // this._frameTag.bind("mouseout", {"bar": self}, this.mouseOut);
 81 }
 82
 83 Taskbar.prototype.setPosition = function(x, y)
 84 {
 85     this._frameTag.css("position", "absolute");
 86     this._frameTag.css("left", x + "px");
 87     this._frameTag.css("top", y + "px");
 88 }
 89
 90 Taskbar.prototype.setContentSize = function(width, height)
 91 {
 92     this._frameTag.css("width", width + "px");
 93     this._frameTag.css("height", height + "px");
 94 }
 95
 96 Taskbar.prototype.setBackgroundColor = function(rgb)
 97 {
 98     //    rgb => "rgb(0, 0, 0)".
 99     this._frameTag.css("background", rgb);
100 }
101
102 Taskbar.prototype.appendNode = function($node)
103 {
104     var frameWidth = Utils.getTagWidth( this._frameTag );
105     var frameHeight = Utils.getTagHeight( this._frameTag );
106     var length = this._cells.length + 1;
107     this._cellWidth = frameWidth / length;
108     this._cellHeight = frameHeight;
109     this._cells.push($node);
110     $node.appendTo( this._frameTag );
111
112     for ( var i = 0; i != length; ++i )
113     {
114         Utils.setTagLeft( this._cells[i], i * this._cellWidth );
115         Utils.setTagWidth( this._cells[i], this._cellWidth);
116     }
117 }
118
119 Taskbar.prototype.mouseDown = function(e)
120 {
121     var bar = e.data["bar"];
122
123     if ( bar._selNode )
124     {
125         return ;
126     }
127
128     var index = bar.hitTest(e.clientX, e.clientY);
129     if ( !bar.isInvalidIndex(index) )
130     {
131         //    激活.
132         bar._selIndex = index;
133         bar._selNode = bar._cells[ index ];
134         bar._selNode.css("z-index", 99);
135         bar._cells[ index ] = null;
136
137         //    保存偏移量, 保持鼠标拖动.
138         var point = bar.converPoint(e.clientX, e.clientY);
139         bar._offsetPoint.x = point.x - index * bar._cellWidth;
140         bar._offsetPoint.y = point.y;
141         console.log("down");
142     }
143
144 }
145
146 Taskbar.prototype.mouseUp = function(e)
147 {
148     var bar = e.data["bar"];
149
150     if ( bar._selNode )
151     {
152         //    加入交换.
153         bar.appendSwap(bar._selNode, bar._selIndex);
154
155         //    鼠标抬起后, 把选中的节点复位.
156         // bar._cells[ bar._selIndex ] = bar._selNode;
157         bar._cells[ bar._selIndex ].css("z-index", 1);
158         bar._selIndex = -1;
159         bar._selNode = null;
160         console.log("up");
161     }
162 }
163
164 Taskbar.prototype.mouseOut = function(e)
165 {
166     var bar = e.data["bar"];
167     bar.mouseUp(e);
168     console.log("mouseout");
169 }
170
171 Taskbar.prototype.mouseMove = function(e)
172 {
173     var bar = e.data["bar"];
174     if ( bar._selNode )
175     {
176         var point = bar.converPoint(e.clientX, e.clientY);
177         var moveX = point.x - bar._offsetPoint.x;
178
179         //    防止位置溢出.
180         bar.noOverflow( bar._selNode, moveX );
181
182         //    挤开旁边的 float block.
183         var curX = Utils.getTagLeft(bar._selNode),
184             width = Utils.getTagWidth(bar._selNode),
185             testX = curX + width / 2,
186             hitIndex = bar.hitTest(testX, 0);
187         if ( bar._selIndex != hitIndex )
188         {
189             bar.appendSwap(bar._cells[hitIndex], bar._selIndex);
190             bar._selIndex = hitIndex;
191         }
192     }
193 }
194
195 Taskbar.prototype.appendSwap = function($node, index)
196 {
197     this._cells[index] = $node;
198
199     this._swapQueue.push({"node": $node, "index": index});
200     this.resetNode();
201 }
202
203 Taskbar.prototype.noOverflow = function($node, moveX)
204 {
205     var width = Utils.getTagWidth( $node ),
206         frameWidth = Utils.getTagWidth( this._frameTag );
207
208     if (moveX < 0)
209         moveX = 0;
210     else if ( moveX + width > frameWidth )
211         moveX = frameWidth - width;
212
213     Utils.setTagLeft( $node, moveX );
214 }
215
216 Taskbar.prototype.resetNode = function()
217 {
218     var self = this;
219     var call = function($node, index)
220     {
221         var oldX = Utils.getTagLeft($node),
222             newX = index * self._cellWidth,
223             diff = newX - oldX,
224             stepCount = 10,
225             step = diff / stepCount,
226             curX = oldX;
227         (
228             function call()
229             {
230                 if ( stepCount != 0 )
231                 {
232                     curX += step;
233                     Utils.setTagLeft($node, curX);
234                     setTimeout(call, 10);
235                 }
236                 else
237                 {
238                     $node.css("z-index", 0);
239                     Utils.setTagLeft($node, newX);
240                 }
241                 --stepCount;
242             }
243         )();
244     };
245
246     for (var i in this._swapQueue)
247     {
248         call(this._swapQueue[i].node, this._swapQueue[i].index);
249     }
250     this._swapQueue = [];
251 }
252
253 Taskbar.prototype.hitTest = function(x, y)
254 {
255     //    y参数完全是个酱油.
256     var point = this.converPoint(x, y);
257     return parseInt(point.x / this._cellWidth);
258 }
259
260 Taskbar.prototype.converPoint = function(x, y)
261 {
262     var frameX = Utils.getTagLeft( this._frameTag );
263         frameY = Utils.getTagTop( this._frameTag );
264     return {
265         "x": x -= frameX,
266         "y": y -= frameY
267     };
268 }
269
270 Taskbar.prototype.isInvalidIndex = function(index)
271 {
272     return index < 0 || index >= this._cells.length;
273 }
274
275 function init()
276 {
277     var getCell = function(cls, left, top, name)
278     {
279         return $(
280             "<div class=‘_cls‘ name=‘_name‘ style=‘left: _leftpx; top: _toppx; width: _widthpx; height: _heightpx;‘></div>"
281             .replace("_cls", cls)
282             .replace("_left", left)
283             .replace("_top", top)
284             .replace("_name", name)
285             .replace("_width", CELL_WIDTH)
286             .replace("_height", CELL_HEIGHT) );
287     };
288
289     // for (var i = 0; i != 5; ++i)
290     // {
291     //     var taskbar = new Taskbar();
292     //     taskbar.init(0, i * 60, 500, 50, "rgb(0, 0, 0)");
293     //     taskbar.getTag().appendTo( $("body") );
294     //     for (var j = 0; j != i + 5; ++j)
295     //     {
296     //         taskbar.appendNode( getCell("cell", 0, 0, 0) );
297     //     }
298     // }
299 }
300
301 $(document).ready(init);

这个思路其实很简单.

创建一个Taskbar对象, 这个对象设定好坐标, 尺寸, 背景色.

随后往这个对象appendChild, 子节点会自动适配大小.

我们用一个 作业队列 来保存需要移动的任务.

这个队列保存需要被移动的节点, 和被动到哪个位置上.

随后会触发一个交换的动作, 这个动作是持续性的, 因此可以看到节点平滑移动.

在我们down下操作之后, 被down下的那个节点位置设置null.

随后我们用一个 _selNode 保存这个节点.

同时用 _selIndex 保存这个节点本应该属于的位置.(这句话很难形容, 但是我想不出怎么说!)

随后在move操作下, 判断这个 _selNode 是否"越线", 一旦越线则push一个交换作业.

随后就像上面所说, 触发交换动作.

在up操作触发之后, 只需要把 _selNode和_selIndex push到作业队列即可.

因为所有的mouse响应都在背景的div里, 因此鼠标超出范围则不会响应..

例如, 我down之后, 鼠标移出范围再up, 此时的up将不会被响应..

我在down中加了一条判断来解决此bug..

在超出范围up, 回到范围之后, 依然是down状态.

js 实现win7任务栏拖动效果

时间: 2024-12-16 23:45:40

js 实现win7任务栏拖动效果的相关文章

js实现弹框的拖动效果

<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> body{position:relative;} *{padding:0;margin:0;} .dialog{width:400px;height:400px;border:1px solid #ddd;position:fixed;top:100px;left:200px;

简单的鼠标拖动效果

使用js实现简单的鼠标拖动效果,但此部分代码有个小小的BUG,后期改进好我会写进来,但基本的效果已经实现,请大家参考. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>鼠标移动</title> <style> #box{ width: 50px; height: 50px; position:

js实现的div拖动效果实例代码

js实现的div拖动效果实例代码:div的拖动效果在很多效果中都有应用,当然还有很多附加的功能,本章节只是给拖动效果,并介绍一下它的实现过程.代码实例如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <t

【推荐】Win7任务栏增强工具 7+ Taskbar Tweaker 强大的任务栏标签管理工具

我曾经推荐过一款XP的任务栏管理工具 Taskix,这是一款在XP系统中拖动任务栏内标签的小工具. XP 32位可以下载我汉化的版本 http://www.cnblogs.com/clso/archive/2011/06/13/2079637.html XP 64位可以去官方下载64位版 http://taskix.robustit.com/ 但是自从我用了Windows 7系统之后,就一直没找到类似这种工具. 事实上Win7系统也提供了一个任务栏标签的分组系统,可以让相同程序的窗体界面排列在一

Web的鼠标拖动效果

以前写过一个拖动效果的Demo,拖拽元素新位置的计算是放在拖拽元素的mousemove事件中进行的.计算效率差,而且效果不好.所以一直有想怎样才能做出jquery-ui那种顺滑的拖拽效果. 其实顺滑的拖拽效果的突破口有两点: 事件捕捉要去捕捉document的鼠标位置. 使用setInterval功能计算拖拽元素的新位置. 使用jQuery,经过一些简单的重构和调试,将代码完善如下: drag.html <!DOCTYPE html> <html> <head> <

jquery实现简单的导航栏切换效果($(this).index)

一个简单的导航栏切换效果的制作,主要通过索引值和jquery的siblings()来实现 html代码: <div class="container"> <ul class="top-nav"> <li class="nav">html</li> <li class="nav">css</li> <li class="nav"&g

运用HTML5原生拖动事件(drag)实现拖动效果

拖动效果相信很多朋友都自己写过,不管你用原生JS还是Jquery要实现起来也很简单,但是今天我想介绍的是运用HTML5标准中定义的原生拖动事件实现拖动效果. 一.背景: 其实说是HTML5标准定义,其实最早在IE4中就有拖放功能的API,只是在IE4中,网页中只有两种对象可以拖放:图像和某些文本.并且在IE4中唯一有效的放置目标是文本框.到了IE5.5,拖放功能得到了扩展,让网页中的任何元素都可以拖放.最终HTML5以IE的实力为基础制定了拖放规范.FF3.5+,Safari3+和Chrome根

通过html和css做出下拉导航栏的效果

引用前请标明出处:http://www.cnblogs.com/zkhzz/ 谢谢 通过观察了百度的首页,对于更多产品一栏,觉得可以不涉及JS便可写出下拉导航栏的效果 1.先设计出大体的框架 <div class="nav"> <ul> <li><a href="#">新闻</a></li> <li><a href="#">hao123</a&g

将以管理员方式运行cmd运行方式放到win7任务栏

首先在桌面空白地方(没有桌面图标位置),点击鼠标右键,选择新建--快捷方式,如下图: 弹出创建快捷方式窗口,输入cmd.exe的路径及文件名,下图是天缘的Windows 7安装到C盘对应的cmd可执行文件地址C:\Windows\System32\cmd.exe,如果是其它驱动器相应修改,设置好点击下一步. 这里设置快捷方式的名称,比如cmd,或者采用默认的也可以,设置完成后,点击完成.如下图: 桌面上会生成一个cmd的快捷方式,如下图,我们再在cmd图标上,点击鼠标右键,选择属性. 如下图,选