Если я использую статические изображения в HTML, API Drag n drop работает, но мне нужно добавить свойства к изображениям, чтобы позже манипулировать этими свойствами с помощью JS (изображения посвящены играм, и я хочу добавить цену, идентификатор, имя и т. д. ), поэтому я создал JSON, содержащий изображения и свойства. Я извлекаю этот JSON и получаю изображения, которые собираюсь перетащить в div с помощью JS. Когда дело доходит до события «dragstart», оно не работает, и я не получаю никаких ошибок, когда начинаю перетаскивать изображение. Изображения присутствуют, когда выборка завершена, но Chrome или даже Firefox не читают их, когда я начинаю перетаскивать. Я принимаю любые комментарии и буду благодарен за любой ответ. Вот мой 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.info("Dragging...")
event.dataTransfer.setData("text/plain", event.target.id);
// event.dataTransfer.setData("text", event.target.value);
}
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


querySelectorAll() вызывается до или даже во время срабатывания DOMContentLoadedEvent. Если бы HTMLElement из NodeList, которые вы извлекаете, были статическими, это не было бы проблемой. Но поскольку он динамичен, HTMLElement еще не существует, когда querySelectorAll() вызывается. Результат — пустой NodeList. Вы можете убедиться в этом сами, добавив фрагмент:
draggableElements.forEach(elem => {
console.info(elem)
/* •••Rest of code••• */
}Я не понимаю, что мешает вам добавить прослушиватель событий непосредственно в созданный вами HTMLElement, учитывая, что они все еще у вас есть. Избегаются затраты на получение NodeList.
function cargarImgNarrow(imagenes = []) {
imagenes.forEach(img => {
/* •••Rest of code••• */
productoImg.addEventListener("dragstart", event => dragStart(event));
})
}Вы можете просто добавить прослушиватель событий к родительскому элементу, например #narrow. Целью события по-прежнему будет изображение, поскольку это единственный элемент, перетаскивание которого разрешено.
Кстати: не определяйте функцию внутри функции. Предварительное определение функции не является проблемой, даже если она обрабатывает элементы в DOM. Вам просто нужно дождаться загрузки DOM, прежде чем вызывать функцию.
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.info("Dragging... id:",event.target.id);
// event.dataTransfer.setData("text", event.target.value);
}<div id = "contenedor"></div>
<div id = "narrow"></div>
изменение позиции forEach решило проблему. Спасибо, мистер Кэнон!