Build a Storytelling App - Step 16

Tell us what’s happening:

  1. When you click the scaryStoryBtn, the #result paragraph should display the scary story “In the dark woods, a group of friends stumbled upon an old, abandoned cabin. They enter the cabin and awaken something malevolent that had been dormant for centuries.” with a border color of #ee4b2b.
  2. When you click the funnyStoryBtn, the #result paragraph should display the funny story with a border color of #f1be32.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Storytelling App</title>
    <link rel="stylesheet" href="./styles.css" />
</head>

<body>

    <h1>Want to hear a short story?</h1>

    <main class="story-container">
        <div class="btn-container">
            <button class="btn" id="scary-btn">Scary Story</button>
            <button class="btn" id="funny-btn">Funny Story</button>
            <button class="btn" id="adventure-btn">Adventure Story</button>
        </div>
        <p id="result"></p>
    </main>
    <script src="./script.js"></script>

</body>

</html>
/* file: script.js */
const storyContainer = document.querySelector(".story-container");

const scaryStoryBtn = document.getElementById("scary-btn");
const funnyStoryBtn = document.getElementById("funny-btn");
const adventureStoryBtn = document.getElementById("adventure-btn");

const resultParagraph = document.getElementById("result");

const storyObj = {
  scary: {
    story: `In the dark woods, a group of friends stumbled upon an old, abandoned cabin. They enter the cabin and awaken something malevolent that had been dormant for centuries.`,
    borderColor: "#ee4b2b",
},
  funny: {
    story: `During a camping trip, Mark decided to show off his culinary skills by cooking dinner over an open fire. However, his attempt caused him to burn the dinner as well as his eyebrows off.`,
    borderColor: "#f1be32",
  },
  adventure: {
    story: `Lost in the heart of the Amazon rain forest, Sarah and Jake stumbled upon an ancient temple. They braved deadly traps and encountered strange wildlife, all while deciphering cryptic clues left behind by a mysterious civilization.`,
    borderColor: "#acd157"
  },
};

function displayStory(genre) {
  if (storyObj.hasOwnProperty(genre)) {
    resultParagraph.textContent = storyObj[genre].story;
    storyContainer.style.borderColor = storyObj[genre].borderColor;
  }
}


// User Editable Region


scaryStoryBtn.addEventListener("click", displayStory("scary"));
funnyStoryBtn.addEventListener("click", displayStory("funny"));
adventureStoryBtn.addEventListener("click", displayStory("adventure"));


// User Editable Region


/* file: styles.css */
*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --dark-grey: #1b1b32;
    --black: #000;
    --white: #fff;
    --golden-yellow: #fecc4c;
    --yellow: #ffcc4c;
    --gold: #feac32;
    --orange: #ffac33;
    --dark-orange: #f89808;
}

body {
    background-color: var(--dark-grey);
    color: var(--white);
}

h1,
#result {
    text-align: center;
}

h1 {
    margin: 10px 0 15px;
}

.story-container {
    margin: auto;
    padding: 10px;
    width: 80%;
    border-style: double;
    border-width: 14px;
    border-color: var(--white);
}

.btn-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

@media (min-width: 760px) {
    .btn-container {
        flex-direction: row;
    }
}

#result {
    margin-top: 15px;
    font-size: 1.2rem;
    line-height: 30px;
}

.btn {
    cursor: pointer;
    width: 200px;
    margin: 10px 0 10px 0.5rem;
    color: var(--black);
    background-color: var(--gold);
    background-image: linear-gradient(var(--golden-yellow), var(--orange));
    border-color: var(--gold);
    border-width: 3px;
}

.btn:hover {
    background-image: linear-gradient(var(--yellow), var(--dark-orange));
}

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36

Challenge Information:

Build a Storytelling App - Step 16

That will cause the displayStory function to execute immediately when the page loads.
(you will notice the adventure story is displayed and clicking any button has no change)

Because using the function name followed by parentheses () or ("funny") if the function takes arguments, means that you want to execute that function.

Since the function doesn’t return anything, it will return undefined.

As a result, once the page has loaded, the code becomes:

scaryStoryBtn.addEventListener("click", undefined);
funnyStoryBtn.addEventListener("click", undefined);
adventureStoryBtn.addEventListener("click", undefined);

Think of a way that you pass a function as the event handler instead of executing it immediately.

See MDN Examples.

Not sure if the MDN page has an example of passing arguments, but you can wrap the function call.

function log(message) {
  console.log(message);
}

document.documentElement.addEventListener("click", () => log("Hello"));

You can also pass the event if you need it.

function setColor(evt, color) {
  evt.target.style.backgroundColor = color;
}

document.documentElement.addEventListener("click", (evt) =>
  setColor(evt, "green")
);

document.documentElement.addEventListener("dblclick", (evt) =>
  setColor(evt, "red")
);

Hi there, following this as had the same issue.

I’m really confused by this. Could you please explain a little more about why the function would be executed immediately if it comes after the event listener?

if the code reads:

scaryStoryBtn.addEventListener(“click”, displayStory(“scary”);

I don’t get why it wouldn’t do things in order of adding the listener, and then triggering it if it receives the click…

Because addEventListener expects the second argument to be a reference to a function that should execute on click.

function sayHi(name) {
  console.log(`Hi, ${name}`);
}

If you want to execute this function, you basically do sayHi("chrisbabes").

That’s execution, but what if you want to tell addEventListener like,
Hey, you see this function? You should execute it if there is a click.

Then you can’t do sayHi("chrisbabes"), since that’s a direct order of you to execute it immediately.

To pass a reference to a function, you just pass its name, like sayHi.

Here comes the problem: this function expects to receive an argument.
That’s what @lasjorg mentioned, to use an anonymous function.

You can see this specific example in the previous link I posted, you can read all the page if you want.