Div arrastrable sin interfaz de usuario jQuery
Como dice el título, estoy tratando de hacer un div arrastrable sin usar jQuery UI.
Sin embargo, estoy atascado con el código a continuación. Entiendo que usaré la posición del ratón relativa al div del contenedor (en el que se arrastrará el div) y que estableceré el desplazamiento divs relativo a esos valores.
Simplemente no puedo averiguar cómo. Alguna pista para mí?
Este código no funciona (por supuesto):
var X, Y;
$(this).mousedown(function() {
$(this).offset({
left: X,
top: Y
});
});
$("#containerDiv").mousemove(function(event) {
X = event.pageX;
Y = event.pageY;
});
11 answers
Aquí hay un realmente ejemplo simple que podría ayudarte a comenzar:
$(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 usaré la posición del ratón relativa al div del contenedor (en el que se arrastrará el div) y que estableceré el desplazamiento divs relativo a esos valores.
No estoy tan seguro de eso. Me parece que en arrastrar y soltar siempre quieres usar el desplazamiento de los elementos relativos al documento.
Si quieres limitar el arrastre a un área en particular, ese es un problema más complicado (pero aún factible).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-20 00:14:11
Aquí hay 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 plugin simple 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-19 13:20:51
Aquí está mi contribució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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-19 11:01:12
Aquí hay otra forma de hacer un objeto arrastrable que se centra en el clic
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;
}
Arrastrando como jQueryUI: JsFiddle
Puede arrastrar el elemento desde cualquier punto sin un centrado extraño.
$(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
});
};
});
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-26 08:52:02
No hay solución Jquery
El código arrastrable más básico sería:
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));
}
Y luego uso (no-jquery) :
document.querySelector('.target').drag();
O en jquery:
$('.target')[0].drag();
Aviso : el elemento arrastrado debe tener una posición:absoluta o posición:fija aplicada para que funcione el movimiento superior izquierdo...
El codepen a continuación tiene algunas características más "avanzadas": dragStart, dragStop callbacks, clases CSS que se añaden para eliminar la selección de texto de otros elementos mientras se arrastra, y una gota característica también...
Compruebe el siguiente código:
Http://codepen.io/anon/pen/VPPaEK
Básicamente es establecer un evento 'mousedown' en el elemento que necesita ser arrastrado, y luego enlazar y desengañar el mousemove del documento para manejar el movimiento.
Mango arrastrable
Para establecer un identificador arrastrable 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);
}.bind(this));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-18 09:05:01
Esto es mío. http://jsfiddle.net/pd1vojsL /
3 botones arrastrables en un div, arrastrando restringido por 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 jQuery (solo):
$(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('');
}
});
}
});
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-27 01:24:51
Lo que vi arriba es complicado.....
Aquí hay un código al que se puede hacer referencia.
$("#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});
}
})
Arrastrar,dragX,dragY puede colocar como la variable global.
Es un espectáculo simple sobre este problema,pero hay algún error sobre este método.
Si es su necesidad ahora,aquí está el Ejemplo aquí.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-21 11:30:44
$(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;});
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-06 07:38:36
Aquí está mi versión simple.
La función draggable 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");
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-04 12:19:34
Aquí hay una implementación sin usar jQuery en absoluto -
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 poner 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-28 05:10:13