Reputation: 81
I managed to do something by searching for some javascript code that I could adapt, and I somehow made it; but its not working properly.
When the button is clicked once it works as intended, but when its clicked two times in a row, the result is inverted in a layout crash that causes two divs to be shown instead of hidden.
Here goes the demo: https://jsfiddle.net/ab8b7g4w/
HTML CODE
<input id="hideshow" type="button" value="Button one" />
<input id="hideshow2" type="button" value="Button two" />
<input id="hideshow3" type="button" value="Button third" />
<div id="punto1">
Main content
</div>
<div id="punto2">
Second div
</div>
<div id="punto3">
Third div
</div>
JQUERY CODE
jQuery(document).ready(function(){
jQuery('#hideshow').on('click', function(event) {
jQuery('#punto1').toggle('show');
jQuery('#punto2').toggle('hide');
jQuery('#punto3').toggle('hide');
});
});
jQuery(document).ready(function(){
jQuery('#hideshow2').on('click', function(event) {
jQuery('#punto1').toggle('hide');
jQuery('#punto2').toggle('show');
jQuery('#punto3').toggle('hide');
});
});
jQuery(document).ready(function(){
jQuery('#hideshow3').on('click', function(event) {
jQuery('#punto1').toggle('hide');
jQuery('#punto2').toggle('hide');
jQuery('#punto3').toggle('show');
});
});
CSS CODE
#punto2, #punto3 { display: none; }
Is there any way to fix this thing with the double click on buttons?
Thanks so much
Upvotes: 0
Views: 79
Reputation: 5014
I wouldn't use two classes show
and hide
. I find it adds confusion. I'd pick a state thats default either displayed or hidden. And add or remove a class when needed. In the example below the default state is to display and a class is added to the other elements making them hidden.
Secondly I wouldn't use CSS id. Use classes. This is more flexible. If you ever need to add or remove a slide you can just update the mark up without touching the js. In the example below if another button and div are added, it'll just work (providing they're added in the same position)
The magic here is finding the index of the element clicked, to know which slide index to display.
const index = buttonsArray.findIndex(el => el === clickedEl);
...
divsArray[index].className = "image-container";
The below example is written without jquery. But feel free to mix in jquery as tasks like toggling will be easier. I find things less confusing to first understand without any libraries, then add helper functions like toggle
or $('.image-button')
'.
<button class="image-button">One</button>
<button class="image-button">Two</button>
<button class="image-button">Three</button>
<button class="image-button">Four</button>
<div class="image-container">One</div>
<div class="image-container image-hidden">Two</div>
<div class="image-container image-hidden">Three</div>
<div class="image-container image-hidden">Four</div>
<script>
const buttons = document.querySelectorAll('.image-button');
const buttonsArray = Array.from(buttons); // convert to array to make findIndex available
const divs = document.querySelectorAll('.image-container');
const divsArray = Array.from(divs); // convert to array to make findIndex available
function handleClick(e) {
const clickedEl = e.target;
// find the index of the clicked button
const index = buttonsArray.findIndex(el => el === clickedEl);
// hide all divs
divsArray.forEach((el) => {
el.className = "image-container image-hidden";
});
// reveal the corresponding div
divsArray[index].className = "image-container";
console.log('click handled', index);
}
buttonsArray.forEach(el => {
el.addEventListener('click', handleClick);
});
</script>
<style>
.image-container {
background: orange;
width: 100px;
height: 100px;
}
.image-hidden {
display: none;
}
</style>
Upvotes: 0
Reputation: 448
This solution works:
jQuery(document).ready(function(){
jQuery('#hideshow').on('click', function(event) {
jQuery('#punto1').show();
jQuery('#punto2').hide();
jQuery('#punto3').hide();
});
});
jQuery(document).ready(function(){
jQuery('#hideshow2').on('click', function(event) {
jQuery('#punto1').hide();
jQuery('#punto2').show();
jQuery('#punto3').hide();
});
});
jQuery(document).ready(function(){
jQuery('#hideshow3').on('click', function(event) {
jQuery('#punto1').hide();
jQuery('#punto2').hide();
jQuery('#punto3').show();
});
});
But, it won't easily scale. As you add more and more elements you're going to bloat your javascript file unnecessarily.
You might want to try using a data value to specify the element that should be shown. This way you could easily loop through an image count and reuse the code for every single image. Something like this:
<input class="hideshow" type="button" value="Button one" data-button-id="1"/>
<input class="hideshow" type="button" value="Button two" data-button-id="2"/>
<input class="hideshow" type="button" value="Button third" data-button-id="3"/>
<div id="punto1" class="image-container">
Main content
</div>
<div id="punto2" class="image-container">
Second div
</div>
<div id="punto3" class="image-container">
Third div
</div>
The JS:
jQuery(document).ready(function(){
jQuery('.hideshow').on('click', function(event) {
var buttonID = this.dataset.buttonId;
var containerID = "#punto" + buttonID;
//Close all open containers
jQuery(".image-container").hide();
jQuery(containerID).show();
});
});
And of course the CSS:
#punto2, #punto3 { display: none; }
You can try it out here: https://jsfiddle.net/ab8b7g4w/1/
Upvotes: 0
Reputation: 221
just change the toggle with hide or show functions.
the toggle function you have used right there will toggle between the hidden and shown states, so when you click the first the div is hidden and the two other divs are shown, and when you click the second time the first div will be shown and the two others will be hidden...
jQuery(document).ready(function(){
jQuery('#hideshow').on('click', function(event) {
jQuery('#punto1').show();
jQuery('#punto2').hide();
jQuery('#punto3').hide();
});
});
jQuery(document).ready(function(){
jQuery('#hideshow2').on('click', function(event) {
jQuery('#punto1').hide();
jQuery('#punto2').show();
jQuery('#punto3').hide();
});
});
jQuery(document).ready(function(){
jQuery('#hideshow3').on('click', function(event) {
jQuery('#punto1').hide();
jQuery('#punto2').hide();
jQuery('#punto3').show();
});
});
Upvotes: 0
Reputation: 67
Show and hide are not needed when using .toggle(), .toggle() does a toggle on the state. Use .hide() and .show() to hide and show the divs.
Upvotes: 1