I am having trouble figuring out how to get the innerHTML to change the displayed text based on the hunger rating. Below is the JS that I used to build the hunger tracker. At the very bottom is the function to drop in the innerHTML, and I’ve tried all of the different variables to try and get it to work. I have also tried dropping in the text as an array, using blood.forEach, but that didn’t work either.
document.addEventListener("DOMContentLoaded", function (event) {
// copy code here
const makeHungerRating = function (noOfBlood = 5) {
let rating = 0;
let bloodComponent;
function changeHunger(newRating) {
rating = newRating;
}
function getBloodComponent() {
if (!bloodComponent) {
bloodComponent = document.createElement(`ul`);
bloodComponent.className = `hunger-rating`;
for (let i = 0; i < noOfBlood; i++) {
const li = document.createElement(`li`);
li.setAttribute(`data-rating`, i + 1)
li.className = `blood`;
if (i === 0) li.tabIndex = 0;
bloodComponent.append(li);
}
bloodComponent.addEventListener(`mouseover`, onMouseOver);
bloodComponent.addEventListener(`mouseLeave`, onMouseLeave);
bloodComponent.addEventListener(`click`, onMouseClick);
bloodComponent.addEventListener(`keyup`, onKeyUp)
}
return bloodComponent;
}
function renderChanges(rating) {
for (let i = 0; i < rating; ++i) {
bloodComponent.children[i].classList.add(`blood-filled`);
}
for (let i = rating; i < noOfBlood; ++i) {
bloodComponent.children[i].classList.remove(`blood-filled`);
}
}
function onMouseOver(e) {
let isBlood = e.target.classList.contains(`blood`);
if (isBlood) {
const { rating } = e.target.dataset;
renderChanges(rating)
}
}
function onMouseLeave(e) {
renderChanges(rating);
}
function onMouseClick(e) {
let blood = e.target ?? e;
let isBlood = blood.classList.contains(`blood`);
if (isBlood) {
activate(blood)
let { rating } = blood.dataset;
if (e.key !== `Tab` && rating === getRating()) {
rating = 0;
resetTabIndex();
bloodComponent.firstElementChild.tabIndex = 0;
}
changeHunger(rating);
renderChanges(rating);
}
}
function focusPrevBlood() {
let focusedBlood = document.activeElement;
if (focusedBlood.previousElementSibling) {
onMouseClick(focusedBlood.previousElementSibling);
}
}
function focusNextBlood() {
let focusedBlood = document.activeElement;
if (focusedBlood.nextElementSibling) {
onMouseClick(focusedBlood.nextElementSibling);
}
}
function activate(element) {
resetTabIndex();
element.tabIndex = 0;
element.focus();
}
function resetTabIndex() {
bloodComponent.childNodes.forEach((blood) => {
blood.tabIndex = -1;
})
}
function onKeyUp(e) {
switch (e.key) {
case `Tab`: {
onMouseClick(e);
break;
}
case `ArrowLeft`: {
focusPrevBlood()
break;
}
case `ArrowRight`: {
focusNextBlood();
break;
}
default:
return;
}
}
function getRating() {
return rating;
}
return { getRating, getBloodComponent };
}
const ratingModule = makeHungerRating();
const bloodComponent = ratingModule.getBloodComponent();
const container = document.querySelector("ul");
container.append(bloodComponent);
const ratingText = document.querySelector(".hunger__level--description")
ratingText.innerHTML = getRatingTextHTML(container)
function getRatingTextHTML(ratingModule) {
let hunger = ratingModule
if (hunger = 0) {
return `<div class="hunger__level--description">"I sleep, for now. You have satisfied me... but never forget, I am always here. Enjoy your peace, little one - it never lasts."</div>
</div>`
}
else if (hunger = 1) {
return `<div class="hunger__level--description">"I feel the pull again. Just a taste... you can manage that, can't you? Just enough to remind me that you know what I need"</div>
</div>`
}
else if (hunger = 2) {
return `<div class="hunger__level--description">"You're making me wait too long. Don't you feel it? That ache in your veins... I do. It's time. Find them. Feed. I won't ask nicely again."</div>
</div>`
}
else if (hunger = 3) {
return `<div class="hunger__level--description">"I'm starving! Do you really think you can hold me back? I can smell them all around us, their warmth, their blood. I will have it, one way or another... you won't stop me!"</div>
</div>`
}
else if (hunger = 4) {
return `<div class="hunger__level--description">"ENOUGH! You're nothing without me! I will tear them apart! They're just cattle, waiting to be slaughtered, and you're a fool if you think you can resist me any longer! YOU. WILL. FEED!"</div>
</div>`
}
}
});
So I posted the JS above, and I will reiterate that I have tried targeting ratingModule, bloodComponent, container, blood, and I have run it as
blood.forEach [
"I sleep, for now. You have satisfied me... but never forget, I am always here. Enjoy your peace, little one - it never lasts.",
"I feel the pull again. Just a taste... you can manage that, can't you? Just enough to remind me that you know what I need",
"You're making me wait too long. Don't you feel it? That ache in your veins... I do. It's time. Find them. Feed. I won't ask nicely again."
"I'm starving! Do you really think you can hold me back? I can smell them all around us, their warmth, their blood. I will have it, one way or another... you won't stop me!"
"ENOUGH! You're nothing without me! I will tear them apart! They're just cattle, waiting to be slaughtered, and you're a fool if you think you can resist me any longer! YOU. WILL. FEED!"
]
But to be honest, I don’t know if I implemented that correctly. The idea is to get the text to appear underneath the Hunger Rating as I change it.
The HTML and CSS already gives the text status showing up under the Hunger Rating, but it doesn’t change when I click on the different ratings.
here is the codepen as well: https://codepen.io/rkbraniff/pen/ZEgWYbb