Gérer les événements sur une image lors d'un drag&drop dans div contenteditable
bonjour à tous,
je travaille actuellement sur un éditeur wysiwyg. L'un des objectifs est d'ajouter une image dans une zone éditable (un div "editeur" avec un contenteditable à true), de pouvoir la déplacer n'importe où dans le texte et de pouvoir l'aggrandir ou la diminuer (en cliquant dessus, j'affiche dynamiquement 8 petits carrés en bordure de l'image via :
- un div parent "cadre_image" qui permet de gérer le cover, et en enfants :
- l'image sélectionnée
- un div "dimensions"
- 8 div "dimension : gauche, haut gauche, haut, haut droit, droit, bas droit, bas, bas gauche" enfants de "dimensions" dessinant les carrés
des événements sur les 8 div "dimension" permettent le redimensionnement. un événement onblur sur "dimensions" permet de désélectionner l'image en supprimant dynamiquement les petits carrés.
mon système de "selection / redimensionnement / deselection" fonctionne parfaitement mais tout part en sucette dès que je déplace l'image. Comme le div parent "editeur" est éditable, je laisse le navigateur gérer le drag and drop du texte et des images.
Le souci, c'est que :
- si l'image est sélectionnée, le drag&drop ne déplace que "cadre_image" et "image", il supprime "dimensions" et les "8 dimension enfant" et il perd tous les événements associés
- si l'image n'est pas sélectionnée, il déplace l'image correctement mais il perd ses événements
j'ai bien entendu essayé de réaffecter les événements à l'image une fois déplacée, mais ça ne fonctionne pas. :aie:
voici mon code allégé avec un simple compteur incrémenté à chaque clic de l'image (cette action remplace ma tartine de code qui gère le redimensionnement). objectif : déplacer l'image et conserver son événement onclick qui incrémente le compteur.
Je vous envoie le bout de code qui se rapproche le plus de la solution mais ce n'est pas stable. l'affectation de l'événement n'est pas systématiquement sur l'image et ça génère des aberrations (c'est le div "editeur" qui est redimensionnable). J'ai aussi des bugs aléatoires ou l'image n'est pas déplacée mais dupliquée voire même des fois supprimée !!!
J'ai fait 3 milliards d'autres essais sans succès :
- appeler la fonction affecter_evenement() dans le drop (elle est bien appelée mais l'image déplacée ne reçoit pas l'événement comme si elle était supprimée et recréée après le drop !?!!)
- appeler affecter_evenement() dans le dragend (mais elle n'est pas appelée du tout)
- affecter un id "image_selection" lors du dragstart pour affecter lors du drop document.getElementById('image_selection').addEventListener('click', compter); (marche pas)
- gérer moi même le drag&drop mais je bloque sur l'insertion de l'image à la position du curseur au milieu du texte...
merci pour votre aide. je suis en train de perdre la boule :arf:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
<!DOCTYPE html>
<html lang="fr">
<head>
<meta http-equiv="content-type" content="text/html" charset="UTF-8">
<style type="text/css">
#editeur
{
width: 600px;
height: 450px;
border: 1px solid black;
}
#editeur .image_wysiwyg
{
/* contain (proportion), cover (ratio) ou fill (étirement) définit par le client */
object-fit: cover;
cursor: move;
}
#compteur
{
background-color: yellow;
}
#result
{
background-color: mistyrose;
}
</style>
</head>
<body>
<div id="editeur" contenteditable="true">
<div id="compteur">1</div>
<div id="result">action...</div>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.
Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.
<br />
<img src="arbre.png" class="image_wysiwyg" style="width: 100px; height: 20px;">
<br />
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.
Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.
<br />
<img src="arbre.png" class="image_wysiwyg" style="width: 150px; height: 50px;">
<br />
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.
Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.
Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. Mauris eget neque at sem venenatis eleifend. Ut nonummy.
</div>
</body>
<script type="text/javascript">
function affecter_evenement()
{
var images_wysiwyg = document.querySelectorAll('.image_wysiwyg'),
images_wysiwyg_nb = images_wysiwyg.length;
for (var i = 0; i < images_wysiwyg_nb; i++)
{
images_wysiwyg[i].addEventListener('click', compter);
j = i + 1;
document.getElementById('result').innerHTML = 'action : affecter_evenement() ' + j + ' image(s) affectée(s)';
}
}
function compter()
{
document.getElementById('result').innerHTML = 'action : click sur image (incrémente le compteur)';
var increment_i = parseInt(document.getElementById('compteur').innerHTML) + 1;
document.getElementById('compteur').innerHTML = increment_i;
}
document.getElementById('editeur').addEventListener('dragstart', function (e)
{
document.getElementById('result').innerHTML = 'action drag :' + e.target.nodeName;
e.dataTransfer.setData('text/plain', ''); // Nécessaire pour Firefox !?!!
});
document.getElementById('editeur').addEventListener('drop', function (e)
{
document.getElementById('result').innerHTML = 'action dragend :' + e.currentTarget.nodeName;
e.currentTarget.addEventListener('click', affecter_evenement);
});
window.onload = affecter_evenement();
</script>
</html> |