Я печатаю простую строку на экране. При нажатии на одну из ее букв следует удалить ее из строки и добавить в конец. После того, как я нажимаю на одну букву, и новая строка печатается на странице, буквы не сохраняют свои прослушиватели событий. Это код JS и вот весь код https://codesandbox.io/s/reverse-array-forked-fvclg?file=/src/index.js:0-1316:
const appBox = document.getElementById("app");
const convertString = (string) => {
let stringToArray = string.split("");
return stringToArray;
};
let stringToArray = convertString("Hello world!");
const printArrayToPage = (string) => {
string.forEach((element) => {
const textBox = document.createElement("div");
if (element !== " ") {
textBox.classList.add("letter");
} else {
textBox.classList.add("emptySpace");
}
const text = document.createTextNode(element);
textBox.appendChild(text);
appBox.appendChild(textBox);
});
};
window.onload = printArrayToPage(stringToArray);
const moveLetter = (event) => {
const targetLetter = event.target;
const letterToRemove = targetLetter.innerHTML;
targetLetter.classList.add("invisible");
if (stringToArray.includes(letterToRemove)) {
const index = stringToArray.indexOf(letterToRemove);
stringToArray.splice(index, 1);
}
stringToArray.push(letterToRemove);
appBox.innerHTML = "";
printArrayToPage(stringToArray);
};
const allLetters = document.querySelectorAll(".letter");
allLetters.forEach((element) => element.addEventListener("click", moveLetter));
const allSpaces = document.querySelectorAll(".emptySpace");
allSpaces.forEach((element) => element.addEventListener("click", moveLetter));
Я попытался переместить четные задания (этот блок)
const allLetters = document.querySelectorAll(".letter");
allLetters.forEach((element) => element.addEventListener("click", moveLetter));
const allSpaces = document.querySelectorAll(".emptySpace");
allSpaces.forEach((element) => element.addEventListener("click", moveLetter));
внутри функции printArrayToPage
, но поскольку я использую синтаксис ES6, я не могу использовать функцию до ее определения. Если я перейду к функциям, созданным с использованием ключевого слова function
, все будет работать так, как ожидалось. Как я могу исправить эту проблему с помощью ES6, чтобы после нажатия на букву и повторного добавления divs
на страницу прослушиватели событий переназначались?
Почему бы просто не использовать объявления ES6 function
? Они более декларативны, немного короче и действительно работают.
@ Берги, ты имеешь в виду этот синтаксис () => {}
?
@AriO Я имею в виду синтаксис function moveLetter(event) {…}
@Bergi Берги Я думал, что это просто объявление стандартной функции? В ES6 появились толстые стрелочные функции, не так ли?
@charlietfl спасибо, на самом деле это то, о чем я не знал, поэтому теперь я могу об этом прочитать. Очень признателен.
@AriO Стандарт ES6 также представил новые функции для объявлений function
. «Использование ES6» не означает ограничение себя самыми последними языковыми дополнениями.
@Bergi Берги, я почитаю об этом подробнее, спасибо. Честно говоря, в 95% случаев я использую стрелочные функции до такой степени, что обычные выглядят странно.
Если вы хотите переместить узел с буквой в конец, вы можете использовать свойство Node.parentNode и добавить дочерний узел в конец. Вам не нужно создавать узлы каждый раз, когда нажимается элемент:
const moveLetter = (event) => {
const targetLetter = event.target;
const parent = targetLetter.parentNode;
parent.appendChild(targetLetter); // move the element to the end
};
См.: https://codesandbox.io/s/reverse-array-forked-lf333?file=/src/index.js
Используйте делегирование событий. Вот простой пример фрагмента:
// adding an event listener to the document
document.addEventListener("click", evt => {
console.clear();
const origin = evt.target;
// ^ where did the event originated?
if (origin.closest("#bttn1")) {
console.info("you clicked button#bttn1");
} else if (origin.closest("#bttn2")) {
console.info("you clicked button#bttn2")
}
});
createElement("h3", "header", "Wait 2 seconds...");
// creating buttons after a while. The earlier created
// event listener will detect clicks for the new buttons
setTimeout( () => {
createElement("button", "bttn1", "click me");
createElement("button", "bttn2", "click me too");
}, 2000);
function createElement(nodetype, id, text) {
document.body.appendChild(
Object.assign(document.createElement(nodetype), {id, textContent: text})
);
}
body {
font: normal 12px/15px verdana, arial;
margin: 2rem;
}
button {
margin: 0 0.6rem 0 0;
}
Предлагаем вам изучить, как использовать «делегирование событий»