Javascript hide/show elements - Too much code, can it be better written? - javascript

I'm trying to get some advice regarding my Javascript code. It works fine but I'm pretty certain that it's overworked and can/could be scaled down.
As of now I have 4 div elements (#5gb, #15gb, #30gb and #100gb) and 4 buttons. Each button triggers one of the four functions, showing one div and hiding the three others.
Is this proper done or do you have any other solution that doesn't require as much code.
Code below:
<script>
function loaded() {
document.getElementById("5gb").style.display = "block";
document.getElementById("15gb").style.display = "none";
document.getElementById("30gb").style.display = "none";
document.getElementById("100gb").style.display = "none";
}
</script>
<script>
function ab5gb() {
document.getElementById("5gb").style.display = "block";
document.getElementById("15gb").style.display = "none";
document.getElementById("30gb").style.display = "none";
document.getElementById("100gb").style.display = "none";
}
function ab15gb() {
document.getElementById("5gb").style.display = "none";
document.getElementById("15gb").style.display = "block";
document.getElementById("30gb").style.display = "none";
document.getElementById("100gb").style.display = "none";
}
function ab30gb() {
document.getElementById("5gb").style.display = "none";
document.getElementById("15gb").style.display = "none";
document.getElementById("30gb").style.display = "block";
document.getElementById("100gb").style.display = "none";
}
function ab100gb() {
document.getElementById("5gb").style.display = "none";
document.getElementById("15gb").style.display = "none";
document.getElementById("30gb").style.display = "none";
document.getElementById("100gb").style.display = "block";
}
</script>
<button onclick="ab5gb()">5 GB</button>
<button onclick="ab15gb()">15 GB</button>
<button onclick="ab30gb()">30 GB</button>
<button onclick="ab100gb()">100 GB</button>

By having one function and passing a parameter would be better. Something like following.
<script>
function loaded() {
document.getElementById("5gb").style.display="block";
document.getElementById("15gb").style.display="none";
document.getElementById("30gb").style.display="none";
document.getElementById("100gb").style.display="none";
}
function ab(param) {
document.getElementById("5gb").style.display="none";
document.getElementById("15gb").style.display="none";
document.getElementById("30gb").style.display="none";
document.getElementById("100gb").style.display="none";
document.getElementById(param).style.display="block";
}
</script>
<button onclick="ab('5gb')">5 GB</button>
<button onclick="ab('15gb')">15 GB</button>
<button onclick="ab('30gb')">30 GB</button>
<button onclick="ab('100gb')">100 GB</button>

Use the toggle method from the select element which will add and remove the class.
const ele = document.getElementById("5gb");
ele.classList.toggle('display-none')
//css
.display-none { display: 'none' }
Note - add default css as display-block

You could use a forEach loop to iterate over your show/hide elements.
<script>
function show(id) {
document.querySelectorAll('.target').forEach((target) => {
if (target.id === id) {
target.style.display = "block";
} else {
target.style.display = "none";
}
})
}
</script>
<div class="target" id="5GB" style="display: block;">5 GB</div>
<div class="target" id="15GB" style="display: none;">15 GB</div>
<div class="target" id="30GB" style="display: none;">30 GB</div>
<div class="target" id="100GB" style="display: none;">100 GB</div>
<button onclick="show('5GB')">5 GB</button>
<button onclick="show('15GB')">15 GB</button>
<button onclick="show('30GB')">30 GB</button>
<button onclick="show('100GB')">100 GB</button>

You can do this in one function instead of four:
<script>
function loaded(id){
document.getElementById("5gb").style.display="none";
document.getElementById("15gb").style.display="none";
document.getElementById("30gb").style.display="none";
document.getElementById("100gb").style.display="none";
document.getElementById(id).style.display="block";
}
</script>
<button onclick="loaded(document.getElementById('5gb').id)">5 GB</button>
<button onclick="loaded(document.getElementById('15gb').id)">15 GB</button>
<button onclick="loaded(document.getElementById('30gb').id)">30 GB</button>
<button onclick="loaded(document.getElementById('100gb').id)">100 GB</button>

Use a parametrized function, and work with the built-in hidden API, which is a simple one-liner:
const els = ['5gb','15gb','30gb','100gb'].map(id => document.getElementById(id));
function toggleDisplay(id) { for (const el of els) el.hidden = id !== el.id }
In HTML, you can use it like this:
<button onclick="toggleDisplay('5gb')">5 GB</button>
<button onclick="toggleDisplay('15gb')">15 GB</button>
<button onclick="toggleDisplay('30gb')">30 GB</button>
<button onclick="toggleDisplay('100gb')">100 GB</button>
Even better would be to not use inline event listeners, and instead put the id into a data-attribute:
<button data-toggle-id="5gb">5 GB</button>
<button data-toggle-id="15gb">15 GB</button>
<button data-toggle-id="30gb">30 GB</button>
<button data-toggle-id="100gb">100 GB</button>
And then work with a delegate listener:
document.addEventListener('click', function(event) {
event.target.dataset.toggleId ?? toggleDisplay(event.target.dataset.toggleId);
})

Related

button toggle display show hide

I want to show-hide the display of these layers with a button click. I can't figure out how to do it with 2 buttons, and 2 divs...
Html:
<div id="first">This is the FIRST div</div>
<div id="second">This is the SECOND div</div>
<button id="toggle">Show first div and hide second div</button>
<button id="toggletoo">Show second div and hide first div</button>
Css:
#first {
display: none;
}
#second {
display: none;
}
Js:
const targetDiv = document.getElementById("first");
const btn = document.getElementById("toggle");
btn.onclick = function () {
if (targetDiv.style.display !== "none") {
targetDiv.style.display = "block";
} else {
targetDiv.style.display = "none";
}
}
https://codepen.io/MaaikeNij/pen/YzrgbQw
Try with the following code:
#first{
display: block; /* <--- change */
}
#second {
display: none;
}
const firstDiv = document.getElementById("first");
const secondDiv = document.getElementById("second");
document.getElementById("toggle").onclick = function () {
if (firstDiv.style.display === "none") {
firstDiv.style.display = "block";
secondDiv.style.display = "none";
} else {
firstDiv.style.display = "none";
secondDiv.style.display = "block";
}
}
There's lots of ways to do this. One common way I've seen in various templates is to add and remove classes. Another way is to call the function from the button's onclick attribute. But my favorite is to write a function that requires no editing of the div HTML because I don't want to interfere with the HTML guy's work, I just want to put functioning code in there. (BTW, I am positive there is a more elegant way to write this, but here ya go!)
const firstDiv = document.querySelector("#first");
const secondDiv = document.querySelector("#second");
const firstButt = document.querySelector("#toggle");
const secondButt = document.querySelector("#toggletoo");
firstButt.addEventListener("click",toggleDivShowHide);
secondButt.addEventListener("click",toggleDivShowHide);
function toggleDivShowHide() {
if (firstDiv.style.display !== "none") {
firstDiv.style.display = "none";
secondDiv.style.display = "block";
} else {
firstDiv.style.display = "block";
secondDiv.style.display = "none";
}
}
You're saying "if the first div is set to none, then set it to block and set the second div to none. Otherwise, do the opposite."
I tried something different, this is working :)))
<div id="first" style="display:none;"> This is the FIRST div</div>
<div id="second" style="display:none;"> This is the SECONDdiv</div>
<input type="button" name="answer" value="Show first div and hide second div" onclick="showDivOne()" />
<input type="button" name="answer" value="Show second div and hide first div" onclick="showDivTwo()" />
function showDivOne() {
document.getElementById('first').style.display = "block";
document.getElementById('second').style.display = "none";
}
function showDivTwo() {
document.getElementById('second').style.display = "block";
document.getElementById('first').style.display = "none";
}
https://codepen.io/MaaikeNij/pen/vYeMGyN
Correction: you should add event Listener for both toggle & toggletoo.
Solution: solution with reusable code.
const Toggles = document.querySelectorAll('.toggle');
const Hides = document.querySelectorAll('.hide');
Toggles.forEach((el) => {
el.addEventListener("click", (e) => {
Hides.forEach((el) => {
el.parentElement.firstElementChild.classList.add('hide');
});
e.target.parentElement.firstElementChild.classList.toggle('hide');
});
})
.hide {
display: none;
}
<div>
<div class="hide">This is the FIRST div</div>
<button class="toggle">Show first div and hide first div</button>
</div>
<div>
<div class="hide">This is the SECOND div</div>
<button class="toggle">Show second div and hide first div</button>
</div>
<div>
<div class="hide">This is the Third div</div>
<button class="toggle">Show Third div and hide first div</button>
</div>
<div>
<div class="hide">This is the Fourth div</div>
<button class="toggle">Show Fourth div and hide first div</button>
</div>
For precisely such cases, javascript has the toggle function. I rewrite your code a little bit.
const btns = document.querySelectorAll(".toggleBtn");
btns.forEach(b => {
b.onclick = function (e) {
reset();
console.log(e.target.getAttribute('data-target'))
const target = e.target.getAttribute('data-target');
const t = document.querySelector('#' + target);
t.classList.toggle('hide');
}
});
function reset() {
const divs = document.querySelectorAll('.out');
divs.forEach(d => d.classList.add('hide'))
}
.hide {
display: none;
}
<div id="first" class="out hide">This is the FIRST div</div>
<div id="second" class="out hide">This is the SECOND div</div>
<button class="toggleBtn" data-target="first">Show first div and hide second div</button>
<button class="toggleBtn" data-target="second">Show second div and hide first div</button>

