Button click works on second click only - javascript

I have a button and a div under it, the button must show this div onclick, i wrote the function and everything is fine, but it works only on second click and i can't figure out why, here is my code:
function showDiv() {
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-default" onclick="showDiv()">Show div</button>
<div id="myDiv">
test
test
test
test
test
test
</div>

To get the value that you apply via a stylesheet (or block) you need to use getComputedStyle(). document.getElementById('myDiv').style.display can only read inline styles.
function showDiv() {
var x = document.getElementById('myDiv');
if ( window.getComputedStyle(x, null).getPropertyValue("display") === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
}
#myDiv{
display: none;
}
<button type="button" class="btn btn-default" onclick="showDiv()">Show div</button>
<div id="myDiv">
test
test
test
test
test
test
</div>

You have set the style in css.So the value of x.style.display is not none initially.it wolud be empty.So set that style initially. or use getComputedStyle to get the CSS rule
function showDiv() {
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-default" onclick="showDiv()">Show div</button>
<div id="myDiv" style="display:none;">
test
test
test
test
test
test
</div>
if the element's display is being inherited or being specified by a CSS rule, compute the style using getComputedStyle
function showDiv() {
var x = document.getElementById('myDiv');
if (getComputedStyle(x, null).display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
}
#myDiv{
display: none;
}
<button type="button" class="btn btn-default" onclick="showDiv()">Show div</button>
<div id="myDiv">
test
test
test
test
test
test
</div>

Setting CSS style does not pervade to x.style.display so when you click the first time x.style.display actually equals "", so it hits your else block and sets the style.display to none, 2nd time and it hits the first branch of the conditional and shows your div.
Either use computedStyle to grab the actual style, or, this would be a little easier using classes.
JS:
function show () {
var x = document.querySelector('#myDiv')
x.classList.toggle('show')
}
CSS:
.show {
display: 'block';
}
Classlist is supported for all modern browsers but some really old ones will struggle with it, although good polyfills exist.

Because div doesn't have display in style. You can add it manually:
function showDiv() {
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-default" onclick="showDiv()">Show div</button>
<div id="myDiv" style='display:none'>
test
test
test
test
test
test
</div>

The problem with your code is that x.style.display corresponds with the display property attached inline to your element. It ignores your CSS selector, which means that x.style.display === 'none' is false the first time you run your function.
Inlining display:none would fix your problem :
<div id="myDiv">...</div> → → → <div id="myDiv" style="display:none;">...</div>
However, that's not the recommended approach here. A better way to achieve the desired result, would be to toggle a class :
document.getElementById('myButton').addEventListener('click', function() {
document.getElementById("myDiv").classList.toggle('hidden');
});
.hidden {
display: none;
}
<button id="myButton" type="button" class="btn btn-default">Show div</button>
<div id="myDiv" class="hidden">test test test test test test</div>

Related

Hide form content until button is clicked

I would like to hide the content of my form until the button is clicked, the code I am using shows content until clicked, I am starting out so probably missing something simple, any help appreciated, the code I am using is:
<script>
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
</script>
you must add "display: none;" to "myDiv" property in css file then you can use your func
I think this is what you need
Heres the code:
document.getElementById("myButton").onclick = function() {
document.getElementById("myInput").style.display = "block";
}
<form>
<input type="text" id="myInput" style="display: none;">
</form>
<button id="myButton">Click</button>
Try this :
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display == "none" || x.style.display == "") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
#myDIV {
border:solid 1px #c0c0c0;
padding:10px;
display:none;
}
<input type="button" onclick="myFunction();" value="switch" /><br>
<div id="myDIV">Welcome</div>
Because, if display is decalred in css to none (or whatever but not in DOM element) then javascript will "see" it like empty string. Or, set in <div id="myDIV" style="display:none;"></div>.
By my opinon, first code is better choice.

Initially I want ON button to be display block and off to display none, if I click ON button, OFF appears & On disappears, and vice versa

I am trying to achieve a toggle effect using display properties, only one button should be on display at a time, while the other is hidden and vice versa. Currently, I am able to hide the off button if I click any of the buttons, so what do I do to get only one displayed at a time
function myFunction() {
var x = document.getElementById("on");
var y = document.getElementById("off");
y.style.display ="none";
if (x.style.display === "none") {
x.style.display = "block";
}
else {
y.style.display = "none";
x.style.display = "block";
}
}
<button onclick="myFunction()" id="on">ON</button>
<button onclick="myFunction()" id="off">OFF</button>
The issue with your logic is that you need to switch the display state of both elements within the function you call:
var on = document.getElementById("on");
var off = document.getElementById("off");
function myFunction() {
if (on.style.display === "none") {
off.style.display = "none";
on.style.display = "block";
} else {
off.style.display = "block";
on.style.display = "none";
}
}
<button onclick="myFunction()" id="on">ON</button>
<button onclick="myFunction()" id="off" style="display: none;">OFF</button>
Another way to do what you require would be to use a CSS class to hide the required element. This avoids the need for the if condition. You can then use classList.toggle() to switch the class on/off on each element on successive clicks. Something like this:
let toggles = document.querySelectorAll('.toggle');
toggles.forEach(toggle => {
toggle.addEventListener('click', e => {
toggles.forEach(el => el.classList.toggle('hide'));
});
});
.hide { display: none; }
<button class="toggle" id="on">ON</button>
<button class="toggle hide" id="off">OFF</button>
Or even more simply using jQuery:
let $toggles = $('.toggle').on('click', () => $toggles.toggleClass('hide'));
.hide { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<button class="toggle" id="on">ON</button>
<button class="toggle hide" id="off">OFF</button>
In this solution, when the on and off buttons are clicked, the toggle() method is called and the display properties are changed. In order to hide a button initially, I set the display property of the <button> with an off id value to none; this feature can also be provided by using the onload event that is triggered when the page is loaded.
const on = document.getElementById('on');
const off = document.getElementById('off');
function toggle(){
if(on.style.display === 'none'){
on.style.display = 'block';
off.style.display = 'none';
}
else{
on.style.display = 'none';
off.style.display = 'block';
}
}
on.addEventListener('click', function(){
toggle();
});
off.addEventListener('click', function(){
toggle();
});
#on {
display: block;
}
#off {
display: none;
}
<button id="on">ON</button>
<button id="off">OFF</button>

