30天學會 MooTools 教學(12): Drag.Move來實現拖放
今天我們開始第十二講,今天我們將仔細看一下Drag.Move——一個很強大的MooTools類,它可以讓你給你的web應用添加拖放功能。它 的使用和我們見過的其他的插件類似:首先你使用「new」關鍵字來創建一個Drag.Move對象並賦值給一個變量,然後你再定義你的選項和事件。這就是 全部要做的事情,不過你一定要注意一下下面的例子中描述的IE的CSS怪異現象。
基本用法
Drag.Move
創建你自己的拖動對象非常的容易。稍微看一下下面的例子就行了。注意一下我們是怎麼把我們的Drag.Move對象的選項和事件從我們的Drag選 項和事件中分離出來的。Drag.Move類擴展了Drag類,因此它可以接受Drag類的選項和事件。今天我們並不打算特別地講一講Drag類,不過我 們還是要研究一下一些有用的選項和事件。看一下下面的代碼,然後學習一下其中的細節。
var myDrag = new Drag.Move(dragElement, {
    // Drag.Move的選項
    droppables: dropElement,
    container: dragContainer,
    // Drag的選項
    handle: dragHandle,
    // Drag.Move 的事件
    // Drag.Move事件會傳遞拖動的元素, 
    // 還有可接納拖動元素的元素(droppable)
    onDrop: function(el, dr) {
        // 顯示拖動到可接納元素的元素的id
        alert(dr.get('id'));
    },
    // Drag事件
    // Drag事件傳遞拖動的元素
    onComplete: function(el) {
        alert(el.get('id'));
    }
});
在這裡我們稍微打斷一下……
Drag.Move選項
Drag.Move選項有兩個很重要的元素:
- droppables——設置可接納的(droppable)元素的選擇器(這個元素將會註冊拖動相關的事件)
 - container——設置拖動元素的容器(可以保證元素一直在容器內)
 
設置這個選項非常的容易:
// 這裡我們通過id定義了一個元素
var dragElement = $('drag_element');
// 這裡我們通過class定義了一組元素
var dropElements = $$('.drag_element');
 
var dragContainer = $('drag_container');
// 現在創建我們的Drag.Move對象
var myDrag = new Drag.Move(dragElement , {
    // Drag.Move選項
    // 把我們上面定義的droppable賦值給droppables
    droppables: dropElements ,
    // 把我們的容器元素變量賦值給容器
    container: dragContainer 
});
現在你的可接受拖動元素的元素就包含進來了,你就有了一個可以接受拖放元素的類。
Drag.Move事件
這個事件可以讓你在不同的點去觸發一個函數,比如當你開始拖動一個對象或者你準備放下它。每一個Drag.Move事件都將傳遞拖動元素和接受拖動元素的元素(我們一直叫做droppable)作為參數。
- onDrop——這個事件將在一個可拖動的元素放到一個接受拖動元素的元素裡面時觸發。
 - onLeave——這個事件將在一個可拖動的元素離開一個接受拖動元素的元素時觸發。
 - onEnter——這這個事件將在一個可拖動的元素進入一個接受拖動元素的元素時觸發。
 
這些事件中的每一個事件都將調用一個函數,每個函數都將在相應的事件觸發時調用。
var dragContainer = $('drag_container');
 
