前端的小玩意(9.1)——做一个仿360工具箱的web页面(Tab按钮切换)

http://blog.csdn.net/qq20004604/article/details/52216203

前端的小玩意(9.2)——做一个仿360工具箱的web页面(全部工具里面的模板)

http://blog.csdn.net/qq20004604/article/details/52226223

前端的小玩意(9.3)——做一个仿360工具箱的web页面(我的工具里的模板和样式)

http://blog.csdn.net/qq20004604/article/details/52235854

前端的小玩意(9.4)——做一个仿360工具箱的web页面(自动生成所有图标,对图标添加响应逻辑)

http://blog.csdn.net/qq20004604/article/details/52246586

DEMO网址:

http://jianwangsan.cn/toolbox

(五)添加、点击和移动的逻辑

我反思了一下,在(四)中我写的并不好,事实上,无论是大按钮,还是被添加到我的工具,或者是添加到常用工具栏,他都是一个按钮,因此,应该共享状态,即他们属于同一个tool实例,并能互相影响。

需求分析:

在重写Tool类之前,需要明确分析按钮的逻辑。

在全部工具页面:

①当按钮未被添加时,鼠标移动上去会有添加按钮显示;

②当按钮未被添加时,鼠标无论点击按钮本身还是点击添加按钮,都执行添加逻辑,将添加按钮显示为取消,执行一次添加动画,添加完成后,按钮隐藏;

③当按钮已被添加时,鼠标点击会启用按钮本身的逻辑(比如打开软件);

在我的工具页面:

①当按钮未被添加时,不显示;

②当按钮被添加时,显示按钮;

③点击按钮时,点击会启用按钮本身的逻辑(比如打开软件);

④长按按钮,可以拖动按钮,原有按钮位置不被占用,显示为空白;

⑤按钮拖动中时,若经过某个已有按钮的位置,原按钮位置不再被占用,经过的位置被空白占用,相当于把空白占位符从DOM中的原位置挪到了DOM树中的新位置;

⑥按钮拖动时,可以离开工具箱的页面显示范围,但不会显示出来(类似overflow:hidden)的效果;

⑦当按钮拖动到主界面快捷入口的四个图标范围时,若原位置有图标,再该位置图标及右侧所有图标依次向右移动一位;当离开这个位置时,原有图标立刻返回原位置;

⑧主界面快捷入口最多有四个图标,假如新插入一个,那么原本最右边的将被移除;

⑨点击编辑按钮时,所有图标右上角都会出现一个红叉符号;

(10)当编辑状态时,点击主界面快捷入口的四个图标的红叉时,将移除被点击的那个图标;

(11)当编辑状态时,点击我的工具的图标的红叉,将删除该图标(全部工具里的添加按钮恢复);若该图标在快捷入口也存在时,快捷入口的该图标也被删除。

因此,这个Tool类也能满足以上功能;

更新模板和样式;

①要有四种状态的图标,依次为全部工具页面的大图标、普通图标,我的工具页面的普通图标、快捷入口图标;

②并且,要能创建这些图标,并且,由于之前没有设计全部工具页面的取消按钮、我的工具页面里的编辑按钮,因此要添上;

我的工具里图标的html模板:,编辑按钮默认为不显示:

div.tool-mydiv.imgdiv.text    小清新日历div.edit-img.displayNONE

快捷入口的按钮的html模板:

div.tool-footdiv.imgdiv.text    系统急救箱div.edit-img.displayNONE

取消按钮添加后的大图标:

div.BigToolspan.imgspan.maskdiv.textdiv.titlediv.descriptiondiv.Button.add  添 加div.Button.cancel.displayNONE   取 消

取消按钮添加后的html模板:

div.normalTooldiv.imgdiv.textdiv.titlediv.descriptiondiv.Button.add  添 加div.Button.cancel.displayNONE   取 消

另附2个新增的CSS样式:

.back .contentbox .toolbox-my .toolbox-content .tool-my .edit-img {position: absolute;right: 14px;top: 13px;width: 18px;height: 17px;background-image: url(../img/toolbox.png);background-position: -80px -50px;
}
.back .contentbox .toolbox-my .toolbox-foot .edit-img {position: absolute;right: 14px;top: 10px;width: 18px;height: 17px;background-image: url(../img/toolbox.png);background-position: -80px -50px;
}

