#javascript #arrays
#javascript #массивы
Вопрос:
Я использую vanilla JS, я могу нажать на массив и удалить последний элемент из массива. Затем я пытаюсь удалить элемент массива по щелчку. Функция, которую я создал ниже, работает, но она неправильная? Где я ошибаюсь? Я не хочу удалять элемент из DOM, я бы предпочел удалить элемент из массива, а затем обновить состояние пользовательского интерфейса.
Итак, код ниже:
let someData = [
'This is some serious data part 2',
'This is some serious data part 3',
'This is some serious data part 4',
];
const loopIt = (data) => {
let item = '';
for (let i = 0; i < data.length; i ) {
item = `<li>${data[i]}<button class='testBtn'>Remove ${i}</button></li>`;
}
return item;
}
let getHtml = () => {
domElem.selector.innerHTML = loopIt(someData);
}
const clickEvents = () => {
domElem.button.addEventListener ('click', function () {
let inputData = domElem.input.value;
if (inputData.length > 0) {
someData.push(inputData);
} else {
alert('no input');
}
getHtml();
});
domElem.buttonRemove.addEventListener ('click', function () {
someData.pop();
getHtml();
});
}
const removeArrayItem = () => {
let queryS = document.querySelectorAll('.testBtn');
for (let i = 0; i < queryS.length; i ) {
let index = queryS[i];
index.addEventListener('click', function () {
alert(i);
someData.splice(i, 1);
console.log(someData);
getHtml();
});
};
}
const init = () => {
getHtml();
elemAttributes();
clickEvents();
removeArrayItem();
}
let initialise = init();
Мой removeArrayItem
- 1 — запрос к dom
(let queryS = document.querySelectorAll('.testBtn');)
- 2 — цикл по массиву, возвращающий значение индекса (i)
(Loop function)
- 3 — добавление прослушивателя событий к каждому элементу в массиве
- 4 — удаление элемента массива (метод сращивания) —
- 5 — обновление пользовательского интерфейса (функция getHtml());
Но что-то где-то идет не так? поскольку пользовательский интерфейс не обновляется после первого щелчка.
Если я нажимаю элементы, я не могу удалить их по щелчку.
Комментарии:
1. как HTML связан с массивом someData? можете ли вы опубликовать рабочий пример?
Ответ №1:
Это связано с тем, что вы сбрасываете innerHTML
местоположение ваших кнопок. Это означает, что все привязки к прослушивателям событий исчезли. Таким образом, вам придется либо сбрасывать прослушиватели событий каждый раз, когда ваш HTML повторно отображается, либо использовать делегирование событий.
Делегирование событий имеет один прослушиватель событий, который прослушивает всплывающие события. Например: вы нажимаете свою кнопку, событие щелчка всплывает в DOM и достигает элемента, в котором вы прослушиваете событие. Оттуда вы можете определить, какой элемент был нажат и что делать дальше. Преимущество этого метода заключается в том, что дочерние элементы в этом элементе, который вы прослушиваете, могут быть динамическими, поэтому добавляются, перемещаются, удаляются и изменяются без необходимости учитывать это.
В вашей loopIt
функции передайте i
индекс атрибуту в кнопке. Вы больше не собираетесь прослушивать нажатие на саму кнопку, поэтому она должна содержать немного данных для обработки прослушивателем событий. value
Атрибут идеально подходит для этой цели.
const loopIt = (data) => {
let item = '';
for (let i = 0; i < data.length; i ) { // Right here ↓
item = `<li>${data[i]}<button class="testBtn" value="${i}">Remove ${i}</button></li>`;
}
return item;
}
Кнопка теперь знает индекс индекса массива, который необходимо сращивать при каждом нажатии кнопки.
Измените removeArrayItem
функцию. Вместо прослушивания щелчка по каждой кнопке, прослушайте событие щелчка по родительскому элементу, которое, я думаю, есть domElem.selector
?
const removeArrayItem = () => {
domElem.selector.addEventListener('click', function(event) {
const clickedElem = event.target; // This is the element that fired the click.
if (clickedElem.classList.contains('testBtn')) {
const index = clickedElem.value // The index in the array.
someData.splice(index, 1); // Splice array.
getHtml(); // Re-render the HTML.
}
});
}
Это добавляет один прослушиватель событий и получает Event
объект для target
, который является элементом, который вызвал событие щелчка. Затем он проверяет, есть ли у него класс, содержащий testBtn
класс. Если это произойдет, он получает i
индекс из value
атрибута, объединяет массив и повторно отображает HTML.
Попробуйте. Ваши клики должны работать каждый раз.
Комментарии:
1. Спасибо, это было хорошо объяснено и дало мне представление о том, что нужно изучить подробнее
Ответ №2:
Я бы подошел к этой задаче, найдя элемент и удалив элемент в массиве, после удаления я бы очистил innerHTML и перестроил пользовательский интерфейс на основе нового массива, как вы описали.
Мое кодовое решение будет выглядеть так:
Здесь я назначаю каждый элемент через свойство onClick . Я создал метод с именем removeItem и передал параметр, который отвечает на элемент в массиве.
Затем метод removeItem может удалить данный элемент, а затем быстро перестроить пользовательский интерфейс.
let someData = [
'This is some serious data part 2',
'This is some serious data part 3',
'This is some serious data part 4'
];
const loopIt = (data) => {
let item = '';
for (let i = 0; i < data.length; i ) {
item = `<li>${data[i]}<button onClick='removeItem(${i})'class='testBtn'>Remove ${i}</button></li>`;
}
return item;
};
let removeItem = (index) => {
someData.splice(index, 1);
getHtml();
};
let getHtml = () => {
domElem.innerHTML = '';
domElem.innerHTML = loopIt(someData);
};
const init = () => {
getHtml();
};
let initialise = init();