JavaScript implementation of the mouse drag element instance code
- 2020-03-30 02:06:43
- OfStack
One, foreword
The most began to realize the purpose of the mouse drag elements is drag a lot of dots on a page, in a fixed location, and then copy the HTML, paste in the development of the page code, is such a function, implementation for many times, all was not well done, have adopted the jQuery. Fn. Draggable plug-ins, in contact with some information and other people's ideas, today finally give the drag function to perfect, take a look at below its implementation
Two, design ideas
Bind the mouse down event on the drag element, bind the mouse movement in the document object, mouse up event;
Why not bind all three events to the drag element, because the mouse movement and unevent handlers will not execute if the mouse moves too fast
$target.bind('mousedown', fn);
$(document)
.bind('mousemove', fn)
.bind('mouseup', fn);
Three, the source code implementation details
There are many things to note in the implementation of the source code:
1. First, in the mousedown event, when you click and drag the element, you may select the text of the region, which is not what we need. The solution is as follows:
//Block field text from being selected for chrome firefox ie9
e.preventDefault();
// for firefox ie9 || less than ie9
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
2, if the drag element is an image (img label), the mouse in the drag picture for a short distance, will appear a prohibited tip, that is: the picture can not be dragged,
This is the default behavior of the browser, so simply block the default behavior of the browser
e.preventDefault();
3. About boundaries (dealing with drag ranges)
The first implementation code is as follows:
//X,y represents the left,top and limitObj values that are to be set by dragging the element.
//In the process of dragging, the object is sometimes not directly close to the edge
if ( x >= limitObj._left && x <= limitObj._right ) {
$target.css({ left: x + 'px' });
}
if ( y >= limitObj._top && y <= limitObj._bottom ) {
$target.css({ top: y + 'px' });
}
Further thinking: the reason why the above problem occurs is that the variable x may be less than limitobj._left or greater than limitobj._right.
So the code needs to do something like this:
if (x < limitObj._left) {
x = limitObj._left;
}
if (x > limitObj._right) {
x = limitObj._right;
}
if (y < limitObj._top) {
y = limitObj._top;
}
if (y > limitObj._bottom) {
y = limitObj._bottom;
}
$target.css({ left: x + 'px', top: y + 'px' });
The problem was finally solved, but cloudgamer came up with a better way to write it:
$target.css({
left: Math.max( Math.min(x, limitObj._right), limitObj._left) + 'px',
top: Math.max( Math.min(y, limitObj._bottom), limitObj._top) + 'px'
});
Complete program source code:
$.fn.extend({
/**
* Autor: Blog garden huazhi yjh 2014/02/21
*/
drag: function(options) {
var dragStart, dragMove, dragEnd,
$boundaryElem, limitObj;
function _initOptions() {
var noop = function(){}, defaultOptions;
defaultOptions = { //Default configuration item
boundaryElem: 'body' //Boundary container
};
options = $.extend( defaultOptions, options || {} );
$boundaryElem = $(options.boundaryElem);
dragStart = options.dragStart || noop,
dragMove = options.dragMove || noop,
dragEnd = options.dragEnd || noop;
}
function _drag(e) {
var clientX, clientY, offsetLeft, offsetTop,
$target = $(this), self = this;
limitObj = {
_left: 0,
_top: 0,
_right: ($boundaryElem.innerWidth() || $(window).width()) - $target.outerWidth(),
_bottom: ($boundaryElem.innerHeight() || $(window).height()) - $target.outerHeight()
};
//Record the position when the mouse is pressed and the relative position of the drag element
clientX = e.clientX;
clientY = e.clientY;
offsetLeft = this.offsetLeft;
offsetTop = this.offsetTop;
dragStart.apply(this, arguments);
$(document).bind('mousemove', moveHandle)
.bind('mouseup', upHandle);
//Mouse movement event handling
function moveHandle(e) {
var x = e.clientX - clientX + offsetLeft;
var y = e.clientY - clientY + offsetTop;
$target.css({
left: Math.max( Math.min(x, limitObj._right), limitObj._left) + 'px',
top: Math.max( Math.min(y, limitObj._bottom), limitObj._top) + 'px'
});
dragMove.apply(self, arguments);
//Block browser default behavior (when the mouse is dragging an image for a short distance, a disabled tip will appear, that is, the image cannot be dragged)
e.preventDefault();
}
//Mouse click event handling
function upHandle(e) {
$(document).unbind('mousemove', moveHandle);
dragEnd.apply(self, arguments);
}
}
_initOptions(); //Initializes the configuration object
$(this)
.css({ position: 'absolute' })
.each(function(){
$(this).bind('mousedown', function(e){
_drag.apply(this, [e]);
//Block field text from being selected for chrome firefox ie9
e.preventDefault();
// for firefox ie9 || less than ie9
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
});
});
return this;
}
});
Instance call:
//Call the instance
(function(){
$('.drag-elem').drag({
boundaryElem: '#boundary',
dragStart: function(){
$(this).html('<span> Ready to drag </span>').css({ zIndex: 2 }).siblings().css({ zIndex: 1 });
},
dragMove: function(){
var pos = $(this).position();
$(this).html('<span> Drag the (' + pos.left + ',' + pos.top + ')</span>' );
},
dragEnd : function(){
$(this).html('<span> Drag the end </span>');
}
});
}());