然后是样式修改:

显示大图标的:

把原来的addButton拆分成Button、add和cancel

.back .contentbox .toolbox-all .firstRow .BigTool .Button {display: none;position: absolute;bottom: 10px;right: 12px;width: 60px;height: 22px;font-size: 12px;text-align: center;line-height: 20px;-webkit-border-radius: 1px;-moz-border-radius: 1px;border-radius: 1px;
}.back .contentbox .toolbox-all .firstRow .BigTool .Button.add {background-image: linear-gradient(rgb(98, 227, 25) 0%, rgb(68, 208, 27) 100%);color: white;border: 1px solid rgb(65, 199, 36);
}.back .contentbox .toolbox-all .firstRow .BigTool .Button.cancel {background-image: linear-gradient(#f3f3f3 0%, #dfdfdf 100%);color: black;border: 1px solid #b6b6b6;display: block;
}.back .contentbox .toolbox-all .firstRow .BigTool:hover .add {display: block;
}

另外一个类似

.back .contentbox .commonRow .normalTool .Button {display: none;position: absolute;top: 7px;right: 15px;width: 60px;height: 22px;font-size: 12px;text-align: center;line-height: 20px;-webkit-border-radius: 1px;-moz-border-radius: 1px;border-radius: 1px;
}.back .contentbox .commonRow .normalTool .add {background-image: linear-gradient(rgb(98, 227, 25) 0%, rgb(68, 208, 27) 100%);border: 1px solid rgb(65, 199, 36);color: white;
}.back .contentbox .commonRow .normalTool .cancel {background-image: linear-gradient(#f3f3f3 0%, #dfdfdf 100%);color: black;border: 1px solid #b6b6b6;display: block;}.back .contentbox .commonRow .normalTool:hover .add {display: block;
}

为了符合实际需求,我们需要做以下工作:

①重构Tool类(之前实在太简陋了);

②需要一个函数,专用进行操作;

③需要一个runAfter函数,他的效果是,监听某个对象的某个方法,在该方法执行完后执行runAfter的回调函数;

④然后利用这个runAfter监听一些函数,并在该函数触发时做一些事情。

重构Tool类:

他分为以下几个部分:

①变量声明(私有变量):

var Tool = function (obj, myToolDom) {var self = this;var obj = obj;// 0表示未加载到我的工具,1表示加载到我的工具,-1表示添加中(未使用)var state = 0;var BigImgDom = null;   //全部工具大图标var NormalToolDom = null;   //全部工具小图标var addButton = null;   //确认按钮var cancelButton = null;    //取消按钮(有,但是实际未使用)var InMyToolDom = null; //我的工具大图标var editButtonInMyToolDom = null;  //我的工具页面的编辑红叉按钮var SmallToolDom = null;    //快捷入口图标var editButtonInSmallToolDom = null;    //快捷入口图标的编辑按钮var DomClickEvent = null;    //这个是该dom点击事件的回调函数var editing = false;    //编辑状态var move = false;   //我的工具大图标移动状态var SmallIconMove = false;  //我的工具小图标移动状态//如果有传参则用传参,如果没有则用默认值var MyToolDom = myToolDom ? myToolDom : $(".toolbox-my .toolbox-content");

注意,以上四种图标,最多只会存在三种(所有工具的大图标和小图标只能存在一种状态)

②dom获取

根据实际需求,我们有时候需要获取dom,其中一个是私有的(只在tool类里调用),一个是公有的(会在外面调用),所以声明方式不同:

//获取DOM
var getDomInAllTools = function () {return BigImgDom ? BigImgDom : NormalToolDom;  //因为只有一个存在
};
this.getDomInMyTools = function () {return InMyToolDom;
};

③创建图标

我们自然需要创建图标,四种图标都需要一个函数(因为他们的dom结构不同);

//全部工具页面
//  大按钮
this.createBigImgDom = function (callback) {var str = '<div class="BigTool">' +'<span class="img" style="background-position: ' + obj.bigImg.ImgPosition.x + ' ' + obj.bigImg.ImgPosition.y + '"></span>' +'<span class="mask"></span>' +'<div class="text">' +'<div class="title">' + obj.title + '</div>' +'<div class="description">' + obj.description + '</div>' +'</div>' +'<div class="Button add">添 加</div>' +'<div class="Button cancel displayNONE">取 消</div>' +'</div>';BigImgDom = $(str);addButton = BigImgDom.find(".add");cancelButton = BigImgDom.find(".cancel");DomClickEvent = callback;setClickEvent();return getDomInAllTools();
};//  普通按钮
this.createNormalToolDom = function (callback) {var str = '<div class="normalTool">' +'<div class="img" style="background-position: ' + obj.commonImg.ImgPosition.x + ' ' + obj.commonImg.ImgPosition.y + '"></div>' +'<div class="text">' +'<div class="title">' + obj.title + '</div>' +'<div class="description">' + obj.description + '</div>' +'</div>' +'<div class="Button add">添 加</div>' +'<div class="Button cancel displayNONE">取 消</div>' +'</div>';NormalToolDom = $(str);addButton = NormalToolDom.find(".add");cancelButton = NormalToolDom.find(".cancel");DomClickEvent = callback;setClickEvent();return getDomInAllTools();
};//我的工具页面
//  创建普通的dom
var createInMyToolDom = function () {var str = '<div class="tool-my">' +'<div class="img" style="background-position: ' + obj.commonImg.ImgPosition.x + ' ' + obj.commonImg.ImgPosition.y + '"></div>' +'<div class="text">' + obj.title + '</div>' +'<div class="edit-img displayNONE"></div>' +'</div>'var node = $(str);return node;
}//  创建小的dom
var createSmallTool = function () {var position_x = parseInt(obj.commonImg.ImgPosition.x) * 0.615 + "px";var position_y = parseInt(obj.commonImg.ImgPosition.y) * 0.615 + "px";var str = '<div class="tool-foot">' +'<div class="img"  style="background-position: ' + position_x + ' ' + position_y + '"></div>' +'<div class="text">' + obj.title + '</div>' +'<div class="edit-img displayNONE"></div>' +'</div>';var node = $(str);return node;
};

注:

(1)以上四个创建图标,在全部工具里的两种还额外获取了编辑按钮;

(2)创建全部工具的图标时,顺便获取了响应函数

④响应逻辑:

图标创建了必然需要对她设置事件,

(1)比如全部工具里图标的点击事件:

//  设置全部工具里的点击事件
var setClickEvent = function () {var node = BigImgDom ? BigImgDom : NormalToolDom;node.click(function (event) {if (state) {DomClickEvent();} else if (state === 0) {self.addDomToMyTools();}});
};

(2)以上点击事件又分为两种,已添加时,触发正常的响应逻辑(在创建图标时作为参数传进来的回调函数);

未添加时,用于添加到我的工具里的函数:

//将dom添加到我的工具里
this.addDomToMyTools = function () {addButton.addClass("displayNONE");state = 1;  //设置其状态为已添加//现在是在mytools里添加if (!InMyToolDom) {InMyToolDom = createInMyToolDom();editButtonInMyToolDom = InMyToolDom.find(".edit-img");//setMyToolEditEvent(editButtonInMyToolDom);    //废弃,同下被整合//setMyToolClickEvent(InMyToolDom);   //废弃,被整合进移动按钮的逻辑中setMyToolsDomMoveEvent();}MyToolDom.append(InMyToolDom);
};

(3)这个添加事件又分为:

设置添加按钮为隐藏,设置添加状态为已添加;

没有dom的时候,创建dom并为其绑定事件,绑定的事件有:

【1】点击事件:

(但事实上这个已废弃,因为后面涉及到移动按钮的函数,被整合在那里了)

//  设置我的工具页面的两种按钮的点击事件
var setMyToolClickEvent = function (node) {node.click(function (event) {if (!editing) {DomClickEvent();}});
};

【2】编辑按钮点击事件:

(同样已废弃,因为后面涉及到移动按钮的函数,被整合在那里了)

【3】设置按钮的移动函数,包括以上两个被整合的事件:

//我的工具大图标的移动函数
var setMyToolsDomMoveEvent = function () {var mouseX = null;var mouseY = null;var startLeft = null;var startTop = null;var placeHholderDom = $('<div class="tool-my .ItsplaceHolder"></div>');InMyToolDom.mousedown(function (evt) {if (evt.button != 0) {return;}if (editing & $(evt.target)[0] == editButtonInMyToolDom[0]) {self.setStateToUnadd();InMyToolDom.detach();if ($(".shortcut .tool-foot").filter(placeHholderDom[0])) {SmallToolDom.detach();$(".shortcut").append('<div class="tool-foot placeholder">' +'<div class="placeholder-img"></div>' +'<div class="text">拖拽到此</div>' +'</div>')}event.stopPropagation();return;}mouseX = evt.clientX;   //这里的值是鼠标坐标mouseY = evt.clientY;var position = InMyToolDom.position();startLeft = position.left;  //没有pxstartTop = position.top;InMyToolDom.css("position", "absolute");InMyToolDom.css("left", startLeft + "px");InMyToolDom.css("top", startTop + "px");InMyToolDom.after(placeHholderDom);move = true;});$(".toolbox-my").mousemove(function (evt) {if (!evt.buttons & move) {  //只有不在按,且当前是true的时候,才触发move = false;placeHholderDom.after(InMyToolDom);placeHholderDom.remove();InMyToolDom.css("position", "relative");InMyToolDom.css("left", "0");InMyToolDom.css("top", "0");self.InMyToolDomEndMoving();if (mouseX == evt.clientX & mouseY == evt.clientY) {if (!editing) {DomClickEvent();}}}if (move) {self.InMyToolDomMoving([placeHholderDom, evt]);var offsetX = evt.clientX - mouseX;var offsetY = evt.clientY - mouseY;InMyToolDom.css("left", offsetX + startLeft + "px");InMyToolDom.css("top", offsetY + startTop + "px");}});InMyToolDom.mouseup(function (evt) {if (move) {move = false;placeHholderDom.after(InMyToolDom);placeHholderDom.remove();InMyToolDom.css("position", "relative");InMyToolDom.css("left", "0");InMyToolDom.css("top", "0");self.InMyToolDomEndMoving();if (mouseX == evt.clientX & mouseY == evt.clientY) {if (!editing) {DomClickEvent();}}}})
};

解释:

以上这个函数干了以下事:

《1》只有鼠标左键按下才有效;

《2》编辑状态时,按编辑按钮是有效的;(因此我们需要一个设置编辑状态的函数)

《3》编辑状态时点击编辑按钮,会删除当前按钮,并用一个空白的按钮替代;

《4》这个dom移除,为了不移除他的事件,因此用的是jquery的detach()方法,并阻止该按钮事件的冒泡;

《5》非编辑状态时,可以移动按钮,原理是设置该按钮的定位为绝对定位,并用一个空白按钮放在该按钮的DOM后起到占位作用,并设置该按钮可移动;

《6》由于代码本身写的并不是很好,因此移动状态被取消时,计算移动距离,如果没有位移偏差,且非编辑状态,触发该按钮的点击事件;(如果要写的好的话,该按钮的移动状态设置,应该在移动位置有偏差之后才设置position为绝对定位);

《7》移动时触发一个InMyToolDomMoving方法,这个要被runAfter方法所监视,返回值是空白dom和鼠标移动时触发的event事件。该事件会决定该按钮和其他按钮的互动;

《8》移动结束后,会触发一个InMyToolDomEndMoving方法,该方法同样被监视。并且设置移动结束后的鼠标弹起事件(同移动中的那个)。

《9》移动结束后,把图标放在占位图标之前(注意,该占位图标的位置可能移动),并解除移动状态,取消绝对定位,移除占位图标;

【4】然后是我的工具的大图标的移动中事件:

this.InMyToolDomEndMoving = function () {if (!SmallToolDom) {SmallToolDom = createSmallTool();//setMyToolClickEvent(SmallToolDom);editButtonInSmallToolDom = SmallToolDom.find(".edit-img");setSmallEditEvent(editButtonInSmallToolDom);setSmallToolDomMoveEvent();}return SmallToolDom;
};

他会返回小图标,如果没有小图标则创建,并为他绑定事件。

绑定事件有:

《1》点击事件(整合进移动相关函数);

《2》编辑按钮点击事件:

//  设置小的dom的编辑按钮的点击事件
var setSmallEditEvent = function (editNode) {editNode.click(function (event) {self.removeSmallTool();editButtonInSmallToolDom.addClass("displayNONE");SmallToolDom.detach();event.stopPropagation();})
};

《3》移动事件;

var setSmallToolDomMoveEvent = function () {var mouseX = null;var mouseY = null;var startLeft = null;var startTop = null;var placeHholderDom = $('<div class="tool-foot placeholder SmallToolHolder">' +'<div class="placeholder-img"></div>' +'<div class="text">拖拽到此</div>' +'</div>');SmallToolDom.mousedown(function (evt) {if (evt.button != 0) {return;}if (editing & $(evt.target)[0] == editButtonInSmallToolDom[0]) {event.stopPropagation();return;}mouseX = evt.clientX;   //这里的值是鼠标坐标mouseY = evt.clientY;var position = SmallToolDom.position();startLeft = position.left;  //没有pxstartTop = position.top;SmallToolDom.css("position", "absolute");SmallToolDom.css("left", startLeft + "px");SmallToolDom.css("top", startTop + "px");SmallToolDom.after(placeHholderDom);SmallIconMove = true;if ($(".SmallToolHolder").length > 1) {$(".SmallToolHolder")[1].remove();}});$(".toolbox-my").mousemove(function (evt) {if (!evt.buttons & SmallIconMove) {  //只有不在按,且当前是true的时候,才触发SmallIconMove = false;placeHholderDom.before(SmallToolDom);placeHholderDom.remove();SmallToolDom.css("position", "relative");SmallToolDom.css("left", "0");SmallToolDom.css("top", "0");$(".SmallToolHolder").remove();if (mouseX == evt.clientX & mouseY == evt.clientY) {if (!editing) {DomClickEvent();}}}if (SmallIconMove) {self.SmallToolDomMoving([placeHholderDom, evt]);var offsetX = evt.clientX - mouseX;var offsetY = evt.clientY - mouseY;SmallToolDom.css("left", offsetX + startLeft + "px");SmallToolDom.css("top", offsetY + startTop + "px");if ($(".SmallToolHolder").length > 1) {$(".SmallToolHolder")[1].remove();}}});SmallToolDom.mouseup(function (evt) {if (SmallIconMove) {SmallIconMove = false;placeHholderDom.before(SmallToolDom);placeHholderDom.remove();SmallToolDom.css("position", "relative");SmallToolDom.css("left", "0");SmallToolDom.css("top", "0");$(".SmallToolHolder").remove();if (mouseX == evt.clientX & mouseY == evt.clientY) {if (!editing) {DomClickEvent();}}}})
}

由于和大图标的移动按钮事件类似,就不细说了

总之,他在移动的时候,会触发一个SmallToolDomMoving方法,runAfter会监视他。

【5】下来是两个按钮移动时触发的事件和移动结束后触发的事件:

//移动时会触发这个方法
this.InMyToolDomMoving = function (arr) {return arr;
};this.InMyToolDomEndMoving = function () {if (!SmallToolDom) {SmallToolDom = createSmallTool();//setMyToolClickEvent(SmallToolDom);editButtonInSmallToolDom = SmallToolDom.find(".edit-img");setSmallEditEvent(editButtonInSmallToolDom);setSmallToolDomMoveEvent();}return SmallToolDom;
};this.SmallToolDomMoving = function (arr) {return arr;
};

⑤其他事件:

//设置编辑或者结束编辑
this.setEditing = function () {editing = true;editButtonInMyToolDom ? editButtonInMyToolDom.removeClass("displayNONE") : "";editButtonInSmallToolDom ? editButtonInSmallToolDom.removeClass("displayNONE") : "";
};this.cancelEditing = function () {editing = false;editButtonInMyToolDom.addClass("displayNONE");editButtonInSmallToolDom ? editButtonInSmallToolDom.addClass("displayNONE") : "";
}
//设置dom为未添加状态
this.setStateToUnadd = function () {addButton.removeClass("displayNONE");editButtonInMyToolDom.addClass("displayNONE");if (editButtonInSmallToolDom) {editButtonInSmallToolDom.addClass("displayNONE");}state = 0;  //设置其状态为未添加
}

编辑状态的两个方法用于设置可编辑或者不可编辑;

另一个用于在删除按钮时调用;

——————————————————————————

重写ToolsConfigJsonLoad函数:

这个函数做了这些事情:

①读取json;

②把json转化为Tool类的数据来源;

③创建Tool类实例,并监听其事件;

④在创建图标的时候,添加分割线、或者创建占位图标等;

声明这个函数:

var ToolsConfigJsonLoad = function (InMyToolArray, url) {this.url = url ? url : "data/tools.json";

这个函数只有一个公有方法,那就是读取json:

this.load = function () {var self = this;$.ajax({url: self.url,dataType: "json",type: "GET",success: function (data) {addToolsInToolbox_all(data);}})
};

读取json成功之后调用的函数:

//将内容添加到全部工具页面中
var addToolsInToolbox_all = function (data) {var type = [];data[0].BigImg.forEach(function (obj) {var tool = new Tool(obj);var mixin = new MixinTool(obj);var callback = mixin.mixin()listenToolEvent(tool);$(".firstRow").append(tool.createBigImgDom(callback));})data[0].CommonImg.forEach(function (obj) {if (type.indexOf(obj.type) < 0) {type.push(obj.type);}var tool = new Tool(obj);var mixin = new MixinTool(obj);var callback = mixin.mixin()listenToolEvent(tool);$(".commonRow." + obj.type).append(tool.createNormalToolDom(callback));})addPlaceHolderWhenOnlyTwoToolsInToolbox_All(type);addDottedLineInToolbox_All();
};

监听事件先略过;

添加分割线:

// 这个目的是为了给全部工具中的多行工具之间添加分割线
var addDottedLineInToolbox_All = function () {$(".commonRow .normalTool:nth-child(3n+4)").before('<div class="dotted"></div>');
};

为保证美观,添加占位图标:

// 这个目的是当某一行只有两个图标时,创造一个占位的图标
var addPlaceHolderWhenOnlyTwoToolsInToolbox_All = function (type) {type.forEach(function (obj) {var length = $(".commonRow." + obj + " > *").length;if (length % 3 == 2) {$(".commonRow." + obj).append($('<div class="normalToolHolder" style="cursor:default"></div>'));}})
};

下来事件监听函数的原型:

//参数1是对象,参数2是方法名(字符串),参数三是该方法执行后执行的函数
var runAfter = function (obj, runEvent, AfterEvent) {var temp = obj[runEvent];obj[runEvent] = function (arguments) {var result = temp(arguments);AfterEvent(obj, result);}
}

类似dojo的aspect.after方法

最后是利用runAfter函数进行事件监听,调用它时只需要传递Tool类的实例。

//监听事件
var listenToolEvent = function (tool) {

他包含以下方法:

①当图标添加进我的工具时,将实例添加到一个数组中:

runAfter(tool, "addDomToMyTools", function () {InMyToolArray.push(tool);
});

②或者是删除我的工具里的按钮时,移除这个实例:

runAfter(tool, "setStateToUnadd", function () {var MyToolIndex = InMyToolArray.indexOf(tool);InMyToolArray.splice(MyToolIndex, 1);
});
</pre><p>③还需要一个占位图标,用于图标在移动时占位:</p><pre name="code" class="javascript">var placeHolderInSmall = $('<div class="tool-foot placeholder">' +'<div class="placeholder-img"></div>' +'<div class="text">拖拽到此</div>' +'</div>')

④监听图标移动时的方法,他涉及到我的工具页面里大图标的互动,和快捷入口小图标的互动:

runAfter(tool, "InMyToolDomMoving", function (obj, result) {var placeHolder = result[0];var event = result[1];InMyToolArray.forEach(function (tool) {var node = tool.getDomInMyTools();if (node.css("position") !== "absolute") {var position = node.offset(); //获取相对于文档的位置if (event.clientY > position.top & event.clientY < position.top + 100 & event.clientX > position.left & event.clientX < position.left + 100) {if (node.index() < placeHolder.index()) {    //根据索引决定放在前还是后面node.before(placeHolder);} else {node.after(placeHolder);}}}});var theNodeInSmallTools = false;    //是否重合$(".tool-foot").toArray().forEach(function (node, index) {var position = $(node).offset(); //获取相对于文档的位置if (event.clientY > position.top & event.clientY < position.top + 70 & event.clientX > position.left & event.clientX < position.left + 76) {theNodeInSmallTools = true;if ($(node) != placeHolderInSmall) {$(node).before(placeHolderInSmall);}}});//如果重合if (theNodeInSmallTools) {$(".shortcut .tool-foot:last-child").addClass("displayNONE");}   //如果不重合else {placeHolderInSmall.remove();$(".shortcut .tool-foot.displayNONE").removeClass("displayNONE");}
});
</pre><p>⑤当图标停止移动时,需要决定他是否被移动到一个新位置,或者是添加到快捷入口那里;</p><pre name="code" class="javascript">runAfter(tool, "InMyToolDomEndMoving", function (obj, node) {var sign = false;$(".tool-foot").toArray().forEach(function (node, index) {if ($(node)[0] == placeHolderInSmall[0]) {sign = true;}})if (sign) {if (node.hasClass("displayNONE")) {node.removeClass("displayNONE");}placeHolderInSmall.before(node);placeHolderInSmall.remove();}if ($(".tool-foot").length < 4) {var temp = '<div class="tool-foot placeholder">' +'<div class="placeholder-img"></div>' +'<div class="text">拖拽到此</div>' +'</div>';$(".shortcut").append(temp);} else if ($(".tool-foot").length > 4) {$(".tool-foot")[4].remove(); //移除第五个} else {$(".tool-foot.displayNONE").removeClass("displayNONE");}$(".shortcut").append($(".tool-foot.placeholder"));
})⑥还有小图标移动时,需要和小图标互动,例如可能需要交换位置:
runAfter(tool, "SmallToolDomMoving", function (obj, result) {var placeHolder = result[0];var event = result[1];$(".tool-foot").toArray().forEach(function (node) {var position = $(node).offset(); //获取相对于文档的位置if ($(node).css("position") !== "absolute") {if (event.clientY > position.top & event.clientY < position.top + 70 & event.clientX > position.left & event.clientX < position.left + 76) {if ($(node).index() < placeHolder.index()) {    //根据索引决定放在前还是后面$(node).before(placeHolder);} else {$(node).after(placeHolder);}}}});
});

——————————————————————

让工具箱运行起来:

以上代码,只涉及到工具箱页面各个图标的交互逻辑,但是并没有真正运行起来(例如,没有显式调用load()方法),并且也没有编辑图标的逻辑。

因此,我们需要一个函数补全剩下的部分:

var ToolBoxEvent = function () {var InMyToolArray = [];var jsonLoad = new ToolsConfigJsonLoad(InMyToolArray);jsonLoad.load();$("#edit").click(function () {//编辑中if ($(this).hasClass("editing")) {InMyToolArray.forEach(function (item) {item.cancelEditing();})//设置编辑按钮的样式变更$(this).removeClass("editing");var text = $(this).find(".text");text.text("编辑");text.css("width", "32px");text.css("margin-left", "0px");} else {InMyToolArray.forEach(function (item) {item.setEditing();})//设置编辑按钮的样式变更$(this).addClass("editing");var text = $(this).find(".text");text.text("退出编辑");text.css("width", "52px");text.css("margin-left", "-10px");}});
}

这个函数干了两件事:

①声明一个ToolsConfigJsonLoad类的实例,并调用它的load方法(加载工具箱);

②设置编辑按钮的事件。

这样的话,工具箱就可以正常跑起来了。

当然,还有一些小BUG,需要被修复,不过这并不影响整体功能的运转,作为一个DEMO来说,程度是足够了,如果真要跑生产环境,那么这些BUG必须被fix

js全部代码:

http://jianwangsan.cn/javascripts/toolboxes.js

css全部代码:

http://jianwangsan.cn/stylesheets/toolboxes.css

前端的小玩意(9.5)——做一个仿360工具箱的web页面(完结篇,可以跑起来的工具箱)相关推荐

  1. 前端的小玩意(9.3)——做一个仿360工具箱的web页面(我的工具里的模板和样式)

    前端的小玩意(9.1)--做一个仿360工具箱的web页面(Tab按钮切换) http://blog.csdn.net/qq20004604/article/details/52216203 前端的小 ...

  2. 前端的小玩意(9.2)——做一个仿360工具箱的web页面(全部工具里面的模板)

    上一篇链接: http://blog.csdn.net/qq20004604/article/details/52216203 DEMO: http://jianwangsan.cn/toolbox ...

  3. 前端的小玩意(9.1)——做一个仿360工具箱的web页面(Tab按钮切换)

    需求: ①写一个web版的360工具箱,示意图如下: ②无左上返回按钮,右上按钮有皮肤切换,下拉框(但无点击逻辑): ③按钮点击有事件,但事件是console.log(按钮名): ④可以在全部工具和我 ...

  4. EonerCMS——做一个仿桌面系统的CMS(二)

    上一周我说到,我要开始做一个仿桌面系统的CMS.现在,一周过去了,来做个小小的总结吧,顺便把上一周片尾留的小问题解答下. 桌面 关于界面,思前想后,还是模仿115的了,说是模仿,其实几乎是照搬.因为我 ...

  5. 做一个略调皮的个人主页--相册与随笔篇

    目录 做一个略调皮的个人主页--菜单篇 做一个略调皮的个人主页--结构篇 做一个略调皮的个人主页--相册与随笔篇 总算在北京找到个便宜的房子租了,算是稳定下来啦. 新工作的节奏本来很快,有些不适用的, ...

  6. Python 用pygame 做一个游戏的开始界面(小白第一篇博客)

    Python 用pygame 做一个游戏的开始界面(小白第一篇博客) 主要功能实现 本篇文章主要是实现了一个游戏开始界面的两个功能: 1,将鼠标放到"开始游戏"或"结束游 ...

  7. 现学现卖做一个炫酷的动态背景页面

    很喜欢酷炫的页面,自从看了抖音的主页之后(如下)(链接),就决定要也做一个牛逼的动态背景页面 对...背景是视频,而且还有音效,太牛逼了 然后决定自己做一个,废话不说,先弄代码: 这里为了设计简便,用 ...

  8. 开博第一篇作品-C#winform版《仿360杀毒》页面切换动画效果(内含源码)

    C#winform版 <仿360杀毒>页面切换动画效果 昨天跟一个同事聊天,谈到了360杀毒的页面效果不错,我们所做的winform页面都是拖控件还是拖控件,不能吸引客户的注意力,想改成3 ...

  9. 用HTML➕CSS做一个漂亮的个人博客页面

    用html+css设计个人博客网页,纯静态页面 前几周我们让做了一个个人博客页面,怎么说,刚接触前端不久,第一次做页面刚开始选择的都是大红大紫的颜色,导致整合页面很low,后来看了些抽象绘画,决定用上 ...

最新文章

  1. 第 171 章 vagrant - Tool for building and distributing virtualized development environments
  2. Web前端基础——HTML
  3. (转)IIS7 配置ASP.NET 2.0, WCF, ASP.NET MVC
  4. stringBuffer、StringBuilder、排序、Arrays、Jdk1.5新特性(java基础知识十三)
  5. 前端学习(1364):学生档案信息管理6
  6. C#LeetCode刷题之#83-删除排序链表中的重复元素(Remove Duplicates from Sorted List)
  7. python教程七牛云_通过Python来使用七牛云存储的方法详解
  8. 结构体08:结构体案例2
  9. Unity中Camera的Clear flags,Culling Mask,Depth参数
  10. 各大软件的 java版本_Java 各个版本的软件 1.4 1.5 5.0 6.0
  11. 人人都可以写贪吃蛇(白话javascript版)
  12. Linux shell 查找操作
  13. PASCAL VOC 2007数据集,百度云下载
  14. 以pdf转cad为例,所有格式之间任意转换
  15. KumiaoQQ机器人框架源码
  16. 【代码质量】-阿里巴巴java开发手册(代码质量提升神器)学习笔记
  17. 高精度计算(三)压位
  18. 数据分析AB测试实战项目
  19. 企业微信聊天框中点击自建应用获取当前聊天外部联系人userid,wx.agentConfig调用
  20. 1033: 五级制成绩 C语言

热门文章

  1. Jetpack Compose之手写分享页面
  2. Python 题之“大小写字母互换”
  3. 设计模式之工厂设计模式及抽象工厂设计模式
  4. 【LC周赛241】1865. 找出和为指定值的下标对
  5. CSP202112-3登机牌条码
  6. 无线路由器首次配置、修改WiFi名称和密码—— Cisco实验/家里实验
  7. apple 产品鉴定
  8. 更自然的解决字典数组插入nil而导致crash
  9. UnicodeEncodeError: 'charmap' codec can't encode characters in position xx: character maps to undefi
  10. 小白也能看懂的自动驾驶简介