#javascript #html #function #ecmascript-6 #event-listener
#javascript #HTML #функция #ecmascript-6 #прослушиватель событий
Вопрос:
Я печатаю простую строку на экране. При нажатии на одну из ее букв is следует удалять из любой строки и добавлять в конце. После того, как я нажимаю на одну букву, и новая строка печатается на странице, буквы не сохраняют свои прослушиватели событий. Это код 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
повторного добавления на страницу слушатели событий переназначались?
Комментарии:
1. Предлагаю вам изучить, как использовать «делегирование событий»
2. Почему бы просто не использовать
function
объявления ES6? Они более декларативные, немного короче и действительно работают.3. @Bergi вы имеете в виду этот синтаксис
() => {}
?4. @AriO Я имею в виду
function moveLetter(event) {…}
синтаксис5. @AriO Стандарт ES6 также представил новые функции для
function
объявлений. «Использование ES6» не означает ограничения себя самыми последними языковыми дополнениями.
Ответ №1:
Если вы хотите переместить буквенный узел в конец, вы можете использовать свойство 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
Ответ №2:
Используйте делегирование событий. Вот простой пример фрагмента:
// 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.log("you clicked button#bttn1");
} else if (origin.closest("#bttn2")) {
console.log("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;
}