<h3>Todos:</h3>
<ul id="list1"></ul>
<hr />
<button id="btn1">+ Add new item</button>
// This the initial state of the app
const todos = [
'buy milk',
'clean kitchen',
'learn js',
]
// This helper function will "render" a new
// DOM item into an HTML list
const appendItem = (item) => {
const el = document.createElement('li')
const elText = document.createTextNode(item)
el.appendChild(elText)
document.getElementById('list1').appendChild(el)
}
// Yes, DOM APIs often return arrays that
// you can loop through!
// And arrow functions let us write a very
// simple and readable piece of code!
const clearList = () =>
document
.querySelectorAll('#list1 *')
.forEach(item => item.remove())
// This is the main rendering logic, it is
// often a simple 2 steps operation:
// 1. cleanup
// 2. re-create everything
const renderList = () => {
clearList()
todos.forEach(appendItem)
}
// Here we write the logic to apply when
// the "Add new item" is pressed:
const addNewItem = () => {
/**
* SOLUTION!
* this is where we actually make the
* change to the state of our app. It's
* clean and simple thanks to the
* Array APIs!
*/
todos.push(`Item n.${todos.length + 1}`)
/**
* Once the data is changes, we simply
* call the methos that translates data
* into DOM.
*
* This concept is the foundation of
* every modern framework such Vue or
* React.
*
* We work so to keep our data
* up-to-date, then we use the frameworks
* to simply "translate"
* our data into DOM elements for the
* browser.
*/
renderList()
}
// Associate the logic to the user action
document
.querySelector('#btn1')
.addEventListener('click', addNewItem)
// As soon the app starts, we run the first
// rendering so to show the initial state.
renderList()
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.