Empêcher de placer l'element de classe"bouge"

Fermé
patricktoulon - 1 mars 2022 à 10:39
 SnoopDoggySnoop - 6 mars 2022 à 08:30
Bonjour,
Configuration: Windows / Chrome 98.0.4758.102

je me suis fait un drag and drop perso avec affiliation au nouveau parent
ce document doit avant tout être compatible ie si + tant mieux mais c'est pas important
car je l'utilise dans une autre application avec un ocx webbrowser issue de IE

je déplace les element de class "bouge" et des que l'element déplacé se trouve a l’intérieur d'un autre element div au relâcher de la souris il lui est affilié en tant qu'enfant et garde sa position
le problème c'est que je n'arrive pas a forcer un min top et un min left correspondant au conteneur principal id "editor"
en gros je ne veux pas qu'il puisse sortir de l'element ID="editor"

merci pour le coup de main
<!DOCTYPE html>
<html>

<head>
<meta http-equiv="X-UA-Compatible" content="IE=10"/>
<title>HTML5 Drag and Drop perso affiliation put on same place By patricktoulon </title>
<style type="text/css">
</style>


<script>
var xx, yy, dragged, vue, EcX, EcY, OldBordure, oldparent, editeur;

window.addEventListener('mousemove', mousemove);
window.addEventListener('mousedown', MouseDown);
editeur=document.getElementById('editor');

function MouseDown(event){
document.title=event.srcElement.id;
}


////////////////////////////////////////////////////////////
function mousemove(event) {
xx = event.pageX;
yy = event.pageY;

if (dragged != null) {
vue.innerHTML = event.pageX;
dragged.style.position = 'absolute';
dragged.style.left = xx - EcX + "px";
dragged.style.top = yy - EcY + "px";
}
}

////////////////////////////////////////////////////////////

function DragStart(ev) {
dragged = ev.srcElement;
oldparent = dragged.parentElement;
OldBordure = dragged.style.border;
vue = document.getElementById('vue');
EcX = ev.pageX - dragged.offsetLeft;
EcY = ev.pageY - dragged.offsetTop;
vue.innerHTML = EcX;
ev.stopPropagation();
ev.returnValue = false;
ev.preventDefault();
ev.returnValue = false;
dragged.style.border = "4px dotted red";
dragged.style.zIndex = 1;
}
//////////////////////////////////////////////////////////
function MouseUp(ev) {
if(dragged != null){
dragged.style.border = OldBordure;
affiliation(ev);
}
}

///////////////////////////////////////////////////////////
function affiliation(ev) {
var rect1 = dragged.getBoundingClientRect();
var r1l = rect1.left;
var r1t = rect1.top;
var r1b = rect1.bottom;
var r1r = rect1.right;
var boxes = document.getElementsByTagName("div");
for (var i = 0; i < boxes.length; i++) {
var rect2 = boxes[i].getBoundingClientRect();
var r2l = rect2.left;
var r2t = rect2.top;
var r2b = rect2.bottom;
var r2r = rect2.right;

if (r2l < r1l && r2t < r1t && r1b < r2b && r1r < r2r) {
var newparent = boxes[i];
}

}
//alert(oldparent.id);


if (oldparent.id != newparent.id) {
var rect2 = newparent.getBoundingClientRect();
if (newparent.id == 'editor') {
var xz = editeur.offsetTop;var yz=editeur.offsetLeft;
} else {
var xz = 0;var yz=0;
}
dragged.style.left = rect1.left - rect2.left+yz + "px";
dragged.style.top = rect1.top - rect2.top + xz + "px";
newparent.appendChild(dragged);

}

dragged.focus;
dragged = null;
oldparent = null;
newparent = null;

}
/////////////////////////////////////////////////////////
function AllDraggable(){
var boxes = document.getElementsByClassName('bouge');
for (var i = 0; i < boxes.length; i++) {
boxes[i].draggable = 'true';
boxes[i].addEventListener('dragstart', DragStart);
boxes[i].addEventListener('mouseup', MouseUp);
}
}
</script>
</head>
<body>
<p>Déplacer l'image et échange de parent à volonté : <font id='vue'></font>
</p>
<div id='editor' contenteditable='true' style="width:600px;height:800px;background-color:rgb(230,230,230);">

<div id='div0' class='bouge' ' style=' position:absolute;left:300px;width:200px;height:200px;background-color:rgb(123,245,232);'></div>

<div id='div1' class='bouge' ' style=' position:absolute;left:50px;top:400px;width:180px;height:180px;background-color:rgb(255,245,232);'></div>

<br>

