#javascript
#javascript
Вопрос:
При установке флажка я пытаюсь создать поля div, а при снятии флажка удалить его динамически.
Я знаю, что с React я мог бы сделать это за 2 минуты, но я пытаюсь изучить ванильный JS-способ
Текущие проблемы, с которыми я сталкиваюсь:
- При установке флажка отображается больше элементов, чем один
- При снятии флажка, например, все элементы по-прежнему отображаются.
КОНЕЧНАЯ ЦЕЛЬ: динамически добавлять и удалять поля Div в зависимости от того, что находится в state
переменной ( console.log
чтобы ее вывод давал указания о том, как правильно она должна выглядеть), а также следить за тем, чтобы никакие дополнительные поля не использовались / не отображались.
window.onload = () => {
const checkbox = document.querySelectorAll('.checkbox')
let state = []
for (idx of checkbox) {
idx.addEventListener('change', (e) => {
if (e.currentTarget.checked === true) {
state.push(e.currentTarget.id)
renderOnDom(state, 'add', e.currentTarget.id) // Experimenting
}
if (e.currentTarget.checked === false) {
state = state.filter((item) => item !== e.currentTarget.id)
renderOnDom(state, 'remove', e.currentTarget.id) // Experimenting
}
console.log('state', state)
})
}
}
const renderOnDom = (el, option, id) => {
if (option === 'add') {
el.map((item, idx) => {
const div = document.createElement('div')
div.setAttribute('key', item)
div.className = 'test'
div.innerHTML = `Box ${item}`
document.querySelector('#projects').appendChild(div)
})
}
if (option === 'remove') {
const test = document.querySelectorAll('.test')
const prod = document.querySelector('#projects')
for (const iterator of test) {
if (iterator.attributes.key.value === id) {
prod.removeChild(prod.firstChild)
}
}
}
}
<input id="id1" data="name1" class="checkbox" type="checkbox" />
<label for="id1">Test 1</label>
<input id="id2" data="name2" class="checkbox" type="checkbox" />
<label for="id2">Test 2</label>
<input id="id3" data="name3" class="checkbox" type="checkbox" />
<label for="id3">Test 3</label>
<div id="projects"></div>
Комментарии:
1. «При установке флажка отображается больше элементов, чем один» — потому что вы добавляете каждый элемент в
state
2. ? мое состояние, которое
console.log
оно показывает правильно. Итак, если в состоянии есть 3 элемента, ему необходимо отобразить эти 3, но не дублировать их при рендеринге3.
el
является ли «состояние»el.map()
(которое, кстати, является неправильным инструментом, проверьте его документацию) перебирает все элементыel
и добавляет каждый элемент вel
/»state» в DOM (.createElement()
,.appendChild()
) .
Ответ №1:
Привет, я обновил ваш фрагмент, чтобы сделать то, что, как я думаю, вы хотите сделать.
В двух словах, источником истины является state
массив. Итак, после любых изменений в нем сбросьте dom с помощью resetDom()
, а затем запустите renderOnDom()
.
window.onload = () => {
const checkbox = document.querySelectorAll('.checkbox')
let state = []
for (idx of checkbox) {
idx.addEventListener('change', (e) => {
if (e.currentTarget.checked === true) {
state.push(e.currentTarget.id)
}
if (e.currentTarget.checked === false) {
state = state.filter((item) => item !== e.currentTarget.id)
}
renderOnDom(state, e.currentTarget.id)
})
}
}
const resetDom = () => {
const projects = document.querySelector("#projects");
while (projects.firstChild) {
projects.removeChild(projects.firstChild)
}
}
const renderOnDom = (el, id) => {
resetDom();
el.forEach((item, idx) => {
const div = document.createElement('div')
div.setAttribute('key', item)
div.className = 'test'
div.innerHTML = `Box ${item}`
document.querySelector('#projects').appendChild(div)
})
}
<input id="id1" data="name1" class="checkbox" type="checkbox" />
<label for="id1">Test 1</label>
<input id="id2" data="name2" class="checkbox" type="checkbox" />
<label for="id2">Test 2</label>
<input id="id3" data="name3" class="checkbox" type="checkbox" />
<label for="id3">Test 3</label>
<div id="projects"></div>
Комментарии:
1. Чувак, ты потрясающий
2. Спасибо @Marius: D и Андреас — да, поскольку мы ничего не возвращаем, forEach имеет больше смысла !!.
3. спасибо, Андреас, я так привык постоянно реагировать с помощью map