I'm building a personal website using Kirby CMS. I have a nav menu that automatically adds new buttons for any new pages I create for the website. I would like each button to have a background color that is randomly chosen from an array of colors every time you load the page.

I've been using the following code:

This is the snippet that loads the javascript and generates the buttons for navigation.

<html>
    <head>
            <title><?= $site->title()?></title>
            <meta name="viewport" content="width=device-width, initial-scale1.0">
            <meta  charset="UTF-8">
            <?= css('/assets/css/menu.css')?>
            <?= js('assets/js/script.js')?>
            <link rel="preconnect" href="https://fonts.googleapis.com">
            <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
            <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@500;700;900&display=swap" rel="stylesheet">
    </head>
    <body class="blog_content_container">
            <img class="background_overlay" src="<?= url('assets/svg/background_overlay.svg') ?>">
            <header class="header">
                    <nav class="menu">
                            <img class="logo_header" src="<?= url('assets/svg/logo.svg') ?>">
                            <?php foreach ($site->children()->listed() as $childpage): ?>
                                    <button class="menu_item">
                                            <a href="<?= $childpage->url()?>" class="menu_text" >
                                                    <?= $childpage->title() ?>
                                            </a>
                                    </button>
                            <?php endforeach ?>
                    </nav>
            </header>

This is the Javascript I have written that is supposed to pick colors from an array and apply it to the buttons.

window.onLoad = () => {
    var colors = ['#ffffff', '#ffbd4b', '#ff634b', '#4b9fff'];
    var random_color = colors[Math.floor(Math.random() * colors.length)];
    document.getElementsById('menu_item').style.backgroundColor = random_color;
};

Finally, this is the CSS that I have written.

.menu {
    grid-column: 2;
    grid-row: 1;
    display: flex;
    flex-flow: row wrap;
    align-items: center;
}

.menu_item {
    width: 150px;
    height: 50px;
    border: 6px solid #FFFFFF;
    border-radius: 6px;
    box-shadow: 4px 4px 6px rgba(0, 0, 0, 0.65);
    margin: 1rem;
    cursor: pointer;
}

.menu_item:hover {
    transform: scale(1.1);
}

.menu_text{
    font-family: 'nunito', sans-serif;
    font-size: 1.4rem;
    font-weight: 900;
    color: rgb(255, 255, 255);
    text-decoration: none;
}

Everything loads as expected without throwing errors, but no background colors apply to the buttons. I appreciate any help you can give, I'm a beginner so please be nice :)

1

There are 1 best solutions below

3
On

Since the question is way more complex then the few typos I will revert to an answer now instead of keeping an extented conversation within the comments.

First there are a few typos:

  1. getElementsById does not exsist. Naturally an id has to be unique and as such can onyl exsist once. So it has to be getElementById
  2. The above mentioned typo does not matetr in the first palce as it is a wrong call. The called element has a class with that name and not an id so querySelector should be chosen.
  3. onLoad actually causes an error and has to be written onload
  4. If you fix all those typos the script will actually work. However it will only apply to the first element with that class. To apply it to all Elements the querySelectorAll has to be used and be combined with forEach
  5. That will lead us to the next issue that. The random color will be for all elements the same unless we move the randomizer within the forEach function:

window.onload = () => {
  var colors = ['#ffffff', '#ffbd4b', '#ff634b', '#4b9fff'];
  document.querySelectorAll('.menu_item').forEach(
    el => el.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]);
};
/* for visualisation purpose only */
div {
  padding: 10px;
  text-align: center;
  margin-bottom: 5px;
  border: 2px dashed red;
}
<div class="menu_item">1</div>
<div class="menu_item">2</div>
<div class="menu_item">3</div>
<div class="menu_item">4</div>
<div class="menu_item">5</div>