<img id='drag1' class='bouge' src='https://www.excel-downloads.com/styles/brivium/stylium/strontium/xenforo/logo.png' width='150' height='70'>
</div>

<script>
document.getElementById('div0').style.border = '3px solid blue';
document.getElementById('div1').style.border = '3px solid orange';
AllDraggable();
editeur = document.getElementById('editor')
</script>
</body>
</html>

5 réponses

SnoopDoggySnoopy
2 mars 2022 à 04:38
Salut,

"en gros je ne veux pas qu'il puisse sortir de l'element ID="editor" "
Pour quoi pas un truc du genre?


if ( document.getElementById('editor').querySelector('#IDdestinataire')){
/** j'ai pris querySelector avec une id mais on peut changer (pour ElementsByTagsName ou autre) */
 //ajouter l'élément bougé
}else{
alert('hors limite')
}
0
patricktoulon
2 mars 2022 à 05:08
re
Bonjour SnoopDoggySnoop
j'ai essayé des tas de trucs mais soit
ca marche mais le drag reste actif après le relâcher de la souris
soit ca meme plante l'element dragged en top 0 mais du document
soit alors la limite offsetTop est appliqué meme quand un element class bouge est placé dans un autre div

et en effet queryselector ne fonctionne pas avec le document dans l'ocx

en l’état là le drang and drop + affiliation fonctionne
c'est juste cette limite que je n'arrive pas a determiner sans que ca fasse dérailler le reste
0
SnoopDoggySnoopy
2 mars 2022 à 23:33
Salut, des script de drag and drop il en existe, il y a même une API en HTML:

https://www.w3schools.com/HTML/html5_draganddrop.asp


Vous devez simplement vérifier que pour le drop l'élément cible (qui va être le nouveau container de l'élément déplacé) est bien un élément contenu dans les limites que vous définissez.

On n'est pas dans ActiveX mais dans du JavaScript(IE n'a d'ailleurs jamais été une référence en développement web, plutôt l'inverse) ce qui n'a rien à voir.
Une page web n'est pas faite en dépendant d'un navigateur au contraire elle doit pouvoir être utilisé avec n'importe quel contexte et utiliser une technologie dépassée et plus utilisée(IE à été remplacée par Edge, il y a de bonnes raisons à cela) pas une bonne façon de travailler, en tout cas un risque accru(de bugs, erreurs et spécificités pour corriger les lacunes de telles technos).

Vous faites une page web: faites la donc pour qu'elle s'affiche (donc indépendamment du navigateur) et laissez tomber IE pour quelque chose qui prends en compte les technologies correctement.

Ceci étant dit ce n'est pas le problème puisque vous écrivez JavaScript la question n'est pas lié à ActiveX(ni à un navigateur en particulier, bien sûr utiliser une technologie à jour est fiable est une bonne chose aussi :) donc pas IE qui n'est plus un navigateur à utiliser) mais à du JavaScript.

"et en effet queryselector ne fonctionne pas avec le document dans l'ocx "
Si JavaScript ne fonctionne pas dans votre contexte alors la solution en JavaScript n'est pas viable.

Moi je vous ai répondu en JavaScript puisque la question concerne du JavaScript.
D'ailleurs querySelector est bien compatible avec IE depuis 2011(version 8)

https://caniuse.com/queryselector

Bien sûr il y a d'autres possibilités.
La notation pointée(objet) indique qu'un élément est inclus dans un autre.

La bout de code que je vous est mit indique donc:

document.getElementById('editor').querySelector('#IDdestinataire')
J'ai bien précisé d'ailleurs qu'on pouvait passer par un autre sélecteur...
Si un élément est inclus dans l'élément ayant pour ID 'editor' , la partie avec querySelector est bien sûr variable et doit correspondre à l'élément ciblé(querySelector permet plus de souplesse mais si l'élément qui doit recevoir la balise à une ID rien ne vous empêche de passer par getElementById qui sera plus précis donc mieux mais oblige à donner des ID à tout les éléments qui peuvent recevoir l'élément déplacé- personnellement la solution que j'aurais choisit par que les ID c'est bien et élimine toute confusion possible ).

Si le résultat est inexistant(pas d'élément HTML sélectionné avec les paramètres indiqués, c'est à dire un élément ayant pour parent id='editor' ) et donc la valeur est null.

