La posibilidad de arrastrar div sin jQuery UI

Como dice el titulo estoy tratando de hacer un div que se pueden arrastrar sin usar jQuery UI.

Sin embargo, estoy pegado con el código de abajo. Yo entiendo que voy a usar el ratón la posición relativa al div contenedor (en el que el div será arrastrado) y que tendré que los divs desplazamiento con respecto a esos valores.

No puedo averiguar cómo. Alguna pista para mí?

Este código no (por supuesto) de trabajo:

var X, Y;

$(this).mousedown(function() {
    $(this).offset({ 
        left: X, 
        top: Y
    });
});

$("#containerDiv").mousemove(function(event) {
    X = event.pageX;
    Y = event.pageY;
});
InformationsquelleAutor holyredbeard | 2011-12-19

11 Kommentare

  1. 74

    Aquí un realmente simple ejemplo que podría empezar:

    $(document).ready(function() {
        var $dragging = null;
    
        $(document.body).on("mousemove", function(e) {
            if ($dragging) {
                $dragging.offset({
                    top: e.pageY,
                    left: e.pageX
                });
            }
        });
    
    
        $(document.body).on("mousedown", "div", function (e) {
            $dragging = $(e.target);
        });
    
        $(document.body).on("mouseup", function (e) {
            $dragging = null;
        });
    });

    Ejemplo: http://jsfiddle.net/Jge9z/

    Entiendo que voy a usar el ratón la posición relativa al div contenedor (en el que el div será arrastrado) y que tendré que los divs desplazamiento con respecto a esos valores.

    No tan seguro. A mí me parece que en arrastrar y soltar que había siempre desea utilizar el desplazamiento de los elementos relativos al documento.

    Si te refieres a la que desea limitar la arrastra a un área en particular, es una cuestión más compleja (pero se puede hacer).

    • Funciona muy bien, pero el arrastre no funciona en dispositivos móviles. ¿Cómo puede este código serán modificados para que funcionen en el móvil así?
    • No estoy seguro. Quizás quieras buscar en toque eventos
    • Sugiero ampliar el código mediante la adición de mouseleave evento, como $("body").mouseleave(function(e) { $dragging = null; }) para atrapar a soltar presiona el botón de fuera de la ventana del navegador.
    • Hay ela Arrastrar y Soltar de la API de HTML5 que puede ser utilizado
    • su trabajo, pero un pequeño problema con posición fija y absoluta
  2. 42

    He aquí otro código actualizado:

    $(document).ready(function() {
        var $dragging = null;
        $('body').on("mousedown", "div", function(e) {
            $(this).attr('unselectable', 'on').addClass('draggable');
            var el_w = $('.draggable').outerWidth(),
                el_h = $('.draggable').outerHeight();
            $('body').on("mousemove", function(e) {
                if ($dragging) {
                    $dragging.offset({
                        top: e.pageY - el_h / 2,
                        left: e.pageX - el_w / 2
                    });
                }
            });
            $dragging = $(e.target);
        }).on("mouseup", ".draggable", function(e) {
            $dragging = null;
            $(this).removeAttr('unselectable').removeClass('draggable');
        });
    });​

    Demo: http://jsfiddle.net/tovic/Jge9z/31/


    He creado un sencillo plugin para este hilo.

    //Simple JQuery Draggable Plugin
    //https://plus.google.com/108949996304093815163/about
    //Usage: $(selector).drags();
    //Options:
    //handle            => your dragging handle.
    //                     If not defined, then the whole body of the
    //                     selected element will be draggable
    //cursor            => define your draggable element cursor type
    //draggableClass    => define the draggable class
    //activeHandleClass => define the active handle class
    //
    //Update: 26 February 2013
    //1. Move the `z-index` manipulation from the plugin to CSS declaration
    //2. Fix the laggy effect, because at the first time I made this plugin,
    //   I just use the `draggable` class that's added to the element
    //   when the element is clicked to select the current draggable element. (Sorry about my bad English!)
    //3. Move the `draggable` and `active-handle` class as a part of the plugin option
    //Next update?? NEVER!!! Should create a similar plugin that is not called `simple`!
    
    (function($) {
        $.fn.drags = function(opt) {
    
            opt = $.extend({
                handle: "",
                cursor: "move",
                draggableClass: "draggable",
                activeHandleClass: "active-handle"
            }, opt);
    
            var $selected = null;
            var $elements = (opt.handle === "") ? this : this.find(opt.handle);
    
            $elements.css('cursor', opt.cursor).on("mousedown", function(e) {
                if(opt.handle === "") {
                    $selected = $(this);
                    $selected.addClass(opt.draggableClass);
                } else {
                    $selected = $(this).parent();
                    $selected.addClass(opt.draggableClass).find(opt.handle).addClass(opt.activeHandleClass);
                }
                var drg_h = $selected.outerHeight(),
                    drg_w = $selected.outerWidth(),
                    pos_y = $selected.offset().top + drg_h - e.pageY,
                    pos_x = $selected.offset().left + drg_w - e.pageX;
                $(document).on("mousemove", function(e) {
                    $selected.offset({
                        top: e.pageY + pos_y - drg_h,
                        left: e.pageX + pos_x - drg_w
                    });
                }).on("mouseup", function() {
                    $(this).off("mousemove"); //Unbind events from document
                    if ($selected !== null) {
                        $selected.removeClass(opt.draggableClass);
                        $selected = null;
                    }
                });
                e.preventDefault(); //disable selection
            }).on("mouseup", function() {
                if(opt.handle === "") {
                    $selected.removeClass(opt.draggableClass);
                } else {
                    $selected.removeClass(opt.draggableClass)
                        .find(opt.handle).removeClass(opt.activeHandleClass);
                }
                $selected = null;
            });
    
            return this;
    
        };
    })(jQuery);

    Demo: http://tovic.github.io/dte-project/jquery-draggable/index.html

    • si usted utiliza este código $selected = $(this).parent(); línea 38:59su obligan a los desarrolladores a usar fijo de una estructura html. usted está asumiendo que el padre va a ser el completo structure a mover, pero si en lugar de asignar una clase como dicen class='draggableContainer', puedes hacer algo como $selected = $(this).closest(".draggableContainer"); ahora puede utilizar cualquier estructura de html y se va a trabajar. Pero en general genial $hit de trabajo realmente genial
    • También si usted está usando este simple plugin usted tiene que darse cuenta de si usted tiene handler events dentro de la que se pueden arrastrar contenedor se activan así, usted tiene que estar seguro de que lo que se ejecuta dentro de la función de controlador que provienen de los eventos previstos y no de la mouseup (arrastre) del evento. O pruebe a utilizar event.stopPropagation() en el plugin, yo lo intenté, pero no pude detenerlo. Yo no sabía dónde ponerlo.
    • Estoy usando este plugin, pero tiene un error importante cuando el elemento se establece la posibilidad de arrastrar ha <seleccione> elemento. El seleccionar simplemente deja de funcionar (al menos en Chrome). También no me gusta la UX problema, que cuando el usuario «, se inicia el arrastre» en la parte superior de una entrada de botón o elemento de arrastre se ejecuta y, a continuación, hace clic con el ratón se ejecuta. Yo prefiero omitir algunos elementos a partir del comienzo del evento de arrastre así que me bifurcada este plugin para tener una opción de cancelación, similar a jquery-ui: github.com/pjfsilva/dte-project/blob/master/jquery-draggable/… Ahora, <seleccione> obras y la experiencia de usuario se ha mejorado la
  3. 14

    Aquí está mi aportación:

    http://jsfiddle.net/g6m5t8co/1/

    <!doctype html>
    <html>
        <head>
            <style>
                #container {
                    position:absolute;
                    background-color: blue;
                    }
                #elem{
                    position: absolute;
                    background-color: green;
                    -webkit-user-select: none;
                    -moz-user-select: none;
                    -o-user-select: none;
                    -ms-user-select: none;
                    -khtml-user-select: none;     
                    user-select: none;
                }
            </style>
            <script>
                var mydragg = function(){
                    return {
                        move : function(divid,xpos,ypos){
                            divid.style.left = xpos + 'px';
                            divid.style.top = ypos + 'px';
                        },
                        startMoving : function(divid,container,evt){
                            evt = evt || window.event;
                            var posX = evt.clientX,
                                posY = evt.clientY,
                            divTop = divid.style.top,
                            divLeft = divid.style.left,
                            eWi = parseInt(divid.style.width),
                            eHe = parseInt(divid.style.height),
                            cWi = parseInt(document.getElementById(container).style.width),
                            cHe = parseInt(document.getElementById(container).style.height);
                            document.getElementById(container).style.cursor='move';
                            divTop = divTop.replace('px','');
                            divLeft = divLeft.replace('px','');
                            var diffX = posX - divLeft,
                                diffY = posY - divTop;
                            document.onmousemove = function(evt){
                                evt = evt || window.event;
                                var posX = evt.clientX,
                                    posY = evt.clientY,
                                    aX = posX - diffX,
                                    aY = posY - diffY;
                                    if (aX < 0) aX = 0;
                                    if (aY < 0) aY = 0;
                                    if (aX + eWi > cWi) aX = cWi - eWi;
                                    if (aY + eHe > cHe) aY = cHe -eHe;
                                mydragg.move(divid,aX,aY);
                            }
                        },
                        stopMoving : function(container){
                            var a = document.createElement('script');
                            document.getElementById(container).style.cursor='default';
                            document.onmousemove = function(){}
                        },
                    }
                }();
    
            </script>
        </head>
        <body>
            <div id='container' style="width: 600px;height: 400px;top:50px;left:50px;">     
                <div id="elem" onmousedown='mydragg.startMoving(this,"container",event);' onmouseup='mydragg.stopMoving("container");' style="width: 200px;height: 100px;">
                    <div style='width:100%;height:100%;padding:10px'>
                    <select id=test>
                        <option value=1>first
                        <option value=2>second
                    </select>
                    <INPUT TYPE=text value="123">
                    </div>
                </div>
            </div>  
        </body>
    </html>
    • Buen Trabajo… Sólo con javascript agradable +1
    • Eso es excelente, el único problema con esto es que si usted tiene un elemento con posición absoluta, en mousedown se piensa es en la parte superior & a la izquierda 0 – existe una forma fácil para mantener su posición actual en primer lugar antes de arrastrar?
    • Llame getBoundingClientRect() para #elem, y luego utilizar el rect del top/left a init divTop/divLeft! Bono: usted no necesitará ninguna de presets, o style de ningún tipo, a continuación,.
  4. 8

    he aquí otra manera de hacer que la posibilidad de arrastrar un objeto que está centrada en el haga clic en

    http://jsfiddle.net/pixelass/fDcZS/

    function endMove() {
        $(this).removeClass('movable');
    }
    
    function startMove() {
        $('.movable').on('mousemove', function(event) {
            var thisX = event.pageX - $(this).width() / 2,
                thisY = event.pageY - $(this).height() / 2;
    
            $('.movable').offset({
                left: thisX,
                top: thisY
            });
        });
    }
    $(document).ready(function() {
        $("#containerDiv").on('mousedown', function() {
            $(this).addClass('movable');
            startMove();
        }).on('mouseup', function() {
            $(this).removeClass('movable');
            endMove();
        });
    
    });

    CSS

    #containerDiv {
        background:#333;
        position:absolute;
        width:200px;
        height:100px;
    }
  5. 7

    No Jquery Solución Básica

    Los más básicos que se pueden arrastrar código sería el siguiente :

    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
    
    }

    y, a continuación, el uso (no jquery) :

    document.querySelector('.target').drag();

    o en jquery :

    $('.target')[0].drag();

    Aviso : el elemento arrastrado debe tener un position:absolute o position:fixed aplicado para la izquierda,arriba a la circulación para trabajar…

    la codepen a continuación tiene algunos de los más «avanzados» características : dragStart, dragStop devoluciones de llamada, las clases css anexando para quitar la selección de texto de otros elementos mientras se arrastra, y una disminución de la función también…

    comprobación de los siguientes codepen :

    http://codepen.io/anon/pen/VPPaEK

    es básicamente la configuración de un «mousedown» evento en el elemento que necesita ser arrastrado y, a continuación, enlazar y desenlazar el documento mousemove para controlar el movimiento.

    La Posibilidad De Arrastrar La Manija

    con el fin de establecer una posibilidad de arrastrar la manija para el elemento

    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
    
    }

    El código anterior se utiliza así :

    var setup = {
       handle : document.querySelector('.handle')
    };
    
    document.querySelector('.box').drag(setup);

    Añadir CSS para eliminar texto seleccionable

    El problema ahora, es que cuando se arrastra, el texto dentro del elemento draggable es molesto ser seleccionado con el no uso…

    Esta es la razón por la que hemos añadido el draggable y dragging clases para el elemento. que anular este comportamiento no deseado, y también añadir un mover el cursor, para mostrar que este elemento es la posibilidad de arrastrar

    .draggable{
        cursor: move;
        position: fixed;
    }
    
    .draggable.dragging{
        user-select: none;
    }

    Añadir Eventos

    Así que ahora que tenemos nuestro elemento draggable, a veces tenemos que llamar a varios eventos.

    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

    Cada uno se va a pasar de la original del evento de ratón para el controlador específico

    Finalmente, esto es lo que tenemos…

    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
    
    }

    Y utilizar este :

    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);

    nota que e.target es una referencia de nuevo a nuestro elemento draggable

    • Fantástica la limpieza! El pensamiento acerca de la creación de otro MODO cuenta solo para votar una vez más. 😉
  6. 6

    Arrastrando como jQueryUI: JsFiddle

    Puede arrastrar el elemento a partir de cualquier punto sin raro centrado.

    $(document).ready(function() {
    
            var $body = $('body');
            var $target = null;
            var isDraggEnabled = false;
    
            $body.on("mousedown", "div", function(e) {
    
                $this = $(this);
                isDraggEnabled = $this.data("draggable");
    
                if (isDraggEnabled) {
                    if(e.offsetX==undefined){
                        x = e.pageX-$(this).offset().left;
                        y = e.pageY-$(this).offset().top;
                    }else{
                        x = e.offsetX;
                        y = e.offsetY;
                    };
    
                    $this.addClass('draggable');
                    $body.addClass('noselect');
                    $target = $(e.target);
                };
    
            });
    
             $body.on("mouseup", function(e) {
                $target = null;
                $body.find(".draggable").removeClass('draggable');
                $body.removeClass('noselect');
            });
    
             $body.on("mousemove", function(e) {
                if ($target) {
                    $target.offset({
                        top: e.pageY  - y,
                        left: e.pageX - x
                    });
                };     
             });
    
        });
    • Interesante resultado. Si sumamos esto a un div, puede arrastrar todos sus elementos hijos de ella, pero si usted haga clic y arrastre en el real de la div y no a un niño, este se mueve todo.
  7. 4

    Esta es la mía.
    http://jsfiddle.net/pd1vojsL/

    3 se pueden arrastrar los botones de un div, arrastrando limitados por la div.

    <div id="parent" class="parent">
        <button id="button1" class="button">Drag me</button>
        <button id="button2" class="button">Drag me</button>
        <button id="button3" class="button">Drag me</button>
    </div>
    <div id="log1"></div>
    <div id="log2"></div>

    Requiere de JQuery (sólo):

    $(function() {
        $('.button').mousedown(function(e) {
            if(e.which===1) {
                var button = $(this);
                var parent_height = button.parent().innerHeight();
                var top = parseInt(button.css('top')); //current top position
                var original_ypos = button.css('top','').position().top; //original ypos (without top)
                button.css({top:top+'px'}); //restore top pos
                var drag_min_ypos = 0-original_ypos;
                var drag_max_ypos = parent_height-original_ypos-button.outerHeight();
                var drag_start_ypos = e.clientY;
                $('#log1').text('mousedown top: '+top+', original_ypos: '+original_ypos);
                $(window).on('mousemove',function(e) {
                    //Drag started
                    button.addClass('drag');
                    var new_top = top+(e.clientY-drag_start_ypos);
                    button.css({top:new_top+'px'});
                    if(new_top<drag_min_ypos) { button.css({top:drag_min_ypos+'px'}); }
                    if(new_top>drag_max_ypos) { button.css({top:drag_max_ypos+'px'}); }
                    $('#log2').text('mousemove min: '+drag_min_ypos+', max: '+drag_max_ypos+', new_top: '+new_top);
                    //Outdated code below (reason: drag contrained too early)
                    /*if(new_top>=drag_min_ypos&&new_top<=drag_max_ypos) {
                        button.css({top:new_top+'px'});
                    }*/
                });
                $(window).on('mouseup',function(e) {
                     if(e.which===1) {
                        //Drag finished
                        $('.button').removeClass('drag');
                        $(window).off('mouseup mousemove');
                        $('#log1').text('mouseup');
                        $('#log2').text('');
                     }
                });
            }
        });
    });
    • Muy Útil para mí.realmente salvar mi montón de horas.
  8. 2

    Lo que he visto de arriba es complicar…..

    Aquí es algo de código, que se puede referir.

    $("#box").on({
                    mousedown:function(e)
                    {
                      dragging = true;
                      dragX = e.clientX - $(this).position().left;
                      //To calculate the distance between the cursor pointer and box 
                      dragY = e.clientY - $(this).position().top;
                    },
                    mouseup:function(){dragging = false;},
                      //If not set this on/off,the move will continue forever
                    mousemove:function(e)
                    {
                      if(dragging)
                      $(this).offset({top:e.clientY-dragY,left:e.clientX-dragX});
    
                    }
                })

    arrastrando,dragX,dragY puede colocar como la variable global.

    Es un simple espectáculo sobre este tema,pero hay algunos errores acerca de este método.

    Si es su necesidad ahora,aquí está el Ejemplo aquí.

  9. 0
    $(document).ready(function() {
        var $startAt = null;
    
        $(document.body).live("mousemove", function(e) {
            if ($startAt) {
                $("#someDiv").offset({
                    top: e.pageY,
                    left: $("#someDiv").position().left-$startAt+e.pageX
                });
                $startAt = e.pageX; 
            }
        });
    
        $("#someDiv").live("mousedown", function (e) {$startAt = e.pageX;});
        $(document.body).live("mouseup", function (e) {$startAt = null;});
    });
  10. -1

    Aquí está mi versión simple.

    La función de la posibilidad de arrastrar toma un objeto jQuery como argumento.

    
    /**
     * @param {jQuery} elem
     */
    function draggable(elem){
    
        elem.mousedown(function(evt){
            var x = parseInt(this.style.left || 0) - evt.pageX;
            var y = parseInt(this.style.top || 0) - evt.pageY;
    
            elem.mousemove(function(evt){
                elem.css('left', x + evt.pageX);
                elem.css('top', y + evt.pageY);
            });
        });
    
        elem.mouseup(off);
        elem.mouseleave(off);
    
        function off(){
            elem.off("mousemove");
        }
    }
    
  11. -2

    Aquí es una aplicación sin necesidad de utilizar jQuery en todo

    http://thezillion.wordpress.com/2012/09/27/javascript-draggable-2-no-jquery

    Incrustar el archivo JS (http://zillionhost.xtreemhost.com/tzdragg/tzdragg.js) en su código HTML, y ponemos el siguiente código

    <script>
    win.onload = function(){
     tzdragg.drag('elem1, elem2, ..... elemn');
     //^ IDs of the draggable elements separated by a comma.
    }
    </script>

    Y el código también es fácil de aprender.

    http://thezillion.wordpress.com/2012/08/29/javascript-draggable-no-jquery

    • Por favor, tenga en cuenta que se trata de requiere que revelar cada vez que enlace a su propio sitio web/del proyecto.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea