JS拖拽原理


實現拖拽效果主要跟鼠標的三個事件有關:    

    onmousedown : 選擇要拖拽的元素
    onmousemove : 移動元素
    onmouseup : 釋放元素

三個事件的關系:
		obj.onmousedown = function(ev){
			var ev = ev||event;

			var disX = ev.clientX - this.offsetLeft;
			var disY = ev.clientY - this.offsetTop;
			
			obj.ommousemove = function(ev){

				var ev = ev||event;
				obj.style.left = ev.clientX - disX + 'px';
				obj.style.top = ev.clientY - disY + 'px';

			}
			obj.onmouseup = function(){
				obj.onmousemove = null;
			}

		}

  以上代碼是實現拖拽的最基本方法,但是如果鼠標移動過快脫離obj,移動就會失去效果,所以移動事件(onmousemove)應該綁定在document上面,同時onmouseup也應該綁定在document上:

obj.onmousedown = function(ev){
			var ev = ev||event;

			var disX = ev.clientX - this.offsetLeft;
			var disY = ev.clientY - this.offsetTop;
			
			document.ommousemove = function(ev){

				var ev = ev||event;
				obj.style.left = ev.clientX - disX + 'px';
				obj.style.top = ev.clientY - disY + 'px';

			}
			document.onmouseup = function(){
				obj.onmousemove = null;
			}

		}

 問題 拖拽的時候,如果有文字被選中,會產生問題

原因:當鼠標按下的時候,如果頁面中有文字被選中,那么會觸發瀏覽器默認拖拽文字的效果 ,拖拽圖片也是一樣,會類似復制一份出來一樣,解決辦法跟文字一樣

  解決:
    標准:  阻止默認行為
    非標准ie:  設置全局捕獲setCapture()(跟事件的捕獲不是一個概念)

 

全局捕獲:

例如:頁面有兩個input,點擊input1彈出1,點擊input2彈出2 ,如果我們給input1設置全局捕獲,讓后續的所有操作截取到input1上面,那么此時無論點擊input2還是點擊文檔的任何地方,包括點擊桌面,

  input1都會將這些點擊事件截取到自己身上來執行自己的click事件,就是彈出1,這就是設置全局捕獲的一個效果。

<script>
window.onload = function() {
	
	var aInput = document.getElementsByTagName('input');
	
	aInput[0].setCapture();	//設置全局捕獲 ,當我們給一個元素設置全局捕獲以后,那么這個元素就會監聽后續發生的所有事件,當有事件發生的時候,就會被當前設置了全局捕獲的元素所觸發
	
	/*
	ie : 有,並且有效果
	ff : 有,但是沒效果
	chrome : 沒有setCapture()
	*/
	
	aInput[0].onclick = function() {
		alert(1);
	}
	
	aInput[1].onclick = function() {
		alert(2);
	}
	
}
</script>
</head>

<body>
	<input type="button" value="按鈕一" />
    <input type="button" value="按鈕二" />
</body>
</html>  

  但是全局捕獲也是有兼容性的,

     ie : 有,並且有效果
	ff : 有,但是沒效果
	chrome : 沒有setCapture()

所以用的時候首先要判斷元素有沒有setCapture()
          if ( obj.setCapture ) {
			oDiv.setCapture();
		  } 

當鼠標抬起的時候也要釋放全局捕獲
releaseCapture();

所以拖拽的時候,如果有文字被選中,我們可以阻止文字的默認事件或者是利用全局捕獲將所有的事件都截取到obj上,這樣文字不會觸發事件:
 
        
<style>
#div1 {width: 100px; height: 100px; background: red; position: absolute;}
</style>
<script>
window.onload = function() {
	
	var oDiv = document.getElementById('div1');
	
	oDiv.onmousedown = function(ev) {
		var ev = ev || event;
		
		var disX = ev.clientX - this.offsetLeft;
		var disY = ev.clientY - this.offsetTop;
		
		if ( oDiv.setCapture ) {
			oDiv.setCapture();
		}
		
		document.onmousemove = function(ev) {
			var ev = ev || event;
			
			oDiv.style.left = ev.clientX - disX + 'px';
			oDiv.style.top = ev.clientY - disY + 'px';
		}
		
		document.onmouseup = function() {
			document.onmousemove = document.onmouseup = null;
			//釋放全局捕獲 releaseCapture();
			if ( oDiv.releaseCapture ) {
				oDiv.releaseCapture();
			}
		}
		
		return false;
		
	}
	
}
</script>
</head>

<body>
	jafldsfjdsjfkl
	<div id="div1"></div>
</body>
</html>

 這就是拖拽的一個最基本的實現。

 

拖拽的封裝 drag(obj);

