JS滑鼠事件完成元素拖拽(簡單-高階)

m0_54072287發表於2020-12-31

JS初學者記錄利用滑鼠事件完成元素在頁面中的拖拽

給入一個簡單div,設定樣式,完成div在頁面中的拖拽

<style>
	div{
		width:50px;
		height:50px;
		background-color:red;
		position:absolute;
	}
</style>
<div></div>

第一種:極簡單版本,下面為JS程式碼

<script>
	var div = document.querySelector("div");
		//按下時開始監聽在文件中滑鼠移動的事件
        div.onmousedown = function (e1) {
        // 當滑鼠在文件移動時,不能再div上移動,因為滑鼠可能離開div,造成無法拖拽
            document.onmousemove = function (e) {
         // 當滑鼠移動時,將當前滑鼠相對視口的座標賦值給元素的left和top
         // 因為我們需要在按下的位置拖拽,因此我們還需要獲取按下鍵滑鼠相對div的左上角位置
         // 使用當前滑鼠位置減去這個相對元素的左上角位置,保證滑鼠所按位置拖拽
                div.style.left = e.clientX - e1.offsetX + "px";
                div.style.top = e.clientY - e1.offsetY + "px";
            }
            // 當釋放滑鼠鍵時,刪除滑鼠移動事件和刪除滑鼠釋放事件
            document.onmouseup = function (e) {
                document.onmousemove = null;
                document.onmouseup = null;
            }
        }
</script>

第二種:簡單版本

<script>
		var div=document.querySelector("div");
        var offsetX,offsetY;
        div.addEventListener("mousedown",mouseDownHandler);

        function mouseDownHandler(e){
            offsetX=e.offsetX;
            offsetY=e.offsetY;
            //按下時開始監聽在文件中滑鼠移動的事件
            document.addEventListener("mousemove",mousemoveHandler);
            document.addEventListener("mouseup",mouseUpHandler);
        }
	
        function mousemoveHandler(e){
        // 用當前滑鼠位置減去這個相對元素的左上角位置,保證滑鼠所按位置拖拽
            div.style.left = e.clientX - offsetX + "px";
            div.style.top = e.clientY - offsetY + "px";
        }
		// 當釋放滑鼠鍵時,刪除滑鼠移動事件和刪除滑鼠釋放事件
        function mouseUpHandler(e){
            document.removeEventListener("mousemove",mousemoveHandler);
            document.removeEventListener("mouseup",mouseUpHandler);
        }
</script>

第三種:簡單升級版

<script>
var div = document.querySelector("div");
        var offsetX, offsetY;
        div.addEventListener("mousedown", mouseHandler);

        function mouseHandler(e) {
            if (e.type === "mousedown") {
                offsetX = e.offsetX;
                offsetY = e.offsetY;
                document.addEventListener("mousemove", mouseHandler);
                document.addEventListener("mouseup", mouseHandler);
            } else if (e.type === "mousemove") {
            // 用當前滑鼠位置減去這個相對元素的左上角位置,保證滑鼠所按位置拖拽
                div.style.left = e.clientX - offsetX + "px";
                div.style.top = e.clientY - offsetY + "px";
            } else if (e.type === "mouseup") {
            // 當釋放滑鼠鍵時,刪除滑鼠移動事件和刪除滑鼠釋放事件
                document.removeEventListener("mousemove", mouseHandler);
                document.removeEventListener("mouseup", mouseHandler);
            }
        }
</script>

第四種:中級版本 拖拽多個元素時

<script>
 var divs = document.querySelectorAll("div");
        // 給每一個div元素新增滑鼠按下事件
        for (i = 0; i < divs.length; i++) {
            divs[i].addEventListener("mousedown", mouseHandler);
        }

        function mouseHandler(e) {
            if (e.type === "mousedown") {
                //取消預設事件
                e.preventDefault();
                //this為點選的目標元素
                document.div = this;
                document.offset = { x: e.offsetX, y: e.offsetY };
                document.addEventListener("mousemove", mouseHandler);
                document.addEventListener("mouseup", mouseHandler);
            } else if (e.type === "mousemove") {
                //這裡的this就是執行偵聽事件的物件,也就是document,document.div就是點選的目標元素
                // this.div.style.left = e.clientX - document.offset.x + "px";
                // this.div.style.top = e.clientY - document.offset.y + "px";
                // 用當前滑鼠位置減去這個相對元素的左上角位置,保證滑鼠所按位置拖拽
                document.div.style.left = e.clientX - document.offset.x + "px";
                document.div.style.top = e.clientY - document.offset.y + "px";
            } else if (e.type === "mouseup") {
                document.removeEventListener("mousemove", mouseHandler);
                document.removeEventListener("mouseup", mouseHandler);
            }
        }
</script>

第五種:高階版本,把事件函式封裝在一個物件裡面,使用時直接填入引數呼叫;下面程式碼為封裝好的函式

var Utils=(function(){
        // 封裝版的拖拽
        // 不能再容器內拖拽
    return {
        dragOn(elem){
            elem.self=this;
            elem.addEventListener("mousedown",this.mouseHandler);
        },
        dragOff(elem){
            elem.addEventListener("mousdown",this.mouseHandler);
        },
        mouseHandler(e){
            if(e.type==="mousedown"){
                e.preventDefault();
                document.div=e.target;
                document.offset={x:e.offsetX,y:e.offsetY};
                document.self=this.self;
                document.addEventListener("mousemove",this.self.mouseHandler);
                document.addEventListener("mouseup",this.self.mouseHandler);
            }else if(e.type==="mousemove"){
                document.div.style.left=e.clientX-document.offset.x+"px";
                document.div.style.top=e.clientY-document.offset.y+"px";
            }else if(e.type==="mouseup"){
                // this document
                document.removeEventListener("mousemove",document.self.mouseHandler)
                document.removeEventListener("mouseup",document.self.mouseHandler)
            }
        }
    }
})();

執行時呼叫封裝好的函式填入引數即可

<script src="./js/Utils.js"></script>

給divs裡面給個div都呼叫一次封裝好的函式,這樣就可以拖拽每個div元素

var divs=document.querySelectorAll("div");
            for(var i=0;i<divs.length;i++){
                Utils.dragOn(divs[i]);
            }

第六種:終極版本,老師沒教。

相關文章