samedi 18 août 2018

IF/Else condition has no effect on addEventListener/removeEventListener

As a beginner, I am out of my depth on even the seemingly simplest things, but maybe I'm aiming too high for only just having started to learn a few weeks ago. I am trying to stick to just HTML, CSS and vanilla Javascript so that I don't have to initially learn the syntax of other frameworks on top of the basics. I have tried to cobble together snippets of solutions from what I've learned at w3, here, etc, however, I don't pretend to fully understand what I'm reading and using.

I need to have a simple, vertical menu as shown below. Currently, and likely only ever, one item ("Portfolio") in the main menu will have sub-menu items. The sub-menu's appearance and functionality depends on the width of the window:

  • A wide window is supposed to allow a hover event on "Portfolio" to just display the sub-menu items to the right of the main menu, without pushing down the other menu items.
  • A narrow window is supposed to enable/watch for a 'click' event on the Portfolio LI, and when triggered it should push down the other menu items and display the sub-menu items in block format directly below "Portfolio".
  • The triangle/arrowhead is supposed to automatically switched to pointing to the right when the window is wide, and it is supposed to automatically switch to pointing up or down if the window is narrow, depending on whether the sub-menu is showing or not (down if not showing, and up if it is showing).
  • A click on any item in the sub-menu is supposed to collapse the sub-menu and flip the arrowhead to point downwards again.

However, there are 'bugs' that I just can't figure out.

  1. I had the hover event working using CSS, but then it stopped working as soon as I introduced any Javascript code to allow for the click event. So I abandoned the CSS approach, and can't even remember if I ever got the wide window/hover feature working again.
  2. Using Javascript, I have the click event sort of working, but several things are wrong.
    • When the window is narrow, for some reason it takes TWO clicks on "Portfolio" to flip the arrowhead to point upwards and display the sub-menu. The first click just flips the arrowhead from down to up, and then the second click displays the sub-menu. Both things should happen with just one click.
    • Once the addEventListener has triggered for the click on Portfolio (in a narrow window), if the window ever returns to being wide, the removeEventListener seems to do nothing and the menu continues to work as if the window was narrow. When the window is wide, I want the menu to go back to having the hover event for "Portfolio"; I don't want the click event enabled when the window is wide.

I have provided what code I have, and I've put it in one document rather than separate CSS and Javascript. (I hope I've formatted the code properly.)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">

</head>

<style media="screen">
body{
  background-color: black;
}

nav ul {
    position: relative;
    text-align: left;
}

nav ul li {
    display: block;  /* WHAT????  REMOVING THIS ACTUALLY MAKES TEXT-DECORATIONS REAPPEAR.... WHY???*/
}

nav a {
    text-decoration: none;
}

/* Hide dropdowns by default */
nav ul ul {
    position: relative;
  display: none;
  left: 0;
}

/* Display Dropdowns on Click */
nav ul li.showSubmenu > ul {
    display: block;
    position: relative;
    width: 30%;
}

.menu a {
    text-decoration-style: none;
    text-decoration: none;
    background-color: black;
    color: white;
}

.menu a:hover{
    background-color: white;
    color: black;
}

</style>

<body>

<nav class="menu">
    <ul>
        <li class="menuItem"><a href="#">Home</a></li>
        <li class="menuItem"><a href="#">About</a></li>
        <li class="submenu_class"><a href="#"><span id="submenuID">Portfolio ▼</span></a>
            <ul>
                 <li><a href="#">Landscape</a></li>
                 <li><a href="#">Architecture</a></li>
                 <li><a href="#">Animal</a></li>
                 <li><a href="#">Other</a></li>
            </ul>
        </li>
        <li class="menuItem"><a href="#">Information</a></li>
        <li class="menuItem"><a href="#">Contact</a></li>
    </ul>
  </nav>


<script>
    function openSubmenu() {
        this.setAttribute('class','submenu_class showSubmenu');
        document.getElementById("submenuID").textContent = "Portfolio ▲";
        this.onclick = resetSubmenus;
    }

    function resetSubmenus() {
        var submenuElements = document.getElementsByClassName('submenu_class');
        for (var i = 0; i < submenuElements.length; i++) {
            submenuElements[i].setAttribute('class','submenu_class');
            submenuElements[i].onclick = openSubmenu;
            document.getElementById("submenuID").textContent = "Portfolio ▼";
        }
    }

    function screenWidthFunction(x) {
        if (x.matches) {//if it's a narrow screen
            document.getElementById("submenuID").textContent = "Portfolio ▼";
            document.getElementById("submenuID").addEventListener("click", openSubmenu);
        } else {
            document.getElementById("submenuID").textContent = "Portfolio ►";
            document.getElementById("submenuID").removeEventListener("click", openSubmenu);
        }
    }

  var x = window.matchMedia("(max-width: 480px)")
  screenWidthFunction(x) // Call listener function at run time
  x.addListener(screenWidthFunction) // Attach listener function on state changes
</script>

Aucun commentaire:

Enregistrer un commentaire