Aller au contenu

Glisser-déposer en JavaScript

Dans ce tutoriel, nous allons explorer la fonctionnalité de glisser-déposer en JavaScript, une fonctionnalité puissante qui améliore l’interactivité des pages web. Nous commencerons par examiner les concepts et algorithmes de base qui rendent le glisser-déposer possible, puis nous passerons à un exemple pratique où vous pourrez voir ces idées en action. Cet exemple met en scène une icône de lumière que vous pouvez faire glisser dans une zone sombre pour l’illuminer.

Qu’est-ce que le glisser-déposer ?

Le glisser-déposer est une interaction d’interface utilisateur qui permet aux utilisateurs de saisir un objet et de le déplacer vers un autre emplacement à l’écran. Cette interaction est courante dans la gestion de fichiers sur votre ordinateur, l’organisation d’éléments dans des jeux ou les outils d’édition en ligne.

Concepts de base du glisser-déposer en JavaScript

L’algorithme du Drag’n’Drop

  1. Commencer le glisser :
    • Le processus commence lorsque l’utilisateur clique sur l’élément et maintient le bouton de la souris enfoncé.
  2. Faire glisser l’élément :
    • À mesure que la souris se déplace, l’élément suit le trajet du curseur à travers l’écran.
  3. Déposer l’élément :
    • L’élément est relâché lorsque l’utilisateur lâche le bouton de la souris, ce qui le place à un nouvel emplacement.

Comprendre les zones de dépôt

Les zones de dépôt sont des zones désignées pour recevoir les éléments déplaçables. Ces zones détectent lorsqu’un objet déplaçable se trouve au-dessus d’elles et peuvent déclencher des actions spécifiques en réponse.

INFO

Assurez-vous que votre fonctionnalité de glisser-déposer est adaptée au tactile. Les utilisateurs mobiles doivent pouvoir faire glisser et déposer avec des gestes tactiles. Pensez à implémenter des événements tactiles (touchstart, touchmove, touchend) ou à utiliser une bibliothèque légère pour une compatibilité multi-appareils.

Exemple interactif : zone claire et zone sombre

Mettons la théorie en pratique avec un exemple simple mais interactif. Nous utiliserons une icône d’ampoule comme objet déplaçable. Lorsque cette icône est déplacée au-dessus d’une zone sombre, la zone s’illuminera, simulant l’effet d’une lumière allumée.

Mise en place du HTML et du CSS

Tout d’abord, nous définissons la structure et le style de base. Nous incluons une boîte sombre et une icône d’ampoule.

Structure HTML


html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Interactive Lighting with Drag and Drop</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />
<style>
  #darkArea {
    width: 300px;
    height: 300px;
    background-color: #333;
    position: relative;
    margin-top: 20px;
  }
  #lightIcon {
    font-size: 48px;
    color: #ccc;
    cursor: pointer;
    position: absolute;
  }
</style>
</head>
<body>
<div id="main">
  <div id="darkArea"></div>
  <i id="lightIcon" class="fas fa-lightbulb"></i>
</div>

<script>
// JavaScript will be added here.
</script>
</body>
</html>

Implémentation du JavaScript

Maintenant, ajoutons la fonctionnalité pour rendre l’ampoule déplaçable et réactive à la zone sombre.

Explication du code JavaScript


