移動端實現拖動操作


前言

近期有個項目需求,需要用到拖動事件。由於不需要考慮IE8等低端瀏覽器的兼容性, 所以想到HTML5中的drag事件, 但是發現移動端 android & IOS 並不支持 drag 事件。所有新事物的產生都不是偶然, 所以決定自己去實現一個頁面元素的拖動。

實現頁面元素的主要思路,是通過監聽事件(touchstart)判斷要拖動的元素並定位該元素; 然后監聽移動事件(touchmove)判斷手指移動的方向距離並將這些參數轉換為元素的移動方向距離,通過 transform (當然也可以通過定位top&left等)移動元素; 當然有開始就有停下來,所以還要監聽結束(touchend)事件,在結束的時候進行相應的處理,返回初始位置,或者停在結束的位置。

現在整體思路有了,然后就是一步步的實現。

源代碼文件

demo (請在移動端打開或者模擬移動端打開)

手機請掃

drag demo 地址二維碼

js實現拖動操作

初始化

就像蓋房子需要打地基一樣,寫程序實現一個功能需要初始化。

初始化主要是對傳入參數處理,然后做一些基本定義。在這里實現的拖動操作, 以將頁面元素拖入垃圾箱為背景來進行一系列的操作。

首先, 我們需要定義可操作的元素,即需要被拖動的元素。接下來就是對可操作元素進行操作,這里需要綁定事件,也就是touch事件,包括 touchstart/touchmove/touchend。在對應的事件內進行相應的操作,從而完成拖動

事件綁定

初始化之后,我們就需要對可操作元素進行事件的綁定,
先上代碼,以下分別是對應touch事件以及對應的操作

Drag.prototype.touchstart = function(e) {
	e.preventDefault();
	e.stopPropagation();
	var tar = e.target;
	//執行定義在拖動開始時須執行的函數, 參數為即將拖動的元素
	this.opts.onStart(tar);
	//初始化拖動元素的位置信息;
	this.dragT = tar.offsetTop;
	this.dragL = tar.offsetLeft;
	this.dragW = tar.offsetWidth || tar.clientWidth;
	this.dragH = tar.offsetHeight || tar.clientHeight;
	//定義開始移動位置
	this.startX = e.pageX || e.touches[0].pageX;
	this.startY = e.pageY || e.touches[0].pageY;
	//重置移動參數
	this.moveX = this.moveY = 0;
}

Drag.prototype.touchmove = function(e) {
	var tar = e.target;
	this.opts.onMove(tar);
	this.nowX = e.pageX || e.touches[0].pageX;
	this.nowY = e.pageY || e.touches[0].pageY;

	//計算目標元素需移動的距離
	this.moveX = this.nowX - this.startX;
	this.moveY = this.nowY - this.startY;

	//檢測是否越界,並調整
	this.checkOver(this.moveX, this.moveY);
	
	//進行拖動元素移動操作
	this.setMove(tar);

	//檢測是否落入目標位置
	this.checkPos('move', tar);

}

Drag.prototype.touchend = function(e) {
	
	//目標區域的視覺變化
	this.tarEle.style.cssText = "opacity: .5;"
	//檢測最終位置
	this.checkPos('end', e.target);
}

注:以上代碼是基於將元素拖入垃圾箱的相應事件函數,可根據自己項目情況進行調整,這里提供思路。

有了事件監聽,探知了我們手指觸摸、移動、抬起等,我們要將對應的操作實現到頁面內的元素,便需要一個移動元素的操作,便是上邊的 setMove 函數(以下方法使用前確定你的瀏覽器支持)

Drag.prototype.setMove = function(e, type) {
	var x = this.moveX || 0,
		y = this.moveY || 0;
	if(type === 'reset') {
		e.style.cssText = '';
		return;
	}
	e.style.cssText += 'position: absolute;-webkit-transform: translate('+x+'px,'+y+'px);';
}

沒錯就是簡單粗暴的調整 css 來實現移動元素

當然再加上驗證元素是否越界(這個界限根據自己情況指定,可以在自己設定的一個盒模型內,也可以是整個屏幕,根據自己情況而定,這里不貼代碼)

因為我這里有個垃圾桶,所以需要判斷拖動元素是否落入垃圾桶,然后進行后續操作

Drag.prototype.checkPos = function(type, e) {

	//判斷拖動元素是否到達目標位置,判斷方式更具情況而定,此處判斷的依據是:touch事件位置判斷,即結束時touch的位置是否在目標區域位置
	if(this.nowX > this.tarL && this.nowX < this.tarL + this.tarW &&  this.nowY > this.tarT && this.nowY < this.tarT + this.tarH) {
		//進入目標區域
		if(type === 'move' && !!this.opts.tarEle) {
			//在移動過程中,進入目標區域
			this.opts.onMoveIn(this.tarEle);
		} else {
			//在拖動結束時進入目標區域
			this.opts.onEnd(e);
		}
	} else {
		//落在目標區域外的情況
		this.tarEle.style.cssText = "opacity: .5;"
		if(type === 'end'){
			this.resetFun(e);
		}
	}
}

致此整個移動過程都已實現

此處只是指出思路,具體執行過程根據自己的項目情況進行相應的調整


免責聲明!

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



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