skip to Main Content

If I use static images in an HTML, the Drag n drop API works, but I need to add properties to the images to manipulate those properties later with JS (the images are about games and I wanna add price, id, name, etc.) so I made a JSON containing the images and properties. I fetch that JSON and get the images I’m gonna drag in a div with JS. When it comes to the ‘dragstart’ event it doesn’t work and I don’t get any errors when I start dragging an image. The images are there when the fetch is done but it’s like Chrome or even Firefox doesn’t read them when I start dragging. I accept any comments and I will be thankful for any response. Here’s my JS:

document.addEventListener('DOMContentLoaded', iniciarApp );

    function iniciarApp() {
    
        var contenedor = document.querySelector('#contenedor');
        var narrowDiv = document.querySelector('#narrow');
        
    
        obtenerDatos();
    function obtenerDatos() {
        const url = 'data/productos.json';
        fetch(url)
            .then( respuesta => respuesta.json())
            .then( resultado => cargarImgNarrow(resultado))
    }
    
    
    function cargarImgNarrow(imagenes = []) {
        
        imagenes.forEach( img => {
            const { imagen, precio, nombre, id } = img;
            var productoImg = document.createElement('IMG');
            productoImg.src = imagen;
            productoImg.value = precio;
            productoImg.name = nombre;
            productoImg.id = id;
            productoImg.alt = "imagen";
            productoImg.draggable = true;
            productoImg.classList.add('draggable', 'drag-item');
            narrowDiv.appendChild(productoImg);
            
        })
    }
        
    var draggableElements = document.querySelectorAll(".draggable");
    
    
    draggableElements.forEach(elem => {
        elem.addEventListener("dragstart", (event) => dragStart(event));
    })
    
    // drag andr drop functions
    
    function dragStart(event) {
        
        console.log("Dragging...")
        event.dataTransfer.setData("text/plain", event.target.id);
       // event.dataTransfer.setData("text", event.target.value);
    } 
    
    }

2

Answers


  1. The querySelectorAll() is invoked before or even during the firing of the DOMContentLoaded Event. If the HTMLElements of the NodeList you are fetching were static, this wouldn’t be a problem. But since it is dynamic, the HTMLElements do not yet exist when the querySelectorAll() is invoked. The outcome is an empty NodeList. You can see for yourself by adding the snippet:

    draggableElements.forEach(elem => {
        console.log(elem)
        /* •••Rest of code••• */
    }

    I don’t see what stops you from adding the event listener directly on the HTMLElement you created given that you still have hold of them. The overhead of fetching a NodeList is avoided.

    function cargarImgNarrow(imagenes = []) {
        imagenes.forEach(img => {
            /* •••Rest of code••• */
            productoImg.addEventListener("dragstart", event => dragStart(event));
        })
    }
    Login or Signup to reply.
  2. You can just add the event listener to a parent element, like #narrow. The event target will still be the image, because it is the only element that you allowed being dragged.

    Btw.: Don’t define function within functions. It is not an issue to define a function beforehand even though it handles elements in the DOM. You just need to wait for the DOM to load before calling the function.

    var narrowDiv, contenedor;
    
    document.addEventListener('DOMContentLoaded', iniciarApp);
    
    function iniciarApp() {
      contenedor = document.querySelector('#contenedor');
      narrowDiv = document.querySelector('#narrow');
    
      narrowDiv.addEventListener("dragstart", dragStart);
    
      obtenerDatos();
    }
    
    function obtenerDatos() {
      let url = 'data:application/json,[{"imagen":"/img01.png","precio":123,"nombre":123,"id":1},{"imagen":"/img02.png","precio":123,"nombre":123,"id":2}]';
      fetch(url)
        .then(respuesta => respuesta.json())
        .then(resultado => cargarImgNarrow(resultado));
    }
    
    
    function cargarImgNarrow(imagenes = []) {
      imagenes.forEach(img => {
        const {
          imagen,
          precio,
          nombre,
          id
        } = img;
        var productoImg = document.createElement('IMG');
        productoImg.src = imagen;
        productoImg.value = precio;
        productoImg.name = nombre;
        productoImg.id = id;
        productoImg.alt = "imagen"+imagen;
        productoImg.draggable = true;
        productoImg.classList.add('draggable', 'drag-item');
        narrowDiv.appendChild(productoImg);
      });
    }
    
    // drag andr drop functions
    
    function dragStart(event) {
      event.dataTransfer.setData("text/plain", event.target.id);
      console.log("Dragging... id:",event.target.id);
      // event.dataTransfer.setData("text", event.target.value);
    }
    <div id="contenedor"></div>
    <div id="narrow"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search