天天看點

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

demo網址:

http://jianwangsan.cn/toolbox

(五)添加、點選和移動的邏輯

我反思了一下,在(四)中我寫的并不好,事實上,無論是大按鈕,還是被添加到我的工具,或者是添加到常用工具欄,他都是一個按鈕,是以,應該共享狀态,即他們屬于同一個tool執行個體,并能互相影響。

在重寫tool類之前,需要明确分析按鈕的邏輯。

在全部工具頁面:

①當按鈕未被添加時,滑鼠移動上去會有添加按鈕顯示;

②當按鈕未被添加時,滑鼠無論點選按鈕本身還是點選添加按鈕,都執行添加邏輯,将添加按鈕顯示為取消,執行一次添加動畫,添加完成後,按鈕隐藏;

③當按鈕已被添加時,滑鼠點選會啟用按鈕本身的邏輯(比如打開軟體);

在我的工具頁面:

①當按鈕未被添加時,不顯示;

②當按鈕被添加時,顯示按鈕;

③點選按鈕時,點選會啟用按鈕本身的邏輯(比如打開軟體);

④長按按鈕,可以拖動按鈕,原有按鈕位置不被占用,顯示為空白;

⑤按鈕拖動中時,若經過某個已有按鈕的位置,原按鈕位置不再被占用,經過的位置被空白占用,相當于把空白占位符從dom中的原位置挪到了dom樹中的新位置;

⑥按鈕拖動時,可以離開工具箱的頁面顯示範圍,但不會顯示出來(類似overflow:hidden)的效果;

⑦當按鈕拖動到主界面快捷入口的四個圖示範圍時,若原位置有圖示,再該位置圖示及右側所有圖示依次向右移動一位;當離開這個位置時,原有圖示立刻傳回原位置;

⑧主界面快捷入口最多有四個圖示,假如新插入一個,那麼原本最右邊的将被移除;

⑨點選編輯按鈕時,所有圖示右上角都會出現一個紅叉符号;

(10)當編輯狀态時,點選主界面快捷入口的四個圖示的紅叉時,将移除被點選的那個圖示;

(11)當編輯狀态時,點選我的工具的圖示的紅叉,将删除該圖示(全部工具裡的添加按鈕恢複);若該圖示在快捷入口也存在時,快捷入口的該圖示也被删除。

是以,這個tool類也能滿足以上功能;

①要有四種狀态的圖示,依次為全部工具頁面的大圖示、普通圖示,我的工具頁面的普通圖示、快捷入口圖示;

②并且,要能建立這些圖示,并且,由于之前沒有設計全部工具頁面的取消按鈕、我的工具頁面裡的編輯按鈕,是以要添上;

我的工具裡圖示的html模闆:,編輯按鈕預設為不顯示:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

div.tool-my  

    div.img  

    div.text    小清新月曆  

    div.edit-img.displaynone  

快捷入口的按鈕的html模闆:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

div.tool-foot  

    div.text    系統急救箱  

取消按鈕添加後的大圖示:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

div.bigtool  

    span.img  

    span.mask  

    div.text  

        div.title  

        div.description  

    div.button.add  添 加  

    div.button.cancel.displaynone   取 消  

取消按鈕添加後的html模闆:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

div.normaltool  

另附2個新增的css樣式:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

