Problème de drag&drop

hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011 - 21 mars 2011 à 13:31
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011 - 24 mars 2011 à 14:41
Bonjour à tous,

je rencontre un problème lié au drag&drop :

j'ai sur ma page plusieurs DIV (contenant des photos) dont la fonction drag&drop est appelée par javascript.
Jusque là tout va bien...
Or, lorsque je place un lien (href) sur l'image contenue dans une DIV,
la fonction drag&drop ne fonctionne plus.

Je cherche donc une solution qui me permette par exemple d'atteindre mon lien par double-click pour que la fonction drag&drop soit conservée.

je laisse mon code au cas où :

mon javascript:

function positionne(p_id, p_posX, p_pos_Y){
document.getElementById(p_id).style.left = p_posX;
document.getElementById(p_id).style.top = p_pos_Y;
}
function getPositionCurseur(e){
//ie
if(document.all){
curX = event.clientX;
curY = event.clientY;
}

//netscape 4
if(document.layers){
curX = e.pageX;
curY = e.pageY;
}

//mozilla
if(document.getElementById){
curX = e.clientX;
curY = e.clientY;
}
}

function beginDrag(p_obj,e){
isDragging = true;
objectToDrag = p_obj;
getPositionCurseur(e);
ecartX = curX - parseInt(objectToDrag.style.left);
ecartY = curY - parseInt(objectToDrag.style.top);
}

function drag(e){
var newPosX;
var newPosY;
if(isDragging == true){

getPositionCurseur(e);
newPosX = curX - ecartX;
newPosY = curY - ecartY;

objectToDrag.style.left = newPosX + 'px';
objectToDrag.style.top = newPosY + 'px';

}
}
function endDrag(){
isDragging = false;
}


et le body :




[monlien 

]


<script type="text/javascript">
positionne('img', '290px', '84px');
isDragging = false;
</script>



PS: vous aurez compris que je ne suis pas un foudre de guerre en programmation, je suis photographe de formation ;)

24 réponses

@karamel Messages postés 1855 Date d'inscription vendredi 9 mai 2008 Statut Modérateur Dernière intervention 18 avril 2024 153
21 mars 2011 à 13:57
il faut utiliser l'evenement ondblclick qui fera appel a une fonction qui fera un location.href









<script type="text/javascript">
positionne('img', '290px', '84px');
isDragging = false;
</script>




function mafonction(lelien){
document.location.href=lelien

}

0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
21 mars 2011 à 14:33
Il serait plus efficace de détecter la cible lors du onmousedown c'est-à-dire dans beginDrag pour ne éviter le drag&drop s'il s'agit d'un lien.

Le code suivant devrait fonctionner (à tester)
function beginDrag(p_obj,e){
   var t=e.target?e.target:e.srcElement;
// Pour les clics sur un noeud texte de Mozilla et autres... 
   while (t.nodeType!=1) t=t.parentNode;
   if (t.tagName.toLowerCase()=='a') return true;
   isDragging = true;
   //... la suite
}
// avec peut-être aussi un return true ici
function endDrag(){
   isDragging = false;
   return true;
}
L'important pour ne pas déactiver les liens, c'est de ne pas gèner le déclenchement du clic après le mousedown et mouseup. D'où les return true ...
0
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011
21 mars 2011 à 14:45
Merci,
mais j'ai peut-être été un peu trop synthétique; en réalité le lien de l'image appelle un lightbox en javascript,

j'ai donc ce code html :

<head>
<script type="text/javascript" src="lightbox.js"></script>
</head>



[image2.jpg 

]


<script type="text/javascript">
positionne('img', '290px', '84px');
isDragging = false;
</script>



