1. 程式人生 > >JavaScript之修復拖拽的bug

JavaScript之修復拖拽的bug

簡易的拖拽 

需要用到的物件和事件:

Event  物件

Event  物件代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、滑鼠的位置、滑鼠按鈕的狀態,事件通常與函式結合使用,函式不會在事件發生前被執行!

Event  物件的產生當用戶單擊某個元素的時候,我們給這個元素註冊的事件就會觸發,該事件的本質就是一個函式,而該函式的形參接收一個event物件.

onmousedown<滑鼠按下時不放 時觸發>

onmousemove<滑鼠每移動一個畫素點時觸發>

onmouseup     <滑鼠按下後鬆開時觸發>           

簡易拖拽的原理圖

JavaScript簡易拖拽原理圖


JavaScript簡易拖拽程式碼:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<!--盒子的樣式-->
		<style type="text/css">
			*{margin: 0;padding: 0;}
			#box{width: 100px; height: 100px; background:aqua; border: 1px solid orchid; box-sizing: border-box; position: absolute;}
		</style>
		<!--簡易拖拽js的程式碼塊-->
		<script type="text/javascript">
			//載入完整個頁面後執行右邊的函式
			window.onload=function (){
				//通過ID找到元素
				var oBox=document.getElementById('box');
				//先宣告作用域較大的數字型別
				//代表X軸   是盒子當前的滑鼠的X軸距的離減去盒子的距離左部的距離得到
				var disX=0;
				//代表Y軸   是盒子當前的滑鼠的Y軸距的離減去盒子的距離頭部的距離得到
				var disY=0;
				
				//onmousedown 事件  當滑鼠按下不放觸發
				//形參ev是當前事件需要向瀏覽器返回值
				oBox.onmousedown=function (ev){
					//event物件 相容性寫法
					var iEvent=ev || event;
					
					//是盒子當前的滑鼠的X軸距的離減去盒子的距離左部的距離得到
					disX=iEvent.clientX-oBox.offsetLeft;
					//是盒子當前的滑鼠的Y軸距的離減去盒子的距離頭部的距離得到
					disY=iEvent.clientY-oBox.offsetTop;
					
					//滑鼠移動一畫素觸發  onmousemove  為了作用域變大 所以加入document 在整個頁面移動都有效
					document.onmousemove=function (ev){
						var iEvent=ev || event;
						//距離左邊的值是當前滑鼠的值座標值減去  滑鼠距離盒子的邊緣的值加畫素
						oBox.style.left=iEvent.clientX-disX+'px';
						oBox.style.top =iEvent.clientY-disY+'px';
					};
					
					//當在頁面按下並且鬆開滑鼠時 觸發執行  讓滑鼠按下的事件 和滑鼠移動的事件為空
					document.onmouseup=function (){
						document.onmousedown=null;
						document.onmousemove=null;
					};
					return false;  //修復低版本的火狐瀏覽器 拖拽的時候出現殘影的問題  這裡忽略不計 
				};
			};
		</script>
	</head>
	<body>
		<div id="box"></div>
	</body>
</html>


書寫拖拽盒子中存在的bug   <已解決>

1、當滑鼠按下的時候觸發onmousedown事件滑鼠按下觸發  那麼這時候我們需要移動 因為是想達到效果是滑鼠按下拖拽著盒子進行移動,那麼就要用到onmousemove事件 滑鼠每移動一畫素,那麼就會觸發當前事件, 但是如果設定作用域在盒子自身的身上的話,很明顯 滑鼠很容易就移出到盒子的外面, 那時這個事件就無法繼續執行了. 所以為了作用域的問題 onmousemove 事件必須寫在 頁面最大的作用域 document 這整個網頁檔案最大的隱性元素節點移動在整個頁面中都有作用.

2、跟隨著上面的bug是 這時我們如果onmousemove事件 寫在onmousedown外面 並級的時候我們會發現根本不用滑鼠按下,盒子就會跟著我們移動,因為很明顯 我們是對整個頁面滑鼠移動時 做的觸發事件. 修復是把當前onmousemove滑鼠移動每一畫素的事件寫在 onmousedown 滑鼠按下執行觸發事件的裡面這樣當滑鼠按下不鬆的情況下 我們可以拖動盒子了

