π Tabby: Event delegation
Previously, we listened for a click event on every tab.
const tabs = Array.from(document.querySelectorAll('.tab'))
tabs.forEach(tab => {
tab.addEventListener('click', _ => {
// ...
})
})
When you see this pattern, you know you can use event delegation.
When you use event delegation, you want to attach one event listener to the closest common ancestor that makes sense. In this case, this ancestor is .tabs.
<div class="tabs">
<button class="tab is-selected"> ... </button>
<button class="tab"> ... </button>
<button class="tab"> ... </button>
</div>
const tabby = document.querySelector('.tabby')
const tabsList = tabby.querySelector('.tabs')
tabList.addEventListener('click', event => {
// Do something
})
We have to follow the same steps as before. We need to:
Find the clicked tab
Find the corresponding tab content
Remove is-selected from other tabs to de-emphasize them
Add is-selected to the clicked tab to emphasize it
Remove is-selected from other tab content to hide them
Add is-selected to the corresponding tab-content to show it
Here, we can use event.target to find the clicked tab.
tabsList.addEventListener('click', event => {
const tab = event.target
console.log(tab)
})
Once we know the clicked tab, we can get the corresponding tab-content through the data-target attribute.
tabsList.addEventListener('click', event => {
const tab = event.target
const target = tab.dataset.target
const tabContent = tabby.querySelector('#' + target)
})
We remove is-selected from other tabs to de-emphasize them. We also add is-selected to the clicked tab to emphasize it.
// ...
const tabs = Array.from(tabby.querySelectorAll('.tab'))
tabsList.addEventListener('click', event => {
// ...
// Selects a tab
tabs.forEach(t => t.classList.remove('is-selected'))
tab.classList.add('is-selected')
})
Finally, we remove is-selected from other tab-content to hide them. We also add is-selected to the target tab-content to show it.
// ...
const tabContents = Array.from(tabby.querySelectorAll('.tab-content'))
tabsList.addEventListener('click', event => {
// ...
// Selects the corresponding tab content
tabContents.forEach(c => c.classList.remove('is-selected'))
tabContent.classList.add('is-selected')
})
Thatβs it!