Et je ne suis pas arrivé à placer correctement le code afin que la lightbox puisse être active :(
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
21 mars 2011 à 16:52
Cela ne devrait pas être un obstacle...

En relisant, je m'aperçois que le lien porte sur l'image. Il faudrait donc prévoir encore un t=t.parentNode pour retrouver le lien. Le remède pourrait consister à supprimer le while (t.nodeType!=1) (il n'y a plus de risque avec le texte du lien) en gardant seulement le t=t.parentNode.

Si un alert(t.tagName) avant le if donne IMG, c'est la solution.

Autre question reste-t-il des marges autour de l'image pour pouvoir déplacer le container ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011
21 mars 2011 à 17:28
@ 007Julien > non il ne reste pas de marges, la div est de la taille de l'image, sans bordures...
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
21 mars 2011 à 17:32
Alors, il n'y a pas de solution d'autant plus que le double-clic (qui est d'abord un clic) ne fonctionnera pas plus que le clic !
0
@karamel Messages postés 1855 Date d'inscription vendredi 9 mai 2008 Statut Modérateur Dernière intervention 18 avril 2024 153
21 mars 2011 à 18:18
je pense que c'est faisable le doubleclick car j'avait deja fait un truc qui deplacer un element et on pouvait faire une autre action en doublecliquant

le probleme je le voit plutot dans la lightbox ou il faudrait detecter le moment ou l'assignation du click se fait afin de le remplacer par un ondblclick
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
22 mars 2011 à 01:07
Bon courage... Votre formation devrait après tout vous permettre de ne pas être arrété par des clics !
0
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011
22 mars 2011 à 08:14
haha oui en théorie...

voici le code lightbox :

var loadingImage = 'loading.gif';		
var closeButton = 'close.gif';		

function getPageScroll(){

var yScroll;

if (self.pageYOffset) {
yScroll = self.pageYOffset;
} else if (document.documentElement && document.documentElement.scrollTop){ // Explorer 6 Strict
yScroll = document.documentElement.scrollTop;
} else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
}

arrayPageScroll = new Array('',yScroll) 
return arrayPageScroll;
}
function getPageSize(){

var xScroll, yScroll;

if (window.innerHeight && window.scrollMaxY) {	
xScroll = document.body.scrollWidth;
yScroll = window.innerHeight + window.scrollMaxY;
} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
xScroll = document.body.scrollWidth;
yScroll = document.body.scrollHeight;
} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
xScroll = document.body.offsetWidth;
yScroll = document.body.offsetHeight;
}
var windowWidth, windowHeight;
if (self.innerHeight) {	// all except Explorer
windowWidth = self.innerWidth;
windowHeight = self.innerHeight;
} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
windowWidth = document.documentElement.clientWidth;
windowHeight = document.documentElement.clientHeight;
} else if (document.body) { // other Explorers
windowWidth = document.body.clientWidth;
windowHeight = document.body.clientHeight;
}	
if(yScroll < windowHeight){
pageHeight = windowHeight;
} else { 
pageHeight = yScroll;
}
if(xScroll < windowWidth){	
pageWidth = windowWidth;
} else {
pageWidth = xScroll;
}

arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
return arrayPageSize;
}
function pause(numberMillis) {
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true) {
now = new Date();
if (now.getTime() > exitTime)
return;
}
}
function getKey(e){
if (e == null) { // ie
keycode = event.keyCode;
} else { // mozilla
keycode = e.which;
}
key = String.fromCharCode(keycode).toLowerCase();

if(key == 'x'){ hideLightbox(); }
}
function listenKey () {	document.onkeypress = getKey; }

function showLightbox(objLink)
{
// prep objects
var objOverlay = document.getElementById('overlay');
var objLightbox = document.getElementById('lightbox');
var objCaption = document.getElementById('lightboxCaption');
var objImage = document.getElementById('lightboxImage');
var objLoadingImage = document.getElementById('loadingImage');
var objLightboxDetails = document.getElementById('lightboxDetails');

var arrayPageSize = getPageSize();
var arrayPageScroll = getPageScroll();

if (objLoadingImage) {
objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - objLoadingImage.height) / 2) + 'px');
objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2) + 'px');
objLoadingImage.style.display = 'block';
}
objOverlay.style.height = (arrayPageSize[1] + 'px');
objOverlay.style.display = 'block';

imgPreload = new Image();

imgPreload.onload=function(){
objImage.src = objLink.href;

var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - imgPreload.height) / 2);
var lightboxLeft = ((arrayPageSize[0] - 20 - imgPreload.width) / 2);

objLightbox.style.top = (lightboxTop < 0) ? "0px" : lightboxTop + "px";
objLightbox.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";


objLightboxDetails.style.width = imgPreload.width + 'px';

if(objLink.getAttribute('title')){
objCaption.style.display = 'block';
//objCaption.style.width = imgPreload.width + 'px';
objCaption.innerHTML = objLink.getAttribute('title');
} else {
objCaption.style.display = 'none';
}

if (navigator.appVersion.indexOf("MSIE")!=-1){
pause(250);
} 

if (objLoadingImage) {	objLoadingImage.style.display = 'none'; }

selects = document.getElementsByTagName("select");
        for (i = 0; i != selects.length; i++) {
                selects[i].style.visibility = "hidden";
        }	
objLightbox.style.display = 'block';

arrayPageSize = getPageSize();
objOverlay.style.height = (arrayPageSize[1] + 'px');

listenKey();