3、第三個是bug是滑鼠按下移動盒子,這一切都沒有問題了,但是我們發現 就算我們鬆開滑鼠 盒子還是跟隨著滑鼠的移動 因為事件一直執行著 滑鼠每移動一畫素觸發的事件onmousemove 的程式碼塊 這時候我們需要停止這些事件 所以 修復bug的話 必須設定滑鼠鬆開事件 onmouseup 當滑鼠鬆開時觸發 這時候我們讓 onmousedown 事件為空 null 並且讓 onmousemove 事件都為空 null 就會修復這個bug 讓滑鼠鬆開按鍵後 盒子不再跟著移動。

4、修復在低版本火狐瀏覽器在拖動時會出現盒子本身移動時帶有殘影的bug . 只需要在滑鼠按下事件onmousedown 的最後一行中加入 return false;

這時我們可以看到 以上程式碼基本上實現了 當滑鼠在盒子上按下不送滑鼠按鍵 並且移動的時候,盒子跟隨著滑鼠移動.並且在鬆開滑鼠後盒子不再跟著移動.

5、這個時候我們會發現 可以實現在滑鼠按下的時候拖拽移動盒子的效果了, 但是 盒子可以任意 被滑鼠拖拽移動 包括移動到瀏覽器頁面外面 <這很明顯 不符合我們的需要了>

修復bug的程式碼如下:

		<!--簡易拖拽js的程式碼塊-->
		<script type="text/javascript">
			//載入完整個頁面後執行右邊的函式
			window.onload=function (){
				//通過ID找到元素
				var oBox=document.getElementById('box');
				//先宣告作用域較大的數字型別
				//代表X軸   是盒子當前的滑鼠的X軸距的離減去盒子的距離左部的距離得到
				var disX=0;
				//代表Y軸   是盒子當前的滑鼠的Y軸距的離減去盒子的距離頭部的距離得到
				var disY=0;
				
				//onmousedown 事件  當滑鼠按下不放觸發
				//形參ev是當前事件需要向瀏覽器返回值
				oBox.onmousedown=function (ev){
					//event物件 相容性寫法
					var iEvent=ev || event;
					
					//是盒子當前的滑鼠的X軸距的離減去盒子的距離左部的距離得到
					disX=iEvent.clientX-oBox.offsetLeft;
					//是盒子當前的滑鼠的Y軸距的離減去盒子的距離頭部的距離得到
					disY=iEvent.clientY-oBox.offsetTop;
					
					//滑鼠移動一畫素觸發  onmousemove  為了作用域變大 所以加入document 在整個頁面移動都有效
					document.onmousemove=function (ev){
						var iEvent=ev || event;
						
						//為了可以實現方便對比 我們建立一個變數 來儲存滑鼠當前的距離 減去滑鼠在盒子中間時距離盒子邊緣的值
						var Left=iEvent.clientX-disX;
						var Top=iEvent.clientY-disY;
						
						
						//限制盒子不能移出瀏覽器外  判斷
						//當盒子距離左邊的值小於 即超出0時讓盒子距離左邊的值等於零
						if(Left<0){  //不能出左邊
							Left=0;
						}
						//不能出右邊
						//當盒子距離右邊的值大於  整個頁面的寬度減去盒子自身的寬度
						else if(Left>document.documentElement.clientWidth-oBox.offsetWidth){  //盒子不能出右邊
							//就讓盒子距離左邊的距離是當前頁面的寬度減去盒子自身的值  <限制在整個頁面>
							Left=document.documentElement.clientWidth-oBox.offsetWidth;
						}
						else if(Top<0){ //不能出頭部
							Top=0;
						}
						//當盒子距離上面的值大於 整個頁面高度減去盒子自身的高度時 
						else if(Top>document.documentElement.clientHeight-oBox.offsetHeight){
							//讓盒子距離頂部的距離 等於頁面視覺化介面的高度減去盒子自身高度
							Top=document.documentElement.clientHeight-oBox.offsetHeight;
						}
						
						//距離左邊的值是當前滑鼠的值座標值減去  滑鼠距離盒子的邊緣的值加畫素
						oBox.style.left=Left+'px';
						oBox.style.top =Top +'px';
						
	

					};
					
					//當在頁面按下並且鬆開滑鼠時 觸發執行  讓滑鼠按下的事件 和滑鼠移動的事件為空
					document.onmouseup=function (){
						document.onmousedown=null;
						document.onmousemove=null;
					};
					return false;  //修復低版本的火狐瀏覽器 拖拽的時候出現殘影的問題  這裡忽略不計 
				};
			};
		</script>
到此我們修復了盒子能脫出瀏覽器外的bug了.
秦卿著