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拖拽构造函数封装+自定义事件_第1张图片

播放器进度条实际运用

/* 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

你可能感兴趣的:(js拖拽构造函数封装+自定义事件)