javascript
<script>
  // Get references to the light bulb icon and the dark area on the webpage
  var lightIcon = document.getElementById("lightIcon");
  var darkArea = document.getElementById("darkArea");

  // Variables to track whether the dragging is active and to store position data
  var active = false;
  var initialX, initialY, currentX, currentY, xOffset = 0, yOffset = 0;

  // Listen for the mouse down event on the light bulb icon
  lightIcon.addEventListener("mousedown", function(e) {
    // Record the starting position of the mouse and adjust by any existing offset
    initialX = e.clientX - xOffset;
    initialY = e.clientY - yOffset;
    // Set the active flag to true, indicating that dragging has started
    active = true;
  });

  // Listen for mouse movement across the entire document
  document.addEventListener("mousemove", function(e) {
    // If not dragging, don't do anything
    if (!active) return;
    // Calculate the new position of the mouse
    currentX = e.clientX - initialX;
    currentY = e.clientY - initialY;
    // Update the offset with the new position
    xOffset = currentX;
    yOffset = currentY;
    // Move the light bulb icon to the new position
    lightIcon.style.transform = "translate3d(" + currentX + "px, " + currentY + "px, 0)";
  });

  // Listen for the mouse up event across the entire document
  document.addEventListener("mouseup", function() {
    // Save the final position of the light bulb
    initialX = currentX;
    initialY = currentY;
    // Set the active flag to false, indicating dragging has ended
    active = false;
    // Check if the light bulb is inside the dark area
    if (isInside(darkArea, lightIcon)) {
      // Change the background color of the dark area to yellow
      darkArea.style.backgroundColor = "yellow";
      // Change the color of the light bulb to yellow
      lightIcon.style.color = "yellow";
    } else {
      // Revert the dark area's color to dark
      darkArea.style.backgroundColor = "#333";
      // Revert the light bulb's color to gray
      lightIcon.style.color = "#ccc";
    }
  });

  // Function to check if the light bulb is inside the dark area
  function isInside(container, element) {
    // Get the position of the container and the element
    var containerRect = container.getBoundingClientRect();
    var elementRect = element.getBoundingClientRect();
    // Return true if the element is within the container's boundaries
    return (
      elementRect.left >= containerRect.left &&
      elementRect.right <= containerRect.right &&
      elementRect.top >= containerRect.top &&
      elementRect.bottom <= containerRect.bottom
    );
  }
</script>

Ce script rend une icône d’ampoule déplaçable à l’écran avec votre souris. Vous pouvez cliquer sur l’ampoule, la faire glisser et voir comment elle interagit avec une zone sombre à l’écran. Voici ce que fait chaque partie du script en termes simples :

  1. Préparer le tout : d’abord, le script identifie l’icône d’ampoule et la zone sombre sur votre page web. Il met aussi en place des règles pour suivre le mouvement de la souris.

  2. Commencer à faire glisser :

    • Lorsque vous appuyez sur l’ampoule avec la souris, le script mémorise l’endroit où vous avez commencé. Cela l’aide à savoir de combien vous déplacez l’ampoule ensuite.
  3. Déplacer l’ampoule :

    • Pendant que vous déplacez la souris en maintenant le bouton enfoncé, le script fait suivre l’ampoule à votre souris. Il le fait en mettant constamment à jour la position de l’ampoule pour qu’elle corresponde à l’endroit où se trouve votre souris.
  4. Déposer l’ampoule :

    • Lorsque vous relâchez le bouton de la souris, le script vérifie si l’ampoule se trouve au-dessus de la zone sombre. Si c’est le cas, la zone sombre s’illumine et devient jaune, et l’ampoule change aussi de couleur pour montrer qu’elle est allumée. Si elle n’est pas au-dessus de la zone sombre, tout revient à la normale.
  5. Vérifier la position :

    • Il existe un ensemble spécial de règles (une fonction nommée isInside) qui aide le script à savoir si l’ampoule se trouve au-dessus de la zone sombre ou non. Elle compare la position de l’ampoule aux limites de la zone sombre.

INFO

Utilisez translate3d dans vos transformations CSS pour faire glisser des éléments. Cela exploite l’accélération GPU, ce qui permet des mouvements plus fluides et une charge CPU plus faible, un point crucial pour les applications gourmandes en performances.

Exemple complet

Maintenant, il est temps de voir tout cela en action, alors :