return false;
}
imgPreload.src = objLink.href;	
}
function hideLightbox()
{
// get objects
objOverlay = document.getElementById('overlay');
objLightbox = document.getElementById('lightbox');

objOverlay.style.display = 'none';
objLightbox.style.display = 'none';

selects = document.getElementsByTagName("select");
    for (i = 0; i != selects.length; i++) {
selects[i].style.visibility = "visible";
}
document.onkeypress = '';
}
function initLightbox()
{

if (!document.getElementsByTagName){ return; }
var anchors = document.getElementsByTagName("a");

for (var i=0; i<anchors.length; i++){
var anchor = anchors[i];

if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){
anchor.onclick = function () {showLightbox(this); return false;}
}
}
var objBody = document.getElementsByTagName("body").item(0);

var objOverlay = document.createElement("div");
objOverlay.setAttribute('id','overlay');
objOverlay.onclick = function () {hideLightbox(); return false;}
objOverlay.style.display = 'none';
objOverlay.style.position = 'absolute';
objOverlay.style.top = '0';
objOverlay.style.left = '0';
objOverlay.style.zIndex = '90';
 	objOverlay.style.width = '100%';
objBody.insertBefore(objOverlay, objBody.firstChild);

var arrayPageSize = getPageSize();
var arrayPageScroll = getPageScroll();

var imgPreloader = new Image();

imgPreloader.onload=function(){

var objLoadingImageLink = document.createElement("a");
objLoadingImageLink.setAttribute('href','#');
objOverlay.appendChild(objLoadingImageLink);

var objLoadingImage = document.createElement("img");
objLoadingImage.src = loadingImage;
objLoadingImage.setAttribute('id','loadingImage');
objLoadingImage.style.position = 'absolute';
objLoadingImage.style.zIndex = '150';
objLoadingImageLink.appendChild(objLoadingImage);

imgPreloader.onload=function(){};

return false;
}

imgPreloader.src = loadingImage;

var objLightbox = document.createElement("div");
objLightbox.setAttribute('id','lightbox');
objLightbox.style.display = 'none';
objLightbox.style.position = 'absolute';
objLightbox.style.zIndex = '100';	
objBody.insertBefore(objLightbox, objOverlay.nextSibling);

var objLink = document.createElement("a");
objLink.setAttribute('href','#');
objLink.setAttribute('title','Click to close or press x key');
objLightbox.appendChild(objLink);

var imgPreloadCloseButton = new Image();
 
imgPreloadCloseButton.onload=function(){

var objCloseButton = document.createElement("img");
objCloseButton.src = closeButton;
objCloseButton.setAttribute('id','closeButton');
objCloseButton.style.position = 'absolute';
objCloseButton.style.zIndex = '200';
objLink.appendChild(objCloseButton);

return false;
}
imgPreloadCloseButton.src = closeButton;

var objImage = document.createElement("img");
objImage.setAttribute('id','lightboxImage');
objLink.appendChild(objImage);

var objLightboxDetails = document.createElement("div");
objLightboxDetails.setAttribute('id','lightboxDetails');
objLightbox.appendChild(objLightboxDetails);

var objCaption = document.createElement("div");
objCaption.setAttribute('id','lightboxCaption');
objCaption.style.display = 'none';
objLightboxDetails.appendChild(objCaption);

}
function addLoadEvent(func)
{	
var oldonload = window.onload;
if (typeof window.onload != 'function'){
    	window.onload = func;
} else {
window.onload = function(){
oldonload();
func();
}
}
}
addLoadEvent(initLightbox);


j'ai essayé de remplacer cette ligne
if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){
anchor.onclick = function () {showLightbox(this); return false;}

par
if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){
anchor.ondbclick = function () {showLightbox(this); return false;}

mais la lightbox ne marche plus.

En regardant sur le net, je suis tombé sur ce site http://www.1-2-3-info.se/
c'est à peu près l'effet que je souhaiterais avoir (en plus simple bien entendu)
0
@karamel Messages postés 1855 Date d'inscription vendredi 9 mai 2008 Statut Modérateur Dernière intervention 18 avril 2024 153
22 mars 2011 à 10:25
c'est a cette endroit que l'evenement est ajouter

if (!document.getElementsByTagName){ return; }
var anchors = document.getElementsByTagName("a");

for (var i=0; i<anchors.length; i++){
var anchor = anchors[i];

if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){
anchor.onclick = function () {showLightbox(this); return false;}
}
}


pluu precisement sur cette ligne

