原文來自:[url]http://www.cainiao8.com/web/js_examples/14_tuozhuai2.html[/url]
上一節我們實作了基本的拖拽,但是需要給可拖拽的元素設定一個特定的id,然後再在JS中修改代碼,使用起來比較麻煩。這樣一旦文檔結構發生變化就要調整JS代碼,沒有做到JavaScript與HTML分離的原則。
是以應該實作一個可以适用于多個元素的拖拽代碼,而且代碼在可拖拽元素改變後應該不需要修改而仍然能正常工作。
使用class做“鈎子”
為了使代碼适用于多個元素,我們使用它的class來指定元素是否可以拖拽。我們使用如下的JavaScript代碼來周遊文檔中所有的節點,然後讓class為drag的元素可以被拖拽。
function dragInit(node){
if(node.className == "drag"){
node.onmousedown = down;
node.onmousemove = move;
node.style.position = "relative";
node.style.top = "0px";
node.style.left = "0px";
}
var children = node.childNodes;
for(var i = 0;i < children.length; i++){
dragInit(children[i]);
}
}
dragInit函數會逐個檢查各個節點的class是否為drag,如是是,那麼會為該元素設定滑鼠經過、滑鼠按下事件的響應函數。
多個元素一起移動的問題
上面我們已經實作了多個元素可移動的問題。可以進入這個網頁測試一下。可以發現這個拖拽效果有一個嚴重的問題。當我們拖動div1的時候,如果滑鼠路徑經過了div2,那麼兩個div會同時移動。原因是這觸發了 div2的onmouseover事件。我們可以通過給元素設定z-index的方法來解決。因為當我們拖動z-index較高的元素經過z-index 較低的元素時并不會觸發z-index較低元素的滑鼠經過事件。是以我們對代碼做出如下修改:
<script type="text/javascript">
var max = 1;//定義一個max變量
……其它部分不變
function down(event)
{
……
//保證點選元素的z-index最高
this.style.zIndex = max++;
}
</script>
我們設定了一個max變量來記錄目前的z-index值,當點選一個元素的時候就用max的值來設定它的z-index屬性,同時max的值會變大。這樣就實作了每次拖拽一個元素的時候,不會觸發其它元素的mouseover事件。但是,
我們發現,當拖動元素的速度非常快的時候,仍然會造成兩個元素一起移動。我個人認為這是浏覽器處理事件的延遲造成的。通過給每個對象分别設定一個判斷拖拽狀态的布爾變量dragging就可以解決這個問題了。最終的代碼如下:
拖拽JavaScript代碼
<script type="text/javascript">
var dragging = false;
var mouseY;
var mouseX;
var max = 1;
function dragInit(node){
if(node.className == "drag"){
node.onmousedown = down;
node.onmousemove = move;
node.onmouseover = over;
node.onmouseup = up;
node.style.position = "relative";
node.style.top = "0px";
node.style.left = "0px";
node.dragging = false;
}
var children = node.childNodes;
for(var i = 0;i < children.length; i++){
dragInit(children[i]);
}
}
window.onload = function(){
dragInit(document);
document.onmouseup = docUp;
}
function down(event)
{
event = event || window.event;
dragging = true;
this.dragging = true;
mouseX = parseInt(event.clientX);
mouseY = parseInt(event.clientY);
objY = parseInt(this.style.top);
objX = parseInt(this.style.left);
this.style.zIndex = max++;
}
function move(event){
event = event || window.event;
if(this.dragging == true && dragging == true){
var x,y;
y = event.clientY - mouseY + objY;
x = event.clientX - mouseX + objX;
this.style.top = y + "px";
this.style.left = x + "px";
}
}
function up(){
this.dragging = false;
}
function docUp(){
dragging = false;
}
function over(){
this.style.cursor = "move";
}
</script>
做出修改的代碼用已經标記了出來。[url=http://www.cainiao8.com/web/js_examples/tuozhuai_ex2.html]點選進入示例網頁。[/url]
JavaScript拖拽系列
1. JavaScript拖拽
2. JavaScript拖拽2——多元素、分離JS
3. JavaScript拖拽3——解決快速拖拽的問題
4. JavaScript拖拽4——獲得元素的位置
5. JavaScript拖拽5——性能優化
6. JavaScript拖拽6——修複錯誤