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
The
querySelectorAll()
is invoked before or even during the firing of theDOMContentLoaded
Event
. If theHTMLElement
s of theNodeList
you are fetching were static, this wouldn’t be a problem. But since it is dynamic, theHTMLElement
s do not yet exist when thequerySelectorAll()
is invoked. The outcome is an emptyNodeList
. You can see for yourself by adding the snippet: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 aNodeList
is avoided.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.