anchor.onclick = function () {showLightbox(this); return 


a remplacer par


anchor.ondblclick = function () {showLightbox(this); return 
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
22 mars 2011 à 10:49
Vous devriez effectivemment vous en sortir en activant la lightbox avec un double-clic, mais n'imitez surtout pas le site donné en exemple, la page est impossible à charger donne des erreurs sur IE et finit par planter le navigateur...
0
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011
22 mars 2011 à 11:11
Noté !
J'ai remplacé la ligne indiqué sur le javascript de la lightbox en remplaçant par le double click,
mais la ni le drag ni la lightbox ne fonctionnent (le lien s'ouvre sur une autre page,

je penses que c'est dans mon body qu'il y a un problème : je ne dois pas à déclarer la fonction onmouseup correctement:

voici ce que j'ai :



[image2.jpg 

]


<script type="text/javascript">
positionne('img', '290px', '84px');
isDragging = false;
</script>



dois-je laiser le code du drag&drop tel-quel ?

function positionne(p_id, p_posX, p_pos_Y){
document.getElementById(p_id).style.left = p_posX;
document.getElementById(p_id).style.top = p_pos_Y;
}
function getPositionCurseur(e){
//ie
if(document.all){
curX = event.clientX;
curY = event.clientY;
}

//netscape 4
if(document.layers){
curX = e.pageX;
curY = e.pageY;
}

//mozilla
if(document.getElementById){
curX = e.clientX;
curY = e.clientY;
}
}
function beginDrag(p_obj,e){
   var t=e.target?e.target:e.srcElement;
// Pour les clics sur un noeud texte de Mozilla et autres... 
   while (t.nodeType!=1) t=t.parentNode;
   if (t.tagName.toLowerCase()=='a') return true;
   isDragging = true;
objectToDrag = p_obj;
getPositionCurseur(e);
ecartX = curX - parseInt(objectToDrag.style.left);
ecartY = curY - parseInt(objectToDrag.style.top);
}

function drag(e){
var newPosX;
var newPosY;
if(isDragging == true){

getPositionCurseur(e);
newPosX = curX - ecartX;
newPosY = curY - ecartY;

objectToDrag.style.left = newPosX + 'px';
objectToDrag.style.top = newPosY + 'px';

}
}
function endDrag(){
isDragging = false;
return true;
}
0
@karamel Messages postés 1855 Date d'inscription vendredi 9 mai 2008 Statut Modérateur Dernière intervention 18 avril 2024 153
22 mars 2011 à 11:46
pour le probleme je pencherait plutot sur cette ligne




il faudrait hiniber le lien car ce qu'il ce passe c'est que c'est considere comme un lien vers l'image image2.jpg donc on est rediriger vers l'image
0
@karamel Messages postés 1855 Date d'inscription vendredi 9 mai 2008 Statut Modérateur Dernière intervention 18 avril 2024 153
22 mars 2011 à 12:00
mais normalement le return false doit normalement iniber lelien


anchor.onclick = function () {showLightbox(this); return false;}
0
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011
22 mars 2011 à 12:17
oui, il doit y avoir un soucis à ce niveau :
anchor.ondblclick = function () {showLightbox(this); return false; 

car le double-clic n'est pas pris en compte et empêche le script de fonctionner...
0
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011
22 mars 2011 à 12:25
Ou bien est-ce que l'on ne pourrait pas faire en sorte que:

sur le lien (div), si la souris (ou le div parent) n'a pas bougé entre le mousedown et mouseup => déclencher le lien, sinon => drop.
La fonction endDrag() peut par exemple renvoyer vrai si la souris a bougé sinon faux.

Cependant, je ne sais pas si c'est possible de gérer les lightbox autrement qu'avec des liens , en Javascript ?
0
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011
22 mars 2011 à 12:28
Mais je crains que le lien se déclenche de toute façon sur le onmousedown :(
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
22 mars 2011 à 15:18
Le lien se déclenche tout simplement sur le click qui précède le double-clic. La solution consiste donc à désactiver le clic avant de transformer le click en double-clic. Ce qui donne dans la fonction initLightbox

for (var i=0; i[98.jpg ]


<script type="text/javascript">
positionne('idm','290px','84px');
</script>

</html

Encore une précision, transformer l'image en bloc pour éviter des marges intempestives (des fractions de lignes) dans le container.
0
hellotk Messages postés 13 Date d'inscription jeudi 15 février 2007 Statut Membre Dernière intervention 4 avril 2011
22 mars 2011 à 17:47
Super ! ça marche comme un charme !!

Mon problème est donc résolu. Merci pour votre réactivité.
@ 007Julien > merci pour votre efficacité !!!
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
22 mars 2011 à 18:36
En outre, ceux qui auront désactivé javascript (il y en a qui préfèrent toujours la draisienne à la bicyclette !) retrouveront le lien et l'image agrandie...
0
Rejoignez-nous