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
id
of the input was incorrect. - Instead of using
guess.split(' ')
, it was necessary to useguess.split('')
to split the string into individual letters. - Implemented a
for
loop to iterate through each letter of both theguess
andwordArr
. - 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. Thestringify
function 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"))
. Theparse
function 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
id
andfor
attributes in both the label and input, we can determine whether it is checked or not. - We utilize the
:checked
selector 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:checked
and 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 thetoggleLights
function every 800 milliseconds. - In the function, we check if
isRed
is true. If it is, we add thelights-on
class to the red lights and remove it from the blue lights. - Otherwise, we add the
lights-on
class 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)