Welcome back! If you've been following along, we've already solved challenges of Days 1 to 18 in our journey. Now, buckle up as we dive into the last leg of this adventure of Days 19 to 24.
Day 19: Debug Jingle Words
Task
- There are loads of problems in JS. Find them, and fix them!
function handleGuess(e) {
e.preventDefault()
let currentState = []
let input = document.getElementById('user-input')
let guess = input.value
const guessArr = guess.split('')
for (let i = 0; i < wordArr.length; i++) {
if (guessArr[i] === wordArr[i]) {
currentState.push(guessArr[i])
} else {
currentState.push("-")
}
}
renderGuess(currentState)
checkWin(guess)
input.value = ''
}
The problems causing the errors were:
- The
idof the input was incorrect. - Instead of using
guess.split(' '), it was necessary to useguess.split('')to split the string into individual letters. - Implemented a
forloop to iterate through each letter of both theguessandwordArr. - Finally, when a letter is matched, it is pushed; otherwise, ('-') is pushed.
function renderGuess(arr) {
const wordHtml = arr.map((letter) => {
let html = ""
if (letter === "-") {
html += `<span class="letter wrong">-</span>`
} else {
html += `<span class="letter correct">${letter}</span>`
}
return html
})
wordDisplay.innerHTML = wordHtml.join('')
}
I have also updated the renderGuess function to provide users with a visual clue indicating whether the letter is correct or not.
Check my scrim here.
Day 20: Save Santa!
Task
- Save Santa by removing the lions, tigers, bears, and other nefarious creatures from the deeply-nested array. Following is the input.
const dangerArray = [
["π
", "πΊ"],
[
["π
", "π¦"],
["πΉ", "π
"]
],
[
[
["π
", "π»"],
["π§", "π
"]
],
[
["π―", "π
"],
["π
", "π"]
]
]
];
function saveSanta(arr) {
for(let i=0; i<arr.length; i++ ){
if(Array.isArray(arr[i])){
saveSanta(arr[i])
}
else{
if(arr[i]!=="π
"){
arr.splice(i, 1)
}
}
}
return arr
}
console.log(saveSanta(dangerArray))
- First we iterate over the array and check if each item is an array.
- If it is, a recursive call to the current function is made.
- Otherwise, we check if the item is not Santa.
- If it isn't, the item is sliced from the array.
Check my scrim here.
Day 21: Expanding Search Bar
Task
ο»ΏSearch input: Takes upto 1/3 of the width of its container
-
When the user clicks into the search bar:
- Input grows to entire width of its parent container with smooth transition
- Shrinks back to original size when user clicks away
- Blue border
- Bonus: placeholder text is not visible when user clicks inside the search bar
<div class="container">
<label for="search-field" class="visually-hidden">Search</label>
<input type="search"
class="search-bar"
id="search-field"
placeholder="Search..."/>
</div>
html, body {
margin: 0;
padding: 0;
}
:root {
--search-border: #bbb;
--search-focus-border: #3a71ca;
}
.visually-hidden {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0,0,0,0) !important;
white-space: nowrap !important;
border: 0 !important;
}
.container{
width: 80%;
margin: 30px auto 0;
}
.search-bar{
border: 1px solid var(--search-border);
border-radius: 4px;
padding: 8px;
width: 30%;
transition: width .2s linear;
}
.search-bar:focus{
width: 100%;
border-color: var(--search-focus-border);
}
.search-bar:focus::-webkit-input-placeholder {
opacity: 0;
}
.search-bar:focus::-moz-placeholder {
opacity: 0;
}
.search-bar:focus:-ms-input-placeholder {
opacity: 0;
}
.search-bar:focus:-moz-placeholder {
opacity: 0;
}
The trick here is that we initially set the width of .search-bar to 30% of its parent container. When clicked, we utilize the :focus selector to dynamically adjust the width to 100%, employing a transition effect for a smooth visual transition. To hide the placeholder text, browser-specific placeholder selectors are used, and a style of opacity: 0; is applied.
Check my scrim here.
Day 22: Gift App
Task
- Make it so that the data doesn't disappear on reload. Use localStorage.
let people = JSON.parse(localStorage.getItem("people")) || []
if(people) renderList(people)
addButtonEl.addEventListener("click", function() {
let inputValue = inputFieldEl.value
if (inputValue) {
people.push(inputValue)
localStorage.setItem("people", JSON.stringify(people))
clearInputFieldEl()
renderList(people)
}
})
function appendPersonToPeopleListEl(person) {
let newEl = document.createElement("li")
newEl.textContent = person
newEl.addEventListener("dblclick", function() {
let index = people.indexOf(person)
people.splice(index, 1)
localStorage.setItem("people", JSON.stringify(people))
img.src = "./images/gifts.webp"
renderList(people)
})
peopleListEl.append(newEl)
}
- When a new person is added to our Gift App list, we use
localStorage.setItem("people", JSON.stringify(people))to store the people array with the key named "people" in localStorage. Thestringifyfunction is used to convert a JavaScript object (in this case, the people array) into a JSON-formatted string. - The object is similarly updated when a person is removed from the list.
- Lastly, to retrieve the data, we use
JSON.parse(localStorage.getItem("people")). Theparsefunction is used to convert a JSON-formatted string back into a JavaScript object.
Check my scrim here.
Day 23: Toggle Switch
Task
- On click, toggle switch moves from one side to another
- Cursor becomes pointer
- Match styles
- No JavaScript
<div class="toggle-wrap">
<label for="toggle">
<input type="checkbox" id="toggle" class="toggle-input"></input>
<div class="toggle-switch"></div>
</label>
</div>
#toggle{
display: none;
}
.toggle-wrap{
width: 80px;
height: 40px;
border: 2px solid var(--toggle-border);
border-radius: 100px;
background: var(--toggle-bg);
display: flex;
align-items: center;
}
label{
width: 100%;
cursor: pointer;
}
.toggle-switch{
width: 30px;
height: 30px;
border-radius: 50%;
background: var(--toggle-switch-bg);
transition: transform 0.2s linear;
backface-visibility: hidden;
}
.toggle-input:checked + .toggle-switch{
transform: translateX(45px);
}
.toggle-input:not(:checked) + .toggle-switch{
transform: translateX(5px);
}
- Here, we hide the actual checkbox, but since we use the
idandforattributes in both the label and input, we can determine whether it is checked or not. - We utilize the
:checkedselector and a combination selector to shift the slide to the right side. - To check if it is unchecked, we use
:not()selector in combination with:checkedand translate the position to its initial state. - The transition property is used to ensure a smooth animation.
Check my scrim here.
Day 24: Christmas Lights
Task
- Make Christmas tree lights flash on and off every 800 milliseconds on a permanent loop.
- Make the blue and red lights toggle on and off alternatively. So first the red lights come on, and then as they go off, the blue lights come on.
const blues = document.querySelectorAll('.blue');
const reds = document.querySelectorAll('.red');
let isRed = true;
function toggleLights() {
if (isRed) {
reds.forEach(redLight => {
redLight.classList.add("lights-on");
});
blues.forEach(blueLight => {
blueLight.classList.remove("lights-on");
});
} else {
blues.forEach(blueLight => {
blueLight.classList.add("lights-on");
});
reds.forEach(redLight => {
redLight.classList.remove("lights-on");
});
}
isRed = !isRed;
}
setInterval(toggleLights, 800);
- We use
setInterval(toggleLights, 800);to call thetoggleLightsfunction every 800 milliseconds. - In the function, we check if
isRedis true. If it is, we add thelights-onclass to the red lights and remove it from the blue lights. - Otherwise, we add the
lights-onclass to the blue lights and remove it from the red lights.
Check my scrim here.
As we finish up the 24-day coding adventure of #JavaScriptmas, I can't help but smile thinking about how much fun it brought to my daily routine. Solving a new challenge each day became something I looked forward to, keeping me consistent and excited.
I want to say a big thank you to everyone who followed along and joined me in this coding journey. Your support and enthusiasm made it even better!
Thanks for being a part of it. Until next time, happy coding!

Top comments (0)