The expected behavior is for the user to be able to style all three elements individually.
How it works:
- When each element is clicked, it is stored in selected.elements
- When "Bold/Italic" are clicked, it is stored in selected.settings
- When "Apply" is clicked, the DOM is updated using the elements & settings in the "selected" object, and selected.elements is cleared
Steps to reproduce:
- Click "elementOne"
- Select "Bold"
- Click "Apply"
- Click "elementTwo"
- Select "Italic"
- Click "Apply"
Expected: elementOne is Bold; elementTwo is Italic
Actual: Both are Italic
At Step 5, model.elementOne.settings is updated even though there is no function called to do that.
const selected = {
elements: [],
settings: {}
}
const model = {
elementOne: {
slug: 'elementOne',
settings: {}
},
elementTwo: {
slug: 'elementTwo',
settings: {}
},
elementThree: {
slug: 'elementThree',
settings: {}
}
}
const elementContainer = document.getElementById('elementContainer')
const buttonContainer = document.getElementById('buttonContainer')
const fontStyleContainer = document.getElementById('fontStyleButtonContainer')
const setupEventListeners = _ => {
elementContainer.addEventListener('click', e => {
// add the selected element to selected.elements
selected.elements.push(e.target.id)
})
fontStyleContainer.addEventListener('click', e => {
// add the selected font style to the selected.settings
for (let i = 0; i < selected.elements.length; i++) {
if (e.target.hasAttribute('data-bold')) {
selected.settings.fontStyle = 'bold'
} else if (e.target.hasAttribute('data-italic')) {
selected.settings.fontStyle = 'italic'
}
}
})
buttonContainer.addEventListener('click', e => {
// update the model for each selected element using the selected settings
for (let i = 0; i < selected.elements.length; i++) {
model[selected.elements[i]].settings = selected.settings
}
// update the DOM based on the new model
updateDOMFromModel()
// reset the selected elements & settings
selected.elements.length = 0
})
}
const updateDOMFromModel = _ => {
// update the DOM based on the new model
for (const el in model) {
if (model.hasOwnProperty(el)) {
const element = model[el]
const elementDOM = document.getElementById(element.slug)
switch (element.settings.fontStyle) {
case 'bold':
elementDOM.style = 'font-weight: 800;'
break
case 'italic':
elementDOM.style = 'font-style: italic;'
break
default:
}
}
}
}
setupEventListeners()
<body>
<div id="elementContainer" style="cursor: pointer;">
<p>1. Select an element to style</p>
<ul>
<li id="elementOne">elementOne</li>
<li id="elementTwo">elementTwo</li>
<li id="elementThree">elementThree</li>
</ul>
</div>
<div id="fontStyleButtonContainer" style="cursor: pointer;">
<p>2. Select a font style</p>
<div id="fontStyleButton" data-bold>Bold</div>
<div id="fontStyleButton" data-italic>Italic</div>
</div>
<div id="buttonContainer" style="cursor: pointer;">
<p>3. Apply changes</p>
<button id="btnApply">Apply</button>
</div>
</body>