<style>
#div1 {width: 100px; height: 100px; background: red; position: absolute;}
#img1 { position: absolute;}
</style>
<script>
window.onload = function() {
	
	var oDiv = document.getElementById('div1');
	var oImg = document.getElementById('img1');
	
	drag(oImg);
	drag(oDiv);
	
function drag(obj) { obj.onmousedown = function(ev) { var ev = ev || event; var disX = ev.clientX - this.offsetLeft; var disY = ev.clientY - this.offsetTop; if ( obj.setCapture ) { obj.setCapture(); } document.onmousemove = function(ev) { var ev = ev || event; obj.style.left = ev.clientX - disX + 'px'; obj.style.top = ev.clientY - disY + 'px'; } document.onmouseup = function() { document.onmousemove = document.onmouseup = null; //釋放全局捕獲 releaseCapture(); if ( obj.releaseCapture ) { obj.releaseCapture(); } } return false; } } } </script> </head> <body> <div id="div1"></div> <img src="1.jpg" id="img1" /> </body> </html>  

限制范圍的拖拽:

先判斷值,再賦值。
<style>
#div1 {width: 100px; height: 100px; background: red; position: absolute;}
#img1 { position: absolute;}
</style>
<script>
window.onload = function() {
	
	var oDiv = document.getElementById('div1');
	var oImg = document.getElementById('img1');
	
	drag(oImg);
	
	drag(oDiv);
	
	function drag(obj) {
		
		obj.onmousedown = function(ev) {
			var ev = ev || event;
			
			var disX = ev.clientX - this.offsetLeft;
			var disY = ev.clientY - this.offsetTop;
			
			if ( obj.setCapture ) {
				obj.setCapture();
			}
			
			document.onmousemove = function(ev) {
				var ev = ev || event;
				
				var L = ev.clientX - disX;
				var T = ev.clientY - disY;
				
				if ( L < 0 ) {
					L = 0;
				} else if ( L > document.documentElement.clientWidth - obj.offsetWidth ) {
					L = document.documentElement.clientWidth - obj.offsetWidth;
				}
				
				if ( T < 0 ) {
					T = 0;
				} else if ( T > document.documentElement.clientHeight - obj.offsetHeight ) {
					T = document.documentElement.clientHeight - obj.offsetHeight;
				}
				
				obj.style.left = L + 'px';
				obj.style.top = T + 'px';
				
			}
			
			document.onmouseup = function() {
				document.onmousemove = document.onmouseup = null;
				if ( obj.releaseCapture ) {
					obj.releaseCapture();
				}
			}
			
			return false;
			
		}
		
	}
	
}
</script>
</head>

<body>
	<div id="div1"></div>
    <img src="1.jpg" id="img1" />
</body>
</html>
 
        

 有一種磁性吸附的效果:

                   if ( L <100 ) {
					L = 0;
				} else if ( L > document.documentElement.clientWidth - obj.offsetWidth ) {
					L = document.documentElement.clientWidth - obj.offsetWidth;
				}
				
				

 

碰撞檢測實例

<style>
#div1 {width: 100px; height: 100px; background: red; position: absolute; z-index: 2;}
#img1 { position: absolute; left: 500px; top: 200px;}
</style>
<script>
window.onload = function() {
	
	var oDiv = document.getElementById('div1');
	var oImg = document.getElementById('img1');
	
	drag(oDiv);
	
	function drag(obj) {
		
		obj.onmousedown = function(ev) {
			var ev = ev || event;
			
			var disX = ev.clientX - this.offsetLeft;
			var disY = ev.clientY - this.offsetTop;
			
			if ( obj.setCapture ) {
				obj.setCapture();
			}
			
			document.onmousemove = function(ev) {
				var ev = ev || event;
				
				var L = ev.clientX - disX;
				var T = ev.clientY - disY;
				
				var L1 = L;
				var R1 = L + obj.offsetWidth;
				var T1 = T;
				var B1 = T + obj.offsetHeight;
				
				var L2 = oImg.offsetLeft;
				var R2 = L2 + oImg.offsetWidth;
				var T2 = oImg.offsetTop;
				var B2 = T2 + oImg.offsetHeight;
				
				if ( R1 < L2 || L1 > R2 || B1 < T2 || T1 > B2 ) {
					oImg.src = '1.jpg';
				} else {
					oImg.src = '2.jpg';
				}
				
				obj.style.left = L + 'px';
				obj.style.top = T + 'px';
				
			}
			
			document.onmouseup = function() {
				document.onmousemove = document.onmouseup = null;
				if ( obj.releaseCapture ) {
					obj.releaseCapture();
				}
			}
			
			return false;
			
		}
		
	}
	
}
</script>
</head>

<body>
	<div id="div1"></div>
    <img src="1.jpg" id="img1" />
</body>
</html>

  

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM