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>');            
        }
    });
}());


Related articles: