没有 Jquery 解决方案 - 基本
最基本的可拖动代码是:
Element.prototype.drag = function(){
var mousemove = function(e){ // document mousemove
this.style.left = ( e.clientX - this.dragStartX ) + 'px';
this.style.top = ( e.clientY - this.dragStartY ) + 'px';
}.bind(this);
var mouseup = function(e){ // document mouseup
document.removeEventListener('mousemove',mousemove);
document.removeEventListener('mouseup',mouseup);
}.bind(this);
this.addEventListener('mousedown',function(e){ // element mousedown
this.dragStartX = e.offsetX;
this.dragStartY = e.offsetY;
document.addEventListener('mousemove',mousemove);
document.addEventListener('mouseup',mouseup);
}.bind(this));
this.style.position = 'absolute' // fixed might work as well
}
然后使用(非jquery):
document.querySelector('.target').drag();
或在 jquery 中:
$('.target')[0].drag();
注意:被拖动的元素应该有一个position:absolute 或position:fixed 应用于它的左侧,顶部移动工作......
下面的 codepen 有一些更“高级”的功能:dragStart、dragStop 回调、附加的 css 类以在拖动时删除其他元素的文本选择,还有一个拖放功能......
签出以下代码笔:
http://codepen.io/anon/pen/VPPaEK
它基本上是在需要拖动的元素上设置一个'mousedown'事件,然后绑定和取消绑定文档mousemove来处理移动。
可拖动手柄
为了给元素设置一个可拖动的句柄
Element.prototype.drag = function( setup ){
var setup = setup || {};
var mousemove = function(e){ // document mousemove
this.style.left = ( e.clientX - this.dragStartX ) + 'px';
this.style.top = ( e.clientY - this.dragStartY ) + 'px';
}.bind(this);
var mouseup = function(e){ // document mouseup
document.removeEventListener('mousemove',mousemove);
document.removeEventListener('mouseup',mouseup);
}.bind(this);
var handle = setup.handle || this;
handle.addEventListener('mousedown',function(e){ // element mousedown
this.dragStartX = e.offsetX;
this.dragStartY = e.offsetY;
document.addEventListener('mousemove',mousemove);
document.addEventListener('mouseup',mouseup);
handle.classList.add('dragging');
}.bind(this));
handle.classList.add('draggable');
this.style.position = 'absolute' // fixed might work as well
}
上面的代码是这样使用的:
var setup = {
handle : document.querySelector('.handle')
};
document.querySelector('.box').drag(setup);
添加 CSS 以消除可选文本
现在的问题是,当拖动时,可拖动元素中的文本令人讨厌地被选中而没有用......
这就是我们向元素添加draggable 和dragging 类的原因。这将消除这种不需要的行为,并添加一个移动光标,以显示该元素是可拖动的
.draggable{
cursor: move;
position: fixed;
}
.draggable.dragging{
user-select: none;
}
添加事件
所以现在我们有了可拖动元素,有时我们需要调用各种事件。
setup.ondraginit // this is called when setting up the draggable
setup.ondragstart // this is called when mouse is down on the element
setup.ondragend // this is called when mouse is released (after dragging)
setup.ondrag // this is called while the element is being dragged
每个都将原始鼠标事件传递给特定的处理程序
最后,这就是我们得到的……
Element.prototype.drag = function( setup ){
var setup = setup || {};
var mousemove = function(e){ // document mousemove
this.style.left = ( e.clientX - this.dragStartX ) + 'px';
this.style.top = ( e.clientY - this.dragStartY ) + 'px';
setup.ondrag && setup.ondrag(e); // ondrag event
}.bind(this);
var mouseup = function(e){ // document mouseup
document.removeEventListener('mousemove',mousemove);
document.removeEventListener('mouseup',mouseup);
handle.classList.remove('dragging');
setup.ondragend && setup.ondragend(e); // ondragend event
}.bind(this);
var handle = setup.handle || this;
handle.addEventListener('mousedown',function(e){ // element mousedown
this.dragStartX = e.offsetX;
this.dragStartY = e.offsetY;
document.addEventListener('mousemove',mousemove);
document.addEventListener('mouseup',mouseup);
handle.classList.add('dragging');
setup.ondragstart && setup.ondragstart(e); // ondragstart event
}.bind(this));
handle.classList.add('draggable');
setup.ondraginit && setup.ondraginit(e); // ondraginit event
}
并使用它:
var setup = {
handle : document.querySelector('.handle'),
ondragstart : e => { console.log('drag has started!'); },
ondrag : e => { console.log('drag!'); },
ondragend : e => { console.log('drag has ended!'); }
};
document.querySelector('.box').drag(setup);
注意e.target 是对我们可拖动元素的引用