天天看點

拖放效果系列 四

在第一節我們實作了基本的拖拽效果的時候,window.onload事件的響應函數定義如下:

Javascript代碼

  1. window.onload = function(){  
  2.     test = document.getElementById("test");  
  3.     test.onmousedown = down;  
  4.     test.onmousemove = move;  
  5.     document.onmouseup = up;  
  6.         //下面三行被标出。本頁中顔色無法顯示  
  7.     test.style.position = "relative";  
  8.     test.style.top = "0px";  
  9.     test.style.left = "0px";  
  10. }  
window.onload = function(){
	test = document.getElementById("test");
	test.onmousedown = down;
	test.onmousemove = move;
	document.onmouseup = up;

        //下面三行被标出。本頁中顔色無法顯示
	test.style.position = "relative";
	test.style.top = "0px";
	test.style.left = "0px";
}
           

注意重點标出的三行代碼,我們給元素設定了relative的position屬性,這是由于元素隻有定義了position屬性,它的top和 left屬性才會有效,才能進一步地制作拖拽的效果。是以給元素假定定位為relative實在是迫于無奈,隻能犧牲一些靈活性(當然也可以指定為 absolute,要根據實際情況)。

之後我們又設定元素的top和left屬性都為0px,這是為了友善後面的代碼獲得這兩個CSS屬性,簡化了代碼。但是這同時給使用這段代碼的文檔提了一個要求——要拖拽的元素必須設定top和left屬性為0。這顯然是一個不太合理的要求。

解決問題

我們在上一個例子中已經看到如何跨浏覽器地利用JavaScript獲得元素的CSS屬性了。現在就來稍稍修改上一個例子中的函數來,讓它服務于我們的拖拽代碼:

Javascript代碼

  1. <script type="text/javascript">  
  2. ……  
  3. function dragInit(node){  
  4.     if(node.className == "drag"){   
  5.         ……  
  6.         //仍然要求元素是relative定位  
  7.         node.style.position = "relative";  
  8.         node.dragging = false;  
  9.     }  
  10.     var children = node.childNodes;  
  11.     for(var i = 0;i < children.length; i++){  
  12.         dragInit(children[i]);  
  13.     }  
  14. }  
  15. window.onload = function(){  
  16.     dragInit(document);  
  17.     document.onmouseup = docUp;  
  18. }  
  19. function down(event)  
  20. {     
  21.     event = event || window.event;   
  22.     dragElement = this;  
  23.     mouseX = parseInt(event.clientX);  
  24.     mouseY = parseInt(event.clientY);  
  25.     objY = parseInt(getNodeStyle(dragElement,"top"));  
  26.     objX = parseInt(getNodeStyle(dragElement,"left"));  
  27.     //IE不傳回未設定的CSS屬性  
  28.     if(!objY)objY=0;  
  29.     if(!objX)objX=0;  
  30.     this.style.zIndex = max++;  
  31. }  
  32. ……  
  33. function getNodeStyle(node,styleName){  
  34.     var realStyle = null;  
  35.     if(node.currentStyle){  
  36.         realStyle = node.currentStyle[styleNmae];  
  37.     }else if(window.getComputedStyle){  
  38.         realStyle = window.getComputedStyle(node,null)[styleName];  
  39.     }  
  40.     return realStyle;  
  41. }  
<script type="text/javascript">
……
function dragInit(node){
	if(node.className == "drag"){ 
		……
		//仍然要求元素是relative定位
		node.style.position = "relative";
		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; 
	dragElement = this;
	mouseX = parseInt(event.clientX);
	mouseY = parseInt(event.clientY);
	objY = parseInt(getNodeStyle(dragElement,"top"));
	objX = parseInt(getNodeStyle(dragElement,"left"));
	//IE不傳回未設定的CSS屬性
	if(!objY)objY=0;
	if(!objX)objX=0;
	this.style.zIndex = max++;
}
……
function getNodeStyle(node,styleName){
	var realStyle = null;
	if(node.currentStyle){
		realStyle = node.currentStyle[styleNmae];
	}else if(window.getComputedStyle){
		realStyle = window.getComputedStyle(node,null)[styleName];
	}
	return realStyle;
}
           

可以看到,我們使用getNodeStyle函數來獲得元素的CSS屬性值,這樣我們的代碼就可以适用于事先設定了top和left定位值的元素了。我做了一個測試頁面,給兩個可拖拽的div分别設定了如下的CSS規則:

Javascript代碼

  1. <style type="text/css">  
  2. .drag{border:1px solid; width:400px; background:#CCCCCC;}  
  3. #test1{ top:20px;}  
  4. #test2{ left:40px;}  
  5. </style>  
<style type="text/css">
.drag{border:1px solid; width:400px; background:#CCCCCC;}
#test1{ top:20px;}
#test2{ left:40px;}
</style>
           

點選進入測試頁面。這樣,我們的拖拽代碼又改進了一小步。

JavaScript拖拽系列

   1. JavaScript拖拽

   2. JavaScript拖拽2——多元素、分離JS

   3. JavaScript拖拽3——解決快速拖拽的問題

   4. JavaScript拖拽4——獲得元素的位置

   5. JavaScript拖拽5——性能優化

   6. JavaScript拖拽6——修複錯誤

繼續閱讀