How do I create show/hide elements for different buttons?

HTML Code...the buttons interfere with each other. How can I fix this?
<button onclick="myFunction()" style="margin-left:50px;"> Click Here For Help </button> <br> <br>
<div id="help1">
<p> Help </p>
</div>
<button onclick="myFunction()" style="margin-left:50px;"> Click Here For Help </button> <br> <br>
<div id="help2">
<p> Help </p>
</div>
Javascript shown with ids for the different buttons. Onload section to hide the content on page
load.
<script>
function myFunction() {
var x = document.getElementById("help1");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
window.onload = function() {
document.getElementById("help1").style.display = 'none';
};
</script>
<script>
function myFunction() {
var x = document.getElementById("help2");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
window.onload = function() {
document.getElementById("help2").style.display = 'none';
};
</script>
One was is to simply pass the id of the element as an input to myFunction so the corresponding element can be retrieved from the document and set to display:none. This will save you from needing duplicate functions. Press the blue Run code snippet button below to see the results.
Method 1:
function myFunction(ID) {
var x = document.getElementById(ID);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
window.onload = function() {
document.getElementById("help1").style.display = 'none';
document.getElementById("help2").style.display = 'none';
};
<button onclick="myFunction('help1')" style="margin-left:50px;"> Click Here For Help </button> <br> <br>
<div id="help1">
<p> Help </p>
</div>
<button onclick="myFunction('help2')" style="margin-left:50px;"> Click Here For Help </button> <br> <br>
<div id="help2">
<p> Help </p>
</div>
Alternative Method:
This example reduces the amount of JavaScript but slightly increases the amount of HTML id tags and classes. It also incoporates some additional CSS. As suggested in the comment above this method uses:
• Event listeners
• Toggles a class using classList
function myFunction() {
document.getElementById("help" + String(this.id.split("_")[2])).classList.toggle("Display_It");
}
window.onload = function() {
document.getElementById("Toggle_Button_1").addEventListener("click", myFunction);
document.getElementById("Toggle_Button_2").addEventListener("click", myFunction);
};
#Toggle_Button_1,
#Toggle_Button_2 {
margin-left: 50px;
}
.Help_Panel {
display: none;
}
.Display_It {
display: block;
}
<button id="Toggle_Button_1"> Click Here For Help </button>
<br>
<br>
<div class="Help_Panel" id="help1">
<p>Help</p>
</div>
<button id="Toggle_Button_2"> Click Here For Help</button>
<br>
<br>
<div class="Help_Panel" id="help2">
<p>Help</p>
</div>

Multiple JavaScript Buttons Simplified Into One Function

I have three buttons and three JS functions that toggle the display of three different divs. How can I simplify/condense my three JS functions into one function that connects each button to its corresponding content?
Example:
HTML Buttons
<button onclick="myFunction1()">Button 1</button>
<button onclick="myFunction2()">Button 2</button>
<button onclick="myFunction3()">Button 3</button>
HTML Content
<div id="ContentOne">This is Content One.</div>
<div id="ContentTwo">This is Content Two.</div>
<div id="ContentThree">This is Content Three.</div>
JavaScript
function myFunction1() {
var x = document.getElementById("ContentOne");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function myFunction2() {
var x = document.getElementById("ContentTwo");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function myFunction3() {
var x = document.getElementById("ContentThree");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
Add a parameter to the condensed function et violà!
function myFunction(id) {
var x = document.getElementById(id);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<button onclick="myFunction('ContentOne')">Button 1</button>
<button onclick="myFunction('ContentTwo')">Button 2</button>
<button onclick="myFunction('ContentThree')">Button 3</button>
<div id="ContentOne">This is Content One.</div>
<div id="ContentTwo">This is Content Two.</div>
<div id="ContentThree">This is Content Three.</div>
Explanation
The only part that differs within the functions is the ID, so decouple the ID. The function does not need to know which element will be affected of the styling adaptions. So keep the function "dump".
Further learning: Anti-Patterns
If you are interested in improving your programming style, I suggest you take a look at some anti-pattern. For example, you demonstrated the antipattern of hard coding. It's not as untypical as you think.
Inline JS is hard to maintain.
I'd use this code with just a line of CSS to hide elements,
and use JS simply to toggle that .hide class:
const toggleEl = e => document.getElementById(e.target.dataset.tog).classList.toggle("hide");
[...document.querySelectorAll("[data-tog]")].forEach( btn =>
btn.addEventListener("click", toggleEl)
);
.hide { display: none;}
<button data-tog="ContentOne">Button 1</button>
<button data-tog="ContentTwo">Button 2</button>
<button data-tog="ContentThree">Button 3</button>
<div class="hide" id="ContentOne">This is Content One.</div>
<div class="hide" id="ContentTwo">This is Content Two.</div>
<div class="hide" id="ContentThree">This is Content Three.</div>
https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
Here's a ES5 example if you prefer:
function toggleEl() {
var id = this.getAttribute("data-tog");
document.getElementById(id).classList.toggle("hide");
}
var buttons = document.querySelectorAll("[data-tog]");
[].forEach.call(buttons, function( btn ) {
btn.addEventListener("click", toggleEl.bind(btn))
});
.hide { display: none;}
<button data-tog="ContentOne">Button 1</button>
<button data-tog="ContentTwo">Button 2</button>
<button data-tog="ContentThree">Button 3</button>
<div class="hide" id="ContentOne">This is Content One.</div>
<div class="hide" id="ContentTwo">This is Content Two.</div>
<div class="hide" id="ContentThree">This is Content Three.</div>
You can use a higher order function.
function generateFunction(elementId) {
return function() {
var x = document.getElementById(elementId);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
}
var myFunction1 = generateFunction("ContentOne");
var myFunction2 = generateFunction("ContentTwo");
var myFunction3 = generateFunction("ContentThree");

Toggle - Hide and show

I copied w3schools hide and show toggle, but I want it to be reversed, so that the extra information isn't there from the beginning, but the button shows it.
This is the code:
html:
<button onclick="myFunction()">Click Me</button>
<div id="myDIV">
This is my DIV element.
</div>
js:
function myFunction() {
var x = document.getElementById('myDIV');
if (x.style.display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
}
Any help would be much appreciated!
Solution is simple: Just hide the div.
<div id="myDIV" style="display:none">
This is my DIV element.
</div>
Even cooler if you hide it in css instead:
<div id="myDIV">
This is my DIV element.
</div>
And this in your css:
#myDIV {
display: none;
}
I'd us a utility CSS class for this:
.is--hidden {
display: none;
}
Then you can apply it to the element by default:
<button class="mybutton">Click Me</button>
<div class="example is--hidden">Some Text</div>
and toggle it via jQuery:
$('.mybutton').on('click', function () {
$('.example').toggleClass('is--hidden');
})
Fiddle: https://jsfiddle.net/tL5mj54n/
You just need to add display : none in your code.
function myFunction() {
var x = document.getElementById('myDIV');
if (x.style.display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
}
<button onclick="myFunction()">Click Me</button>
<div id="myDIV" style="display:none;">
This is my DIV element.
</div>
No changes to styles or HTML required. Your javascript should be the following:
(function () {
var x = document.getElementById('myDIV');
if (x.style.display != 'none') {
x.style.display = 'none';
} else {
x.style.display = 'block';
}
} )();
function myFunction() {
var x = document.getElementById('myDIV');
if (x.style.display != 'none') {
x.style.display = 'none';
} else {
x.style.display = 'block';
}
};
The first function runs and hides your div and the second reacts to clicks and toggles the div.
Here's a snippet example
Set the style to hide the element (display:none) from the start. Toggle it on click.
document.getElementById('myButton').onclick = function() {
var x = document.getElementById('myDIV');
x.style.display = x.style.display === 'none' ? 'block' : 'none';
};
<button id='myButton' >Click Me</button>
<div id="myDIV" style="display:none">
This is my DIV element.
</div>

Categories

Resources