无Jquery解决方案-基础
最基本的可拖动代码如下:
Element.prototype.drag = function(){
var mousemove = function(e){
this.style.left = ( e.clientX - this.dragStartX ) + 'px';
this.style.top = ( e.clientY - this.dragStartY ) + 'px';
}.bind(this);
var mouseup = function(e){
document.removeEventListener('mousemove',mousemove);
document.removeEventListener('mouseup',mouseup);
}.bind(this);
this.addEventListener('mousedown',function(e){
this.dragStartX = e.offsetX;
this.dragStartY = e.offsetY;
document.addEventListener('mousemove',mousemove);
document.addEventListener('mouseup',mouseup);
}.bind(this));
this.style.position = 'absolute'
}
然后使用(非jQuery):
document.querySelector('.target').drag();
或使用jQuery:
$('.target')[0].drag();
注意:被拖动的元素应该应用position:absolute
或position:fixed
以使左、上移动生效...
以下CodePen具有一些更高级的功能:dragStart、dragStop回调,追加CSS类来移除拖动时其他元素的文本选择,还具有放置特性...
请查看以下CodePen:http://codepen.io/anon/pen/VPPaEK
基本上是在需要拖动的元素上设置'mousedown'事件,然后绑定和解绑文档mousemove来处理移动。
可拖动手柄
为了为元素设置可拖动手柄
Element.prototype.drag = function( setup ){
var setup = setup || {};
var mousemove = function(e){
this.style.left = ( e.clientX - this.dragStartX ) + 'px';
this.style.top = ( e.clientY - this.dragStartY ) + 'px';
}.bind(this);
var mouseup = function(e){
document.removeEventListener('mousemove',mousemove);
document.removeEventListener('mouseup',mouseup);
}.bind(this);
var handle = setup.handle || this;
handle.addEventListener('mousedown',function(e){
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'
}
以上代码的用法如下:
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){
this.style.left = ( e.clientX - this.dragStartX ) + 'px';
this.style.top = ( e.clientY - this.dragStartY ) + 'px';
setup.ondrag && setup.ondrag(e);
}.bind(this);
var mouseup = function(e){
document.removeEventListener('mousemove',mousemove);
document.removeEventListener('mouseup',mouseup);
handle.classList.remove('dragging');
setup.ondragend && setup.ondragend(e);
}.bind(this);
var handle = setup.handle || this;
handle.addEventListener('mousedown',function(e){
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);
}.bind(this));
handle.classList.add('draggable');
setup.ondraginit && setup.ondraginit(e);
}
而要使用它:
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
是指向我们可拖动元素的引用。
mouseleave
事件来扩展代码,例如$("body").mouseleave(function(e) { $dragging = null; })
,以便在浏览器窗口外释放按下的按钮。 - rabudde