简体   繁体   中英

Show / Hide Div on Click with JavaScript

Can't use jQuery or CSS (only). I have:

 function handleDropDown (elementId) { document.getElementById('languages').style.display = "block"; }
 .flag-icon-wrapper { margin-right: 20px; padding-top: 5px; }.flex { display: flex; }.flag-icon { width: 50px; }.is-hidden-initially { display: none; }
 <span class="flag-icon-wrapper flex" onClick='handleDropDown()'> <img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" /> </span> <div class="languages is-hidden-initially"> <ul> <li>Spanish</li> <li>French</li> <li>Russian</li> </ul> </div>

The idea is that when you click on the American flag, it should reveal a list of other languages (eventually to choose from). Eventually, when you click on another language, I'd like to show the flag that's associated with that language in the flag-icon-wrapper span, but for now, I just want to show or hide the languages div when you click on the flag.

At this point, I'm getting Uncaught TypeError: Cannot read property 'style' of null" - why? I'm getting the element by ID languages to display it as block - so why is that part not working? Thanks

EDIT It's now fixed by changing the class to an ID in the html:

<span class="flag-icon-wrapper flex" onClick='handleDropDown()'>
<img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" />
</span>

<div id="languages" class="is-hidden-initially">
<ul>
<li>Spanish</li>
<li>French</li>
<li>Russian</li>
</ul>
</div>

But now how can we toggle between showing and hiding the div?

You are trying to access an element by id but haven't specified an id for the element yet.

You could do it like this:

 const divHide = document.getElementById("div-hide"); function handleHide(){ divHide.style.display = "none"; } function handleShow(){ divHide.style.display = "block"; }
 <div id="div-hide"> Hello </div> <button onclick="handleHide()"> click to hide </button> <button onclick="handleShow()"> click to show </button>

Or like this:

 const divHide = document.getElementById("div-hide"); const btnHide = document.getElementById("btn-hide"); const btnShow = document.getElementById("btn-show"); btnHide.addEventListener("click", () => { divHide.style.display = "none"; }); btnShow.addEventListener("click", () => { divHide.style.display = "block"; });
 <div id="div-hide"> Hello </div> <button id="btn-hide"> click to hide </button> <button id="btn-show"> click to show </button>

If you want to add some toggle logic you could do the following:

 const divHide = document.getElementById("div-hide"); function handleToggle(){ divHide.style.display === "none"? divHide.style.display = "block": divHide.style.display = "none"; }
 <div id="div-hide"> Hello </div> <button onclick="handleToggle()"> click to toggle </button>

You want to access using getElementById but your code contains languages as a class, not id. Corrected your code below,

 function handleDropDown(elementId) { const element = document.getElementById('languages'); if (element.style.display === "block") { element.style.display = "none"; } else { element.style.display = "block"; } }
 .flag-icon-wrapper { margin-right: 20px; padding-top: 5px; }.flex { display: flex; }.flag-icon { width: 50px; }.is-hidden-initially { display: none; }
 <span class="flag-icon-wrapper flex" onClick='handleDropDown()'> <img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" /> </span> <div id="languages" class="is-hidden-initially"> <ul> <li>Spanish</li> <li>French</li> <li>Russian</li> </ul> </div>

I believe I see what you are attempting. I would be a bit more deliberate, not proliferate with unique id's and I would use a data attribute set to both toggle and set visibility using CSS.

I added a second flag just to illustrate the same code works for both using the data attributes set. Note I pass this from the element but you could also use an event handler instead of embedding that call in the element, keeping the code separate from the markup. (2nd example)

 function handleDropDown(me) { // get and use the selector from the data attribute let toggles = ["hidden", "showem"]; let tarsel = me.dataset.clickTarget; let tar = document.querySelector(tarsel); tar.dataset.hideme = tar.dataset.hideme == toggles[0]? toggles[1]: toggles[0]; }
 .flag-icon-wrapper { margin-right: 20px; padding-top: 5px; }.flex { display: flex; }.flag-icon { width: 50px; } [data-hideme="hidden"] { display: none; } [data-hideme="showem"] { border: solid lime 1px; ; }
 <span class="flag-icon-wrapper flex" onClick='handleDropDown(this)' data-click-target=".mytarget.languages"> <img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" /> </span> <span class="flag-icon-wrapper flex" onClick='handleDropDown(this)' data-click-target=".newtarget.languages"> <img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" /> </span> <div class="newtarget languages" data-hideme="hidden"> <ul> <li>Spanish</li> <li>French</li> <li>Russian</li> </ul> </div> <div class="mytarget languages" data-hideme="hidden"> <ul> <li>Beer</li> <li>Wine</li> <li>Cheese</li> </ul> </div>

2nd example using an event handler from code instantiation rather than in markup

 let wappers = document.querySelectorAll(".flag-icon-wrapper"); wappers.forEach(el => el.addEventListener("click", function(event) { // get and use the selector from the data attribute let toggles = ["hidden", "showem"]; let tarsel = this.dataset.clickTarget; let tar = document.querySelector(tarsel); tar.dataset.hideme = tar.dataset.hideme == toggles[0]? toggles[1]: toggles[0]; }));
 .flag-icon-wrapper { margin-right: 20px; padding-top: 5px; }.flex { display: flex; }.flag-icon { width: 50px; } [data-hideme="hidden"] { display: none; } [data-hideme="showem"] { border: solid lime 1px; ; }
 <span class="flag-icon-wrapper flex" data-click-target=".mytarget.languages"> <img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" /> </span> <span class="flag-icon-wrapper flex" data-click-target=".newtarget.languages"> <img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" /> </span> <div class="newtarget languages" data-hideme="hidden"> <ul> <li>Spanish</li> <li>French</li> <li>Russian</li> </ul> </div> <div class="mytarget languages" data-hideme="hidden"> <ul> <li>Beer</li> <li>Wine</li> <li>Cheese</li> </ul> </div>

<span class="flag-icon-wrapper flex" onclick="handleDropDown()">
        <img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" />
        </span>
        
        <div class="languages is-hidden-initially" id="languages">
        <ul>
        <li>Spanish</li>
        <li>French</li>
        <li>Russian</li>
        </ul>
        </div>

js

function handleDropDown() {
    var x = document.getElementById("languages");
    if (x.style.display === "none") {
        x.style.display = "block";
    } else {
        x.style.display = "none";
    }
}

Hope It will work.

You can simply add a toggle to the classList: element.classList.toggle("is-hidden-initially");

 function handleDropDown(elementId) { const element = document.getElementById('languages'); element.classList.toggle("is-hidden-initially"); }
 .flag-icon-wrapper { margin-right: 20px; padding-top: 5px; }.flex { display: flex; }.flag-icon { width: 50px; }.is-hidden-initially { display: none; }
 <span class="flag-icon-wrapper flex" onClick='handleDropDown()'> <img class="flag-icon" src="https://i.imgur.com/3DpAxu5.png" /> </span> <div id="languages" class="is-hidden-initially"> <ul> <li>Spanish</li> <li>French</li> <li>Russian</li> </ul> </div>

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