javascripthtmldrag-and-drop

Is it possible to use the HTML5 Drag and drop API with JSON and JavaScript?


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);
    } 
    
    }

Solution

  • 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));
        })
    }