var myDrag = new Drag.Move(dragElement , {
    // Drag.Move選項
    droppables: dropElements ,
    container: dragContainer ,
    // Drag.Move事件
    // Drag.Move函數將傳遞可拖動的元素(這個例子中是'el')
    // 還有接受拖動元素的元素(這個例子中是'dr')
    onDrop: function(el, dr) {
        // 下面這句的意思大概是:
        // 如果你拖動的元素不是到了可以接受拖動元素的元素的範圍內
        if (!dr) { 
            // 什麼都不做
        }
        // 否則(從邏輯上講,
        // 如果你拖動的那個的元素到了可接受拖動元素的元素範圍內)
        // 做這一件事件
        else {
            // 在這裡做一些事情
        };
    },
    onLeave: function(el, dr) {
        // 這個事件將在拖動的元素離開可接受拖動對象的元素時觸發
    },
    onEnter: function(el, dr) {
        // 這個事件將在拖動的元素進入可接受拖動對象的元素時觸發
    }
});
一些Drag事件和選項
對於Drag,有許多選項和事件,不過這裡我們只看一小部分。
snap——選項
snap選項可以讓你設置用戶的鼠標至少移動多少個像素後開始拖動。默認是6,你額可以設置為任何數字或者值為數字的變量。很明顯,這裡有一些合理的限制(比如設置snap為1000將毫無用處),但是這在定製你的用戶體驗時將會派上用場。
var myDrag = new Drag.Move(dragElement , {
    // Drag選項
    snap: 10 
});
handle——選項
handle可以給你的拖動元素添加一個控制對象。這個控制對象將成為唯一的可以接受「抓取」(拖動)的元素,從而允許你使用其他的元素做一些其他的事情。要設置一個控制對象,只需調用這個元素就可以了。
// 這裡我們使用了一個類選擇器建立了一個數組
// 這將使得我們很輕易地添加多個控制對象,如果我們決定要有多個可接受拖動元素的元素
var dragHandle = $('drag_handle');
var myDrag = new Drag.Move(dragElement , {
    // Drag選項
    handle: dragHandle 
});
onStart——事件
onStart和它名字一樣,當開始拖動時觸發這個事件。如果你設置了一個很大的snap,這個事件將不會觸發直到鼠標離開元素有指定的snap值那麼遠。
var myDrag = new Drag.Move(dragElement , {
    // Drag選項
    // Drag選項將把拖動的元素作為參數傳遞
    onStart: function(el) {
        // 在這裡放置開始拖動時你要做的任何事情
    }
});
onDarg——事件
這個onDrag事件,將會在你拖動一個元素時連續地觸發。
var myDrag = new Drag.Move(dragElement , {
    // Drag選項
    // Drag選項將把拖動的元素作為參數傳遞
    onDrag: function(el) {
        // 在這裡放置開始拖動時你要做的任何事情
    }
});
onComplete——事件
最後是onComplete事件,將在你放下一個拖動元素時觸發,而不管你是不是把它放到了一個可以接受拖動元素的元素內部。
var myDrag = new Drag.Move(dragElement , {
    // Drag選項
    // Drag選項將把拖動的元素作為參數傳遞
    onComplete: function(el) {
        // 在這裡放置開始拖動時你要做的任何事情
    }
});
代碼示例
讓我們把剛才的這些代碼以一種方式組合起來,當不同的事件觸發時,我們突出顯示不同的內容,並且我們使用上面我們看到的選項來配置我們的Drag.Move對象:
window.addEvent('domready', function() {
    var dragElement = $('drag_me');
    var dragContainer = $('drag_cont');
    var dragHandle = $('drag_me_handle');
    var dropElement = $$('.draggable');
    var startEl = $('start');
    var completeEl = $('complete');
    var dragIndicatorEl = $('drag_ind');
    var enterDrop = $('enter');
    var leaveDrop = $('leave');
    var dropDrop = $('drop_in_droppable'); 
 
    var myDrag = new Drag.Move(dragElement, {
    // Drag.Move選項
    droppables: dropElement,
    container: dragContainer,
    // Drag選項
    handle: dragHandle,
    // Drag.Move事件
    onDrop: function(el, dr) {
        if (!dr) { }
 
        else {
            dropDrop.highlight('#FB911C'); //橙色閃爍
            el.highlight('#fff'); //白色閃爍
            dr.highlight('#667C4A'); //綠色閃爍
        };
    },
    onLeave: function(el, dr) {
        leaveDrop.highlight('#FB911C'); //橙色閃爍
    },
    onEnter: function(el, dr) {
        enterDrop.highlight('#FB911C'); //橙色閃爍
    },
    // Drag事件
    onStart: function(el) {
        startEl.highlight('#FB911C'); //橙色閃爍
    },
    onDrag: function(el) {
        dragIndicatorEl.highlight('#FB911C'); //橙色閃爍
    },
    onComplete: function(el) {
        completeEl.highlight('#FB911C'); //橙色閃爍
    }
    });
});
注意一下CSS:在IE中,為了能夠適合地註冊Drag.Move的容器,你需要在下面的CSS中明確地指出它 的位置。最重要的一點是你需要記住設置容器的位置為「position: relative」,而設置可拖動的元素的位置為「position: absolute」,然後一定要設置可拖動元素的left和top屬性。現在,如果你正在為其他瀏覽器構建並且遵循此規則,你可以忽略這一部分:
/* 下面這個定義通常是不錯的主意 */
body {
    margin: 0
    padding: 0
}
 