.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 {  

    top: 10px;  

然後是樣式修改:

顯示大圖示的:

把原來的addbutton拆分成button、add和cancel

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

.back .contentbox .toolbox-all .firstrow .bigtool .button {  

    display: none;  

    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 {  

另外一個類似

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

.back .contentbox .commonrow .normaltool .button {  

    top: 7px;  

    right: 15px;  

.back .contentbox .commonrow .normaltool .add {  

.back .contentbox .commonrow .normaltool .cancel {  

.back .contentbox .commonrow .normaltool:hover .add {  

為了符合實際需求,我們需要做以下工作:

①重構tool類(之前實在太簡陋了);

②需要一個函數,專用進行操作;

③需要一個runafter函數,他的效果是,監聽某個對象的某個方法,在該方法執行完後執行runafter的回調函數;

④然後利用這個runafter監聽一些函數,并在該函數觸發時做一些事情。

他分為以下幾個部分:

①變量聲明(私有變量):

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

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類裡調用),一個是公有的(會在外面調用),是以聲明方式不同:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//擷取dom  

var getdominalltools = function () {  

    return bigimgdom ? bigimgdom : normaltooldom;   //因為隻有一個存在  

};  

this.getdominmytools = function () {  

    return inmytooldom;  

③建立圖示

我們自然需要建立圖示,四種圖示都需要一個函數(因為他們的dom結構不同);

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//全部工具頁面  

//  大按鈕  

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>' +  

    normaltooldom = $(str);  

    addbutton = normaltooldom.find(".add");  

    cancelbutton = normaltooldom.find(".cancel");  

//我的工具頁面  

//  建立普通的dom  

var createinmytooldom = function () {  

    var str = '<div class="tool-my">' +  

        '<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>' +  

注:

(1)以上四個建立圖示,在全部工具裡的兩種還額外擷取了編輯按鈕;

(2)建立全部工具的圖示時,順便擷取了響應函數

④響應邏輯:

圖示建立了必然需要對她設定事件,

(1)比如全部工具裡圖示的點選事件:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//  設定全部工具裡的點選事件  

var setclickevent = function () {  

    var node = bigimgdom ? bigimgdom : normaltooldom;  

    node.click(function (event) {  

        if (state) {  

            domclickevent();  

        } else if (state === 0) {  

            self.adddomtomytools();  

        }  

    });  

(2)以上點選事件又分為兩種,已添加時,觸發正常的響應邏輯(在建立圖示時作為參數傳進來的回調函數);

未添加時,用于添加到我的工具裡的函數:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//将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】點選事件:

(但事實上這個已廢棄,因為後面涉及到移動按鈕的函數,被整合在那裡了)

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//  設定我的工具頁面的兩種按鈕的點選事件  

var setmytoolclickevent = function (node) {  

        if (!editing) {  

【2】編輯按鈕點選事件:

(同樣已廢棄,因為後面涉及到移動按鈕的函數,被整合在那裡了)

【3】設定按鈕的移動函數,包括以上兩個被整合的事件:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//我的工具大圖示的移動函數  

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();  

        mousex = evt.clientx;   //這裡的值是滑鼠坐标  

        mousey = evt.clienty;  

        var position = inmytooldom.position();  

        startleft = position.left;  //沒有px  

        starttop = 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) {  

    })  

解釋:

以上這個函數幹了以下事:

《1》隻有滑鼠左鍵按下才有效;

《2》編輯狀态時,按編輯按鈕是有效的;(是以我們需要一個設定編輯狀态的函數)

《3》編輯狀态時點選編輯按鈕,會删除目前按鈕,并用一個空白的按鈕替代;

《4》這個dom移除,為了不移除他的事件,是以用的是jquery的detach()方法,并阻止該按鈕事件的冒泡;

《5》非編輯狀态時,可以移動按鈕,原理是設定該按鈕的定位為絕對定位,并用一個空白按鈕放在該按鈕的dom後起到占位作用,并設定該按鈕可移動;

《6》由于代碼本身寫的并不是很好,是以移動狀态被取消時,計算移動距離,如果沒有位移偏差,且非編輯狀态,觸發該按鈕的點選事件;(如果要寫的好的話,該按鈕的移動狀态設定,應該在移動位置有偏差之後才設定position為絕對定位);

《7》移動時觸發一個inmytooldommoving方法,這個要被runafter方法所監視,傳回值是空白dom和滑鼠移動時觸發的event事件。該事件會決定該按鈕和其他按鈕的互動;

《8》移動結束後,會觸發一個inmytooldomendmoving方法,該方法同樣被監視。并且設定移動結束後的滑鼠彈起事件(同移動中的那個)。

《9》移動結束後,把圖示放在占位圖示之前(注意,該占位圖示的位置可能移動),并解除移動狀态,取消絕對定位,移除占位圖示;

【4】然後是我的工具的大圖示的移動中事件:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

this.inmytooldomendmoving = function () {  

    if (!smalltooldom) {  

        smalltooldom = createsmalltool();  

        //setmytoolclickevent(smalltooldom);  

        editbuttoninsmalltooldom = smalltooldom.find(".edit-img");  

        setsmalleditevent(editbuttoninsmalltooldom);  

        setsmalltooldommoveevent();  

    return smalltooldom;  

他會傳回小圖示,如果沒有小圖示則建立,并為他綁定事件。

綁定事件有:

《1》點選事件(整合進移動相關函數);

《2》編輯按鈕點選事件:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//  設定小的dom的編輯按鈕的點選事件  

var setsmalleditevent = function (editnode) {  

    editnode.click(function (event) {  

        self.removesmalltool();  

        editbuttoninsmalltooldom.addclass("displaynone");  

        smalltooldom.detach();  

        event.stoppropagation();  

《3》移動事件;

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

var setsmalltooldommoveevent = function () {  

    var placehholderdom = $('<div class="tool-foot placeholder smalltoolholder">' +  

        '<div class="placeholder-img"></div>' +  

        '<div class="text">拖拽到此</div>' +  

        '</div>');  

    smalltooldom.mousedown(function (evt) {  

        if (editing & $(evt.target)[0] == editbuttoninsmalltooldom[0]) {  

        var position = smalltooldom.position();  

        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();  

        if (!evt.buttons & smalliconmove) {  //隻有不在按,且目前是true的時候,才觸發  

            smalliconmove = false;  

            placehholderdom.before(smalltooldom);  

            smalltooldom.css("position", "relative");  

            smalltooldom.css("left", "0");  

            smalltooldom.css("top", "0");  

            $(".smalltoolholder").remove();  

        if (smalliconmove) {  

            self.smalltooldommoving([placehholderdom, evt]);  

            smalltooldom.css("left", offsetx + startleft + "px");  

            smalltooldom.css("top", offsety + starttop + "px");  

            if ($(".smalltoolholder").length > 1) {  

                $(".smalltoolholder")[1].remove();  

    smalltooldom.mouseup(function (evt) {  

由于和大圖示的移動按鈕事件類似,就不細說了

總之,他在移動的時候,會觸發一個smalltooldommoving方法,runafter會監視他。

【5】下來是兩個按鈕移動時觸發的事件和移動結束後觸發的事件:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//移動時會觸發這個方法  

this.inmytooldommoving = function (arr) {  

    return arr;  

this.smalltooldommoving = function (arr) {  

⑤其他事件:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//設定編輯或者結束編輯  

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");  

    if (editbuttoninsmalltooldom) {  

    state = 0;  //設定其狀态為未添加  

編輯狀态的兩個方法用于設定可編輯或者不可編輯;

另一個用于在删除按鈕時調用;

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

這個函數做了這些事情:

①讀取json;

②把json轉化為tool類的資料來源;

③建立tool類執行個體,并監聽其事件;

④在建立圖示的時候,添加分割線、或者建立占位圖示等;

聲明這個函數:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

var toolsconfigjsonload = function (inmytoolarray, url) {  

    this.url = url ? url : "data/tools.json";  

這個函數隻有一個公有方法,那就是讀取json:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

this.load = function () {  

    $.ajax({  

        url: self.url,  

        datatype: "json",  

        type: "get",  

        success: function (data) {  

            addtoolsintoolbox_all(data);  

讀取json成功之後調用的函數:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//将内容添加到全部工具頁面中  

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);  

        $(".commonrow." + obj.type).append(tool.createnormaltooldom(callback));  

    addplaceholderwhenonlytwotoolsintoolbox_all(type);  

    adddottedlineintoolbox_all();  

監聽事件先略過;

添加分割線:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

// 這個目的是為了給全部工具中的多行工具之間添加分割線  

var adddottedlineintoolbox_all = function () {  

    $(".commonrow .normaltool:nth-child(3n+4)").before('<div class="dotted"></div>');  

為保證美觀,添加占位圖示:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

// 這個目的是當某一行隻有兩個圖示時,創造一個占位的圖示  

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>'));  

下來事件監聽函數的原型:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//參數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類的執行個體。

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

//監聽事件  

var listentoolevent = function (tool) {  

他包含以下方法:

①當圖示添加進我的工具時,将執行個體添加到一個數組中:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

runafter(tool, "adddomtomytools", function () {  

    inmytoolarray.push(tool);  

});  

②或者是删除我的工具裡的按鈕時,移除這個執行個體:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

runafter(tool, "setstatetounadd", function () {  

    var mytoolindex = inmytoolarray.indexof(tool);  

    inmytoolarray.splice(mytoolindex, 1);  

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

</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>')  

④監聽圖示移動時的方法,他涉及到我的工具頁面裡大圖示的互動,和快捷入口小圖示的互動:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

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");  

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

</pre><p>⑤當圖示停止移動時,需要決定他是否被移動到一個新位置,或者是添加到快捷入口那裡;</p><pre name="code" class="javascript">runafter(tool, "inmytooldomendmoving", function (obj, node) {  

    var sign = false;  

        if ($(node)[0] == placeholderinsmall[0]) {  

            sign = true;  

    if (sign) {  

        if (node.hasclass("displaynone")) {  

            node.removeclass("displaynone");  

        placeholderinsmall.before(node);  

    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) {  

    $(".tool-foot").toarray().foreach(function (node) {  

        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);  

                    $(node).after(placeholder);  

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

讓工具箱運作起來:

以上代碼,隻涉及到工具箱頁面各個圖示的互動邏輯,但是并沒有真正運作起來(例如,沒有顯式調用load()方法),并且也沒有編輯圖示的邏輯。

是以,我們需要一個函數補全剩下的部分:

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

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 {  

                item.setediting();  

            $(this).addclass("editing");  

            text.text("退出編輯");  

            text.css("width", "52px");  

            text.css("margin-left", "-10px");  

前端的小玩意(9.5)——做一個仿360工具箱的web頁面(完結篇,可以跑起來的工具箱)

這個函數幹了兩件事:

①聲明一個toolsconfigjsonload類的執行個體,并調用它的load方法(加載工具箱);

②設定編輯按鈕的事件。

這樣的話,工具箱就可以正常跑起來了。

當然,還有一些小bug,需要被修複,不過這并不影響整體功能的運轉,作為一個demo來說,程度是足夠了,如果真要跑生産環境,那麼這些bug必須被fix

js全部代碼:

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

css全部代碼:

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

繼續閱讀