简体   繁体   中英

Is there a better way than this to create a toggle function just with JavaScript (no JQuery at all)?

I have a nav bar in the form of a ul with several li elements and with the last li (named 'more') having its own sub-menu in the form of another ul. I was trying (and was successful) in making it so that the sub-menu's original state is visibility:visible; and then when the user clicks on li name 'more' it would toggle between visibility: visible; and visibility: hidden; I used JavaScript and a counter with an if statement. The reason why I used the counter was because when I tried:

if(document.querySelector('#subMenu').style.visibility == "hidden")...;

But it wouldn't toggle.

My questions are:

  1. Would this method of creating the toggle function be deemed acceptable in a professional front end developer workplace?

  2. Is there a better way to toggle between visible and hidden on clicking an element using JavaScript ONLY (trying to get better at JavaScript)?

The code is as follows(I have only included the relevant code):

HTML

<ol id = "leftNav" class = "bothNavs">
    <li class = "navs" id = "more">More<div class = "arrow"></div>
        <ul class = "subMenu">
            <li>One</li>
            <li>Two</li>
            <li>Three</li>
        </ul>
    </li>
</ol>

CSS

.subMenu {
    width: 160%;
    padding: 5px 0px;
    padding-left: 7px;
    margin-left: 6px;
    position:  absolute;
    top: 100%;
    left:0px;
    visibility: hidden;
    box-shadow: 0px 2px 3px rgba(0,0,0,0.2);
    background: #2D2D2D;
    list-style: outside none none;
    z-index: 1001;
}

JavaScript

var more = document.querySelector('#more');
var subMenu = document.querySelector('.subMenu');
var counter =0;

more.addEventListener("click", toggle);

function toggle () {
    if(counter === 0){
        subMenu.style.visibility = "visible";
        counter += 1;
    } else {
        subMenu.style.visibility = "hidden";
        counter -= 1;
    }
};

Thank you in advance for your answers.

I feel a better way of toggling visibility (or any style) is to toggle a class.

Consider something like this in your CSS:

.subMenu.is-visible {
    visibility: visible;
}

Then your function just needs to look like this:

var menu = document.querySelector('.subMenu');
document.getElementById('more').addEventListener('click', function () {
    menu.classList.toggle('is-visible');
}, false);

For a toggle you should use a boolean value rather than int:

 var more = document.querySelector('#more'); var subMenu = document.querySelector('.subMenu'); var clicked = false; more.addEventListener("click", function(evt) { // This is called a ternary operator, it's basically // a really simple if/else statement subMenu.style.visibility = (clicked) ? "visible " : "hidden"; // This will set clicked to the opposite (not) value of what // it currently is. Being that we're using a boolean // it will toggle true/false clicked = !clicked; }); 

You should also read (and vote for) this - What is the difference between visibility:hidden and display:none?

You should not embed a <ul> inside a <li> element. There's all sorts of reasons why, but mostly it messes with the hierarchy and makes the HTML less meaningful.

Also the last time I had to tackle this problem it ended up looking something like this:

var subMenu = document.querySelector('.subMenu');
if (clicked) {
    subMenu.style.visibility = "visible";
} else {
    subMenu.style.visibility = "hidden";
}

Consider making it id instead of class incase you have other submenus it interferes with.

If you don't really need a counter, use a boolean:

 var more = document.querySelector('#more'); var subMenu = document.querySelector('.subMenu'); more.addEventListener("click", toggle); function toggle () { subMenu.style.visibility = subMenu.style.visibility != "hidden" ? "hidden" : "visible"; }; 
 .subMenu { width: 60%; background: #2D2D2D; list-style: outside none none; color: white } 
 <ol id = "leftNav" class = "bothNavs"> <li class = "navs" id = "more">More<div class = "arrow"></div> <ul class = "subMenu" style="visibility: hidden"> <li>One</li> <li>Two</li> <li>Three</li> </ul> </li> </ol> 

Ideally, you'd modify this code to toggle a class instead of an inline CSS style, as James suggested in his answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM