天天看點

JavaScript 拖放效果系列二——多元素、分離JS

原文來自:[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——修複錯誤

繼續閱讀