Si la valeur est nulle alors on annule le déplacement de l'élément(pas de drop et on remet le drag à sa position initiale).
Si la valeur renvoi un élément (donc est un élément contenu dans l'élément ayant pour ID 'editor') alors le programme déplace l'élément.

Vous avez de moins bons algorithmes/conception que celui que j'ai indiqué au dessus qui pourront faire le job.

Par exemple définir une liste dans une tableau de valeurs des éléments qui peuvent recevoir l'élément à déplacer.


const listeCiblesAutorisees =[document.getElementById('element1'), document.getElementsByTagName('div')[1], document.getElementById('element3')]

if(listeCiblesAutorisees.includes(elementDestinationDrop)){
//-- OK on va jusqu'au bout
...instructions pour le drop: déplacer l'élément dans son nouveau contaner
}else{
//-- PAS OK on arrête tout
...instructions pour annuler le drag, afficher un message d'erreur...
}


C'est beaucoup moins dynamique car oblige à créer une liste des éléments qui peuvent recevoir un autre.

Les façons de concevoir son illimitées, tout dépends de vos buts et de la possibilité d'avoir un code dynamique qui peut se maintenir dans la durée.
On voit qu'avez la première méthode que je vous ai indiqué il n'y a besoin que d'un test sur une expression(l'élément existe t'il bien dans les limite définies) et que si la page est changée, qu'on ajoute ou enlève des éléments il fonctionnera toujours.

La deuxième méthode oblige à rajouter une variable et donc mettre à jour si un changement intervient dans la page.
On peut faire beaucoup moins dynamique, compliqué et long à écrire/comprendre pour avoir un résultat, donc un moins bon code qui fonctionnera mais sur le long terme rends juste le programme lourd et oblige à modifier le code(ça s'appelle donc un mauvais programme et il devient impossible à maintenir donc bon à jeter pour partir sur de bonnes bases car ce sera moins de travail pour modifier le moindre élément de la page)...

Utiliser offset et des dimensions fixées(imposées à l'utilisateur qui peuvent facilement provoquer des bugs) me semble tenir du dernier cas.

A vous de voir parce qu'on peut arriver à ce que vous voulez en utilisant les tailles et positions(renseignées par offset), mais par rapport à votre demande une ligne comparée à des dizaines qui dépendront du contexte et nécessiteront du développement compliqué(et pas évident non plus) qui déjà ne s'adaptera pas à toutes les tailles d'écrans(donc pas très fiable) et un temps de développement pour la moindre modification qui est aussi long que de tout refaire de zéro(recalculer à chaque fois et pour chaque page/utilisateur des positions précises quand il existe d'autres méthodes).

Avec ma première proposition vous pouvez aussi regarder du côté des méthodes childsNodes et .children mais elles ne sont adaptées que pour cibler des éléments qui seraient des enfants directs(oubliant toute descendance plus lointaine). A voir si cela peut correspondre à votre environnement(la page HTML) cela peut faciliter les choses(et p-e votre compréhension).
0
patricktoulon
3 mars 2022 à 08:18
re
Bonjour SnoopDoggySnoop
oui je sais que le drag and drop existe mais tout seul il ne fait pas ce que je fait

ensuite il est pour moi obligé de travailler en compatibilité IE car l'ocx en est issue

je n'ai pas de soucis avec mon code je ne sais tout simplement pas ou mettre le blocage en top 0 du conteneur

j'ai déjà essayé les offsetTop et offsetLeft sauf que que ces deux donnent le offset par rapport au parent initial donc quand je dragg un div qui enfant d'un autre div pour le ramener a enfant de editor ca déraille ce blocage s'applique alors meme dans un autre div

j'ai aussi essayé de bloquer xx et yy -ecx et yy-ecy si plus petit que offsetTop de editor
la aussi ca déraille

quand a faire une liste c'est pas possible car les div sont ajoutés et / ou supprimés dynamiquement

merci quand meme pour les retours
0

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

Posez votre question
Salut,
quelques remarques:
"oui je sais que le drag and drop existe mais tout seul il ne fait pas ce que je fait "
A moins de le rajouter...ce qui est le principe d'une API fournir un outil pour en faire ce qu'on en veut, comme personnaliser/améliorer/augmenter les fonctions de base et ne pas avoir à réinventer la roue.

"ensuite il est pour moi obligé de travailler en compatibilité IE car l'ocx en est issue "
Ce qui prouve bien ce que je dit, ocx n'est pas adapté comme solution. Donc autant en changer plutôt que de s'acharner à utiliser quelque chose qui n'est pas adapté. A moins bien sûr qu'une autre contrainte vous y oblige. Regarder éventuellement du côté des polyfills pour IE mais utiliser des technologies désuètes et non maintenues ajoute des risques(failles nottament de sécurité) et complique les choses.

"j'ai déjà essayé les offsetTop et offsetLeft sauf que que ces deux donnent le offset par rapport au parent initial"
En effet c'est bien ce que dit la doc de la propriété:
https://www.w3schools.com/jsref/prop_element_offsettop.asp

Où vous pouvez lire voir aussi: .clientTop qui fait bien ce que vous voulez mais ne résous pas les problèmes que j'ai évoqués : des dimensions qui sont différentes pour chaque utilisateur(selon son écran et la résolution choisie) donc pas la bonne façon de faire à moins que cela vous plaise de vous compliquer la vie en devant rajouter des calculs de proportions en obtenant les tailles de la fenêtre du navigateur et qui sont facilement évitables en utilisant directement des tailles proportionnelles dans votre mise en page ou simplement en définissant l'élément parent qui peut accepter le drop en incluant les enfants comme le code que j'ai indiqué peut le faire.

"quand a faire une liste c'est pas possible car les div sont ajoutés et / ou supprimés dynamiquement "
Si c'est possible en définissant la liste dynamiquement(bien que le mot porte à confusion: les pages dynamiques ou zones dynamiques d'une page utilisent une base de données et un programme serveur). Là il me semble que vous mélangez la méthode/algorithme qui permet de faire une chose et son résultat. Ajouter un div est une fonctionnalité et le résultat d'une partie du programme et non le programme en lui même. C'est donc sur la partie programme et à l'ajout du div que vous pouvez rajouter celui ci dans la liste(ou son ID pour contrôler , voir name mais la méthode getElementsByTagName est réputée à éviter car elle donne un résultat en tableau et nécessite plus de ressources/temps pour obtenir un réssultat tout en donnant un résultat non exploitable directement ainsi bien sûr que des possibilité de confusion quand on cherche un résultat unique qui n'est pas garantit par l'attribut name mais l'est par l'attribut id ).

Vous pouvez voir ici que le problème des technologie ActiveX est cité en première ligne:

https://fr.wikipedia.org/wiki/ActiveX
ActiveX désigne l'une des technologies dépréciées...

Déprécié signifiant (pour une fonction ou un langage) bien ce que ça veut dire et indique qu'il ne faut pas utiliser ce qui est déprécié sauf si on aime avoir un programme qui tombe en panne facilement, ne peut pas être maintenu/mis à jour et ne persistera pas dans le temps tout en étant une porte ouverte à des failles de sécurités.
Dans un langage/technologie qui est maintenu ce qui est déprécié est remplacé par autre chose qui ne présente pas de problème. Hors ActiveX n'étant pas maintenu comme la plupart des technologies Microsoft du web qui voulait établir des technologies propriétaires à eux plutôt que des technologies libres qui ne nécessitent pas de passer par eux. Bref c'était une opération commerciale de tentative de monopole(classique depuis les débuts de Microsoft) qui n' a donné que des outils comportant des problèmes(bien connus des développeurs web) quand d'autres n'en avaient pas.
Et forcément qui ont disparues quand quelque chose est mauvais, pas fiable, oblige à des complexités qu'il n'y a pas ailleurs et provoque facilement des erreurs(l'incompatibilité étant l'une d'elles) tout en étant dépendant d'une entreprise en particulier et qu'à côté on a quelque chose de performant non lié à une entreprise en particulier c'est logique que ce qui es mauvais disparaisse pour son alternative efficace, pertinente et non commerciale ou en tout cas ouverte quand un format propriétaire(d'une entreprise) est tout l'inverse.

ps: vous expliquez ça à votre entreprise (ou client) et vous leur fournissez un audit de technologie, sur cette partie en tout cas et cela peut vous valoriser d'améliorer les outils qu'ils utilisés. Si le client/commanditaire/patron ne comprends pas alors l'entreprise continue à fonctionner avec des outils médiocres et multiplie les risques tout en perdant en performances et l'entreprise fait un mauvais choix car fonctionner avec de mauvais outils(pas peur du changement? Sauf que les changements font partie intégrante de l'informatique et s'y adapter un atout et l'inverse un désavantage)

Voilà comme vous pouvez voir une question technique s'aborde en amont, c'est l'analyse+conception et la pertinence du choix des technologie utilisés(auquel on peut ajouter la veille technologique: se tenir au courant de l'évolution dans le temps de ce qui se fait, ce qui fonctionne pour un cahier des charges précis ).
Ce qui semble le problème auquel vous êtes confronté et ne se résous pas par changer une ligne de code mais changer vos outils non adaptés et votre méthodologie(algorithme pour le cas précis que vous évoquez, voir mes explications où j'indique pourquoi un placement par le positionnement est pas la bonne façon de faire et complique les choses quand d'autres méthodes/façon, de penser plus efficaces et simples permettent le même résultat en mieux).
0