html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Interactive Lighting with Drag and Drop</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />
    <style>
      #darkArea {
        width: 300px;
        height: 300px;
        background-color: #333;
        position: relative;
        margin-top: 20px;
      }
      #lightIcon {
        font-size: 48px;
        color: #ccc;
        cursor: pointer;
        position: absolute;
      }
    </style>
  </head>
  <body>
    <div id="main">
     <p>Move the light into the dark area to light it up!</p>
      <div id="darkArea"></div>
      <i id="lightIcon" class="fas fa-lightbulb"></i>
    </div>

    <script>
      // Get references to the light bulb icon and the dark area on the webpage
      var lightIcon = document.getElementById("lightIcon");
      var darkArea = document.getElementById("darkArea");

      // Variables to track whether the dragging is active and to store position data
      var active = false;
      var initialX,
        initialY,
        currentX,
        currentY,
        xOffset = 0,
        yOffset = 0;

      // Listen for the mouse down event on the light bulb icon
      lightIcon.addEventListener("mousedown", function (e) {
        // Record the starting position of the mouse and adjust by any existing offset
        initialX = e.clientX - xOffset;
        initialY = e.clientY - yOffset;
        // Set the active flag to true, indicating that dragging has started
        active = true;
      });

      // Listen for mouse movement across the entire document
      document.addEventListener("mousemove", function (e) {
        // If not dragging, don't do anything
        if (!active) return;
        // Calculate the new position of the mouse
        currentX = e.clientX - initialX;
        currentY = e.clientY - initialY;
        // Update the offset with the new position
        xOffset = currentX;
        yOffset = currentY;
        // Move the light bulb icon to the new position
        lightIcon.style.transform = "translate3d(" + currentX + "px, " + currentY + "px, 0)";
      });

      // Listen for the mouse up event across the entire document
      document.addEventListener("mouseup", function () {
        // Save the final position of the light bulb
        initialX = currentX;
        initialY = currentY;
        // Set the active flag to false, indicating dragging has ended
        active = false;
        // Check if the light bulb is inside the dark area
        if (isInside(darkArea, lightIcon)) {
          // Change the background color of the dark area to yellow
          darkArea.style.backgroundColor = "yellow";
          lightIcon.style.color = "yellow";
        } else {
          // Revert the dark area's color to dark
          darkArea.style.backgroundColor = "#333";
          // Revert the light bulb's color to gray
          lightIcon.style.color = "#ccc";
        }
      });

      // Function to check if the light bulb is inside the dark area
      function isInside(container, element) {
        // Get the position of the container and the element
        var containerRect = container.getBoundingClientRect();
        var elementRect = element.getBoundingClientRect();
        // Return true if the element is within the container's boundaries
        return elementRect.left >= containerRect.left && elementRect.right <= containerRect.right && elementRect.top >= containerRect.top && elementRect.bottom <= containerRect.bottom;
      }
    </script>
  </body>
</html>

Événements de souris clés utilisés :

  1. mousedown : cet événement se déclenche lorsque l’utilisateur appuie sur le bouton de la souris au-dessus de l’icône d’ampoule. Il marque le début du glisser et enregistre la position initiale du curseur.
  2. mousemove : cet événement se déclenche lorsque la souris est déplacée. Si le glisser est actif (c’est-à-dire si le bouton de la souris est toujours enfoncé), il calcule la nouvelle position de l’icône en fonction du mouvement du curseur et met à jour la position de l’ampoule à l’écran.
  3. mouseup : cet événement se produit lorsque l’utilisateur relâche le bouton de la souris, marquant la fin du glisser. Il vérifie si l’ampoule se trouve à l’intérieur des limites de la zone sombre pour décider s’il faut changer la couleur de fond de la zone.

Comme nous l’avons appris dans l’article Mouse Events, ces événements sont fondamentaux pour créer une fonctionnalité interactive de glisser-déposer, permettant de déplacer dynamiquement des éléments sur une page web et d’interagir avec eux à l’aide d’une souris.

Conclusion

Les actions de glisser-déposer peuvent rendre vos sites web plus faciles à utiliser et plus attrayants. En apprenant les idées simples et en les essayant avec de vrais exemples, vous pouvez bien utiliser ces fonctionnalités intéressantes. Cela rend vos sites web plus amusants et interactifs.

Practice

Quelles sont les affirmations vraies concernant la fonctionnalité de glisser-déposer en JavaScript ?

Trouvez-vous cela utile?

Aperçu dual-run — comparez avec les routes Symfony en production.