/* 確保可拖動的元素有"position: absolute" */
/* 並設置開始時的left和top屬性 */
#drag_me {
    width: 100px
    height: 100px
    background-color: #333
    position: absolute
    top: 0
    left: 0
}
 
 
#drop_here {
    width: 200px
    height: 200px
    background-color: #eee
}
 
/* 確保拖動的容器有「position:relative」 */
#drag_cont {
    background-color: #ccc  
    height: 600px 
    width: 500px
    position: relative
    margin-top: 100px
    margin-left: 100px
} 
 
#drag_me_handle {
    width: 100%
    height: auto
    background-color: #666
}
 
#drag_me_handle span {
    display: block
    padding: 5px
}
 
 
.indicator {
    width: 100%
    height: auto
    background-color: #0066FF
    border-bottom: 1px solid #eee
}
 
.indicator span {
    padding: 10px
    display: block
}
 
.draggable {
    width: 200px
    height: 200px
    background-color: blue
}
現在我們再建立我們的HTML:
<div id="drag_cont">
    <div id="start" class="indicator"><span>拖動開始</span></div>
    <div id="drag_ind" class="indicator"><span>拖動中</span></div>
    <div id="complete" class="indicator"><span>拖動結束</span></div>
    <div id="enter" class="indicator"><span>進入了Droppable元素</span></div>
    <div id="leave" class="indicator"><span>離開了Droppable元素</span></div>
    <div id="drop_in_droppable" class="indicator"><span>放進了Droppable元素</span></div>
    <div id="drag_me">
    <div id="drag_me_handle"><span>控制對象</span></div>
    </div>
 
    <div id="drop_here" class="draggable"> </div>
</div>
更多學習……
這裡是文檔中一些相關的章節:
  下載一個包含你開始所需要的所有東西的zip包
  包含MooTools 1.2核心庫、MooTools 1.2擴展庫,一個包含你的函數的外部JavaScript文件,一個定義你的樣式的外部CSS文件,一個簡單的HTML文件和上面的例子。
  Mootools 教學列表:
- 30天學會 MooTools 教學(1): 認識MooTools
 - 30天學會 MooTools 教學(2): DOM選擇器
 - 30天學會 MooTools 教學(3): 數組管理DOM元素
 - 30天學會 MooTools 教學(4): 函數和MooTools
 - 30天學會 MooTools 教學(5): 事件處理
 - 30天學會 MooTools 教學(6): 操縱HTML DOM元素
 - 30天學會 MooTools 教學(7): 設置和獲取樣式表屬性
 - 30天學會 MooTools 教學(8): 輸入過濾-數字
 - 30天學會 MooTools 教學(9): 輸入過濾-字符串
 - 30天學會 MooTools 教學(10): Fx.Tween漸變
 - 30天學會 MooTools 教學(11): Fx.Morph、Fx選項和Fx事件
 - 30天學會 MooTools 教學(12): Drag.Move來實現拖放
 - 30天學會 MooTools 教學(13): 正規表示式
 - 30天學會 MooTools 教學(14): 定時器和Hash對象
 - 30天學會 MooTools 教學(15): 滾動條(Slider)
 - 30天學會 MooTools 教學(16): 排序類和方法簡介
 - 30天學會 MooTools 教學(17): 手風琴(Accordion)教程
 - 30天學會 MooTools 教學(18): Class 類(第一部分)
 - 30天學會 MooTools 教學(19): 工具提示 Tooltips
 - 30天學會 MooTools 教學(20): Tab 標籤頁
 - 30天學會 MooTools 教學(21): Class 類(第二部分)
 - 30天學會 MooTools 教學(22): 通過Fx.Elements同時處理多個形變動畫
 - 30天學會 MooTools 教學(23): 滑動效果(Slide)
 - 超過 50 個國外 Mootools 教學大集合