天天看點

js拖拽構造函數封裝+自定義事件

DranInit構造函數使用+源碼

1.定義規則(down,move,up)

  • 函數client是包裝好的對象, client是滑鼠的x與y軸距離視口位置 {x:…,y:…}
  • 函數體this指向拖動塊元素
  • 函數體mousedown不能為空,其餘可以為空或則null,false 為空代表不執行該規則
var drag = new DragInit({
    mousedown: function (client) { 	 // 滑鼠按下規則
    },
    mousemove: function (client) {	// 滑鼠移動規則
    },
    mouseup: function (client) {	// 滑鼠松開規則
    }
})
           

2.為元素添加拖拽

drag.ev(dragEl_1)
// drag的ev方法可以定義多個元素拖拽,并且享用共同的拖拽規則
drag.ev(dragEl_2)
           

3.為拖拽添加自定義事件(可選)

  • 定義自定義事件是為了更好的區分拖拽規則和根據拖動改變的其他元素
  • dragRect是拖動塊資訊, 包含元素内滑鼠的x與y軸和寬搞
  • 函數體this指向拖拽塊元素dragEl
drag.ev(dragEl,
       function (dragRect) { // 滑鼠按下自定義事件 

    }, function (dragRect) { // 滑鼠移動自定義事件 

    }, function (dragRect) { // 滑鼠松開自定義事件 
    })
           

實作一個簡單的拖拽

var drag = new InitDrag({ 
    mousedown: function(ev){ 	 // 滑鼠按下規則
		// 按下時儲存元素内滑鼠偏移量
		this.offsetX =  ev.x - this.offsetLeft
		this.offsetY =	ev.y - this.offsetTop  
    },
    mousemove: function(ev){	// 滑鼠移動規則
    	// 移動時減去元素内滑鼠偏移量
		this.style.left = ev.x - this.offsetX +"px"
		this.style.top = ev.y - this.offsetY +"px"
    },
    mouseup: function(ev){}  	// 滑鼠松開規則
}) 	
var div = document.querySelector('div')
// 綁定元素
drag.ev(div)
           
js拖拽構造函數封裝+自定義事件

播放器進度條實際運用

/* progress_bar歌曲進度條 */
var prog_drag = InitDrag({//定義進度條拖拽規則 
    mousedown: function(ev){ 
        var client_x = ev.x;									// 滑鼠距離視口
        var changeEl = this.changeEl							// 擷取需要變化的元素
        var domClient_x = changeEl.getBoundingClientRect().x 	// 小方塊距離視口
        var domOffset_x = changeEl.offsetLeft 					// 離父元素的距離
        var domOffset_w = changeEl.offsetWidth 					// 小方塊寬度
        changeEl.style.left = domOffset_x + client_x - domClient_x - domOffset_w/2 +'px'
    },
    mousemove: function (ev) { 
        var client_x = ev.x;									// 滑鼠距離視口
        var changeEl = this.changeEl							// 擷取需要變化的元素
        var domClient_x = changeEl.getBoundingClientRect().x 	// 小方塊距離視口
        var domOffset_x = changeEl.offsetLeft 					// 離父元素的距離
        var domOffset_w = changeEl.offsetWidth 					// 小方塊寬度
        // 滑鼠距離 - 小方塊到視口距離 - 小方塊寬度/2 + 小方塊離父元素距離 
        var move_x = client_x - domClient_x - domOffset_w/2 + domOffset_x
        // 讓目标元素永遠保持在父元素内
        if(move_x < 0) {move_x = 0}
        move_x = move_x > this.offsetWidth ? this.offsetWidth : move_x,
        // 執行變化
        changeEl.style.left = (move_x) + "px";
    }
})
// 不使用自定義事件開啟拖拽
// var pro_drag = $('.progress_bar .drag-box')[0]
// prog_drag.ev(pro_drag)