Hide/Show element on click JS not working properly

I have a simple function when I click on a button to display text for the button, everything is ok but on the first click it's not working then after the second click it's working perfectly can anybody tell me whats my mistake? I have the element hidden in CSS display;none, here is my logic
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
#myDIV {
display: none;
}
<button type="button" class="btn btn-primary btn-lg btn-block" onclick="myFunction()">
<div id="myDIV">
This is my DIV element.
</div>
The problem is probably that you didn't close the button tag. So it doesn't find myFunction(). You also need to fetch the computed value of display style not the elements value because css files do not affect the elements styles directly. (e.g. vs style="")
<body>
<script>
function myFunction() {
var x = document.getElementById("myDIV");
if (getComputedStyle(x).display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
<button
type="button"
class="btn btn-primary btn-lg btn-block"
onclick="myFunction()"
>
test
</button>
<div id="myDIV">
This is my DIV element.
</div>
</body>

Javascript - hide/show - multiple buttons - calling 1 function [duplicate]

This question already has answers here:
How can I hide/show a div when a button is clicked?
(9 answers)
Closed 2 years ago.
Please can someone explain this situation?
I want to use the same function (hide/show) for more buttons. How can I call the same function with different buttons?
I found how to do it with one but can't find any solution for 2 or more buttons.
I would like to hide div1 if I click on bt1 and hide div2 if I click on bt2. Thank you for any help...
My current code is:
function myFunction() {
var x = document.getElementById("div1");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<html>
<body>
<button id="bt1" onclick="myFunction()">Button 1</button>
<div id="div1">div1</div>
<p></p>
<button id="bt2" onclick="myFunction()">Button 2</button>
<div id="div2">div2</div>
</body>
</html>
Thank you for your help...
You could pass the ID of the div to your function as a parameter:
function myFunction(el) {
var x = document.getElementById(el);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<button id="bt1" onclick="myFunction('div1')">Button 1</button>
<div id="div1">div1</div>
<p></p>
<button id="bt2" onclick="myFunction('div2')">Button 2</button>
<div id="div2">div2</div>
One way is to pass the ID of the DIV as a function parameter.
function myFunction(id) {
var x = document.getElementById(id);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<html>
<body>
<button id="bt1" onclick="myFunction('div1')">Button 1</button>
<div id="div1">div1</div>
<p></p>
<button id="bt2" onclick="myFunction('div2')">Button 2</button>
<div id="div2">div2</div>
</body>
</html>
Another way is to pass the button itself, and use DOM navigation, if the DIV to hide and show is always right after the button.
function myFunction(button) {
var x = button.nextElementSibling;
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<html>
<body>
<button id="bt1" onclick="myFunction(this)">Button 1</button>
<div id="div1">div1</div>
<p></p>
<button id="bt2" onclick="myFunction(this)">Button 2</button>
<div id="div2">div2</div>
</body>
</html>
I would do it like so:
Add a data-attribute like data-js-hide="div1"
Add a click event listener for all those elements having the attribute data-js-hide
when clicked use the value "div1" from the attribute data-js-hide
The advantages are that it does not matter where in DOM the elements are. You just need to set the attribute with id, and then on click the item with the id will be hidden or shown accordingly.
function myFunction(event) {
var x = document.getElementById(event.target.dataset.jsHide);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
var buttons = document.querySelectorAll('[data-js-hide]');
buttons.forEach(
button => {
button.addEventListener('click', myFunction);
}
);
<html>
<body>
<button data-js-hide="div1" >Button 1</button>
<div id="div1">div1</div>
<p></p>
<button data-js-hide="div2">Button 2</button>
<div id="div2">div2</div>
<p></p>
<button data-js-hide="div3">Button 3</button>
<div id="div3">div3</div>
</body>
</html>

How to make a JavaScript function control two HTML IDs?

I have this button tag element
<button class="btn btn-link" type="button" onclick="contentDownloads()">
<img src="./downloads/content-textures.svg" width="120px" />
</button>
And has a javascript function
function contentDownloads() {
var x = document.getElementById("vipDownloads");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
But, in the future I will include more buttons and would lead to the same function.
This is the part that contains the IDs:
<div id="vipDownloads" class="collapse show" style="display: none;">
<div class="card-body">
<h5 class="card-title">Map Pack v 1.8 <span class="caption-entry">by cWaLker</span> </h5>
<p class="card-text">
Aight Fellas,
Map Pack v 1.8 introduces some revived classics and under the radar stunners. <br>
<br> 1.7 went on a diet and dropped some restraining pounds.
For this nugget to work stable, you'd need to remove your own user folder first and then drop the User folder from the 1.8 bulk package.. it will serve you everything you need anyways ;-)<br>
<br> Have Fun Guys lets kick some flips!
</p>
<button type="button" class="btn btn-outline-success">Download</button><br>
</div>
</div>
You can see here how I designed the buttons and content http://thpsblog.000webhostapp.com/downloads.html (the css on my host takes a while to actually update, might include some white on white colors)
The function hides and unhides content.
I have found some solutions but they were all typed in jQuery, and unfortunately I do not know jQuery.
How could I make this function take two unique ids?
Make the ID of the element to toggle a parameter of the function, and pass it when you call the function.
function contentDownloads(id) {
var x = document.getElementById(id);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<button class="btn btn-link" type="button" onclick="contentDownloads('vipDownloads')">
<img src="./downloads/content-textures.svg" width="120px" />
</button>
If you don't want to add an onclick event to your html, you can create a vars array and use a forEach loop. Else, you can use #Barmar's answer.
function contentDownloads() {
var x = document.getElementById("vipDownloads");
var y = document.getElementById("y");
var z = document.getElementById("z");
vars = [x,y,z]; // update this array when selected a new element
vars.forEach(function(p){
if (p.style.display === "none") {
p.style.display = "block";
} else {
p.style.display = "none";
}
})
}
Make id param as others suggested or use data attributes:
<button class="btn btn-link" type="button" onclick="contentDownloads(this)" data-downloadsid="vipDownloads">
<img src="./downloads/content-textures.svg" width="120px" />
</button>
function contentDownloads(element) {
var x = document.getElementById(element.dataset.downloadsid);
if(x == null) return;
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
You can query the elements with a class and iterate each
<div class="download-element">Element 1</div>
<div class="download-element">Element 2</div>
<div class="download-element">Element 3</div>
<button class="btn btn-link" type="button" onclick="contentDownloads()">
<img src="./downloads/content-textures.svg" width="120px" />
</button>
function contentDownloads() {
document.querySelectorAll('.download-element')
.forEach(element => {
if(element.style.display === "none") {
element.style.display = "block";
} else {
element.style.display = "none";
}
})
}

Make text appear/disappear on button click [duplicate]

This question already has answers here:
How can I change CSS display none or block property using jQuery?
(15 answers)
Closed 3 years ago.
I'm trying to make the button alternate the text from hidden using 'none' to appear using 'block'. I tried the below but it did not work
<p id='demo' style = 'display: none'>Hello Javascript</p>
<button type='button' onclick="document.getElementById('demo').style.display='block'" >click me</ button>
I want to convert event listener to Javascript and run from there.
Try this, I hope it'll help you out. Thanks
function toggleText() {
var text = document.getElementById("demo");
if (text.style.display === "none") {
text.style.display = "block";
} else {
text.style.display = "none";
}
}
<p id='demo' style='display: none'>Hello Javascript</p>
<button type='button' onclick="toggleText()">Click me</button>
css:
.demo {
display: none;
}
html:
<p id='demo' class='demo'>Hello Javascript</p>
<button type='button'> click me </button>
js:
var tag = document.getElementById('demo');
var button = document.querySelector('button');
button.addEventListener('click', function(){
tag.classList.toggle('demo');
});
Running Snippet:
var tag = document.getElementById('demo');
var button = document.querySelector('button');
button.addEventListener('click', function(){
tag.classList.toggle('demo');
});
.demo {
display: none;
}
<p id='demo' class='demo'>Hello Javascript</p>
<button type='button'> click me </button>
Is it helpful:
var showHide = document.getElementById("showHide");
var demo = document.getElementById("demo");
showHide.onclick = function() {
if (demo.style.display == "block") {
demo.style.display = "none";
} else {
demo.style.display = "block";
}
}
<p id='demo' style='display: none'>Hello Javascript</p>
<button id="showHide">Click Me</button>

Categories