Comme le titre l'indique, j'essaie de rendre une div déplaçable sans utiliser l'interface utilisateur de jQuery.
Cependant, je suis coincé avec le code ci-dessous. Je comprends que je vais utiliser la position de la souris par rapport au conteneur div (dans lequel le div doit être déplacé) et que je définirai le décalage des div par rapport à ces valeurs.
Je n'arrive pas à comprendre comment. Des indices pour moi?
Ce code ne fonctionne pas (bien sûr):
var X, Y;
$(this).mousedown(function() {
$(this).offset({
left: X,
top: Y
});
});
$("#containerDiv").mousemove(function(event) {
X = event.pageX;
Y = event.pageY;
});
Voici un exemple simple vraiment qui pourrait vous aider à démarrer:
$(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;
});
});
Exemple: http://jsfiddle.net/Jge9z/
Je comprends que je vais utiliser la position de la souris par rapport au conteneur div (dans lequel le div doit être déplacé) et que je définirai le décalage des div par rapport à ces valeurs.
Pas si sûr de ça. Il me semble qu'en glisser-déposer, vous voudriez toujours utiliser le décalage des éléments par rapport au document.
Si vous voulez dire que vous voulez limiter le glissement vers une zone particulière, c'est un problème plus compliqué (mais toujours réalisable).
Voici un autre code mis à jour:
$(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');
});
});
Démo: http://jsfiddle.net/tovic/Jge9z/31/
J'ai créé un plugin simple à ce fil.
// 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);
Démo: http://tovic.github.io/dte-project/jquery-draggable/index.html
Voici ma contribution:
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>
voici une autre façon de faire un objet glissable qui est centré au 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;
}
Le code glissable le plus élémentaire serait:
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
}
et ensuite usage (non-jquery):
document.querySelector('.target').drag();
ou en jquery:
$('.target')[0].drag();
Remarque: l'élément déplacé doit avoir un position:absolute
ou position:fixed
lui a été appliqué pour le mouvement de gauche, en haut pour fonctionner ...
le code ci-dessous présente quelques fonctionnalités plus "avancées": dragStart, rappels dragStop, ajout de classes css pour supprimer la sélection de texte d'autres éléments lors du glissement, et une fonctionnalité de suppression également ...
commander le code suivant:
http://codepen.io/anon/pen/VPPaEK
il définit essentiellement un événement 'mousedown' sur l'élément à déplacer, puis lie et dissocie le document mousem pour supprimer le mouvement.
afin de définir un handle glissable pour l'élément
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
}
Le code ci-dessus est utilisé comme suit:
var setup = {
handle : document.querySelector('.handle')
};
document.querySelector('.box').drag(setup);
Le problème maintenant, c’est que lors du glissement, le texte dans l’élément glissable est sélectionné de manière ennuyeuse sans aucune utilisation ...
C'est pourquoi nous avons ajouté les classes draggable
et dragging
à l'élément. ce qui annulera ce comportement indésirable et ajoutera également un curseur de déplacement pour indiquer que cet élément est déplaçable
.draggable{
cursor: move;
position: fixed;
}
.draggable.dragging{
user-select: none;
}
Alors maintenant que nous avons notre élément déplaçable, nous avons parfois besoin d'appeler divers événements.
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
Chacun passera l'événement de souris d'origine au gestionnaire spécifique
Enfin, c'est ce que nous obtenons ...
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
}
Et pour utiliser ceci:
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);
notez que e.target
est une référence à notre élément déplaçable
Faire glisser comme jQueryUI: JsFiddle
Vous pouvez faire glisser l'élément de n'importe quel point sans un centrage étrange.
$(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
});
};
});
});
C'est à moi. http://jsfiddle.net/pd1vojsL/
3 boutons pouvant être déplacés dans un div, le glissement étant contraint par 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>
Requiert JQuery (uniquement):
$(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('');
}
});
}
});
});
Ce que j'ai vu ci-dessus est compliqué .....
Voici un code peut se référer.
$("#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});
}
})
dragging, dragX, dragY peut être placé en tant que variable globale.
C'est une émission simple sur ce problème, mais il y a un problème avec cette méthode.
Si c'est votre besoin maintenant, voici le Exemple ici.
$(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;});
});