// 使用自定義事件開啟拖拽
// 拖動塊元素
	var pro_drag = $('.progress_bar .drag-box')[0]
	// 變化塊元素
	pro_drag.changeEl = $('.progress_bar .drag-box .ball')[0]
	// 開啟拖拽
	prog_drag.ev(pro_drag, 
	function(dragRect){ // 按下事件回調 接收拖動塊資訊
		// 自定義事件可以幹很多事情,比如這裡,我在按下的時候停止了播放器的同步定時器
		clearInterval(player.timer)
	},
	function(dragRect){ // 移動事件回調 接收拖動塊資訊

		// 這裡我讓音頻的時間顯示根據音頻總時間和拖動百分比改變

		var perc = dragRect.x / (dragRect.width/100) // 移動百分比
		var duration = player.audio.duration // 音頻總時間
		// 移動百分比 * 總時間百分比 在調用播放器的秒數轉00:00函數
		$('time .being').text(player.converTimeFormat(perc * (duration / 100)))
	},
	function(dragRect){ // 松開事件回調 接收拖動塊資訊

		// 這裡我根據拖動的百分比更改了音頻時間

		var perc = dragRect.x / (dragRect.width/100)// 移動百分比
		var duration = player.audio.duration // 音頻總時間
		player.audio.currentTime = perc * duration/100 // 更改時間
		player.synch()// 開啟歌曲同步
		// 如果播放器是沒有播放的狀态, 那麼過2秒停止同步器
		if(player.audio.paused == true){clearInterval(player.timer)}
	})
           

構造函數源碼

function DragInit(dragRule) { // 拖拽函數
    return DragInit.prototype.init(dragRule)
}
DragInit.prototype = {
    init: function (dragRule) { // 初始化資料
        this.dragRule = dragRule // 擷取拖動dom
    },
    getDragRect: function (dragEl, bit) { // 擷取拖動塊資訊
        var dragRect = {}
        dragRect.x = bit.x - dragEl.getBoundingClientRect().x // 擷取拖動塊内x軸
        dragRect.y = bit.y - dragEl.getBoundingClientRect().y // 擷取拖動塊内y軸
        dragRect.width = dragEl.getBoundingClientRect().width	// 擷取拖動塊寬
        dragRect.height = dragEl.getBoundingClientRect().height // 擷取托都塊高
        return dragRect
    },
    ev: function (dragEl, downCallBack, moveCallBack, upCallback) { // 拖拽事件代碼
        var dragRule = this.dragRule
        var $this = this
        dragEl.onmousedown = function (ev) {
            //當點選時所有事件都捕獲為dragEl的事件
            document.setCapture && document.setCapture();
            // 相容浏覽器
            ev = ev || window.event;
            // 将按下位置儲存為startBit(初始位)
            var startBit = { x: ev.clientX, y: ev.clientY }

            // 執行拖拽元素規則 傳入滑鼠位置與拖動元素
            dragRule.mousedown && dragRule.mousedown.call(dragEl, startBit)
            // 執行按下回調,傳入元素内移動值和寬高 如果沒有值,則不執行
            downCallBack && downCallBack.call(dragEl, $this.getDragRect(dragEl, startBit))


            // ondragenter ondragover事件内容為event.preventDefault()
            document.onmousemove = function (ev) {
                ev = ev || window.event;
                // 将按下位置儲存為startBit(移動位)
                var moveBit = { x: ev.clientX, y: ev.clientY }

                // 執行拖拽元素規則 傳入滑鼠位置與拖動元素
                dragRule.mousemove && dragRule.mousemove.call(dragEl, moveBit)
                // 執行移動回調,傳入元素内移動值和寬高 如果沒有值,則不執行
                moveCallBack && moveCallBack.call(dragEl, $this.getDragRect(dragEl, moveBit))


                document.onmouseup = function (ev) {
                    ev = ev || window.event;
                    // 釋放document的move事件
                    document.onmousemove = null;
                    // 釋放document的onmouseup事件
                    document.onmouseup = null;
                    //釋放dragEl的點選事件
                    document.releaseCapture && document.releaseCapture();
                    // 将按下位置儲存為startBit(移動位)
                    var endBit = { x: ev.clientX, y: ev.clientY }

                    // 執行拖拽元素規則 傳入滑鼠位置與拖動元素
                    dragRule.mouseup && dragRule.mouseup.call(dragEl, startBit)
                    // 執行松開回調
                    upCallback && upCallback.call(dragEl, $this.getDragRect(dragEl, moveBit))
                }; return;



            }; return;
        }
    }
}
DragInit.prototype.init.prototype = DragInit.prototype
           

繼續閱讀