I am trying to trigger the visibility of a DIV via a button.
My code looks like this:
function myFunction() {
var moreText = document.getElementById("csrmore");
var x = document.getElementById("myDIV");
let ishidden = x.classList.contains("hidden")
if (ishidden == true) {
x.classList.remove("hidden");
x.classList.add("shown");
moreText.innerHTML = "Show less";
}
else {
x.classList.remove("shown");
x.classList.add("hidden");
moreText.innerHTML = "Show more";
}
}
div {
width: 100px;
height: 100px;
}
.hidden {
display:none
}
.shown {
display:block;
}
<button id="csrmore" onclick="myFunction()">
Show more
</button>
<div id="myDIV" class="hidden">
This is the triggerable content.
</div>
Fiddle: https://jsfiddle.net/6zxa0Lg2/
It works fine, however since I am a JS starter, I was wondering if this is bad practice or is it a totally fine piece of code?
Thanks for every help :)
Here's another way to go about it. Make it all relative. The button is clicked and the javascript finds the content associated to that button to show/hide. This way you don't need any ID tags and you can have as many show/hide buttons as you want on the page.
document.addEventListener('DOMContentLoaded', () => {
// after the page loads...
document.querySelectorAll('.csrmore').forEach(button => {
// find all the 'show more' buttons and for each one...
button.addEventListener('click', e => {
// when someone clicks this button
let content = e.target.closest('.container').querySelector('.content');
// find the content div associated with this button
content.classList.toggle('hidden');
// toggle on or off the content
e.target.innerText = content.classList.contains('hidden') ? 'Show more' : 'Hide';
// change the text of the button
})
})
})
div {
width: 100px;
height: 100px;
}
.hidden {
display: none
}
<div class='container'>
<button class="csrmore">
Show more
</button>
<div class="content hidden">
This is the triggerable content.
</div>
</div>
<hr>
<div class='container'>
<button class="csrmore">
Show more
</button>
<div class="content hidden">
This is the triggerable content.
</div>
</div>
This is a fine way to do this! This is not the solution I would not have come up with, but it is actually pretty clever. I would have thought to have done it by toggling TARGET.style.visibility to either "hidden" or "visible" when clicking the button. Again though, your code looks perfectly fine!
Related
Apologies in advance, I'm not terribly familiar with Javascript, but I do understand what this code is doing and why it is causing me this problem. I'm just not sure how to go about solving it AT all.
On my webpage I have an open/close dialogue toggle which is the parent div, the dialogue box is hidden upon the page loading. Within this dialogue box are more hidden divs for the dialogue options. Problem is, when one of the dialogue options is clicked, the script hides the entire dialogue box, preventing any of the dialogue options from being seen, because it can only show one div at a time, regardless of its parent or child status. When a div is clicked, all other divs are re-hidden.
I need the parent div to remain visible until the dialogue box toggle is clicked again. The individual choices DO need to hide/unhide when another choice is clicked.
Not sure if I should include any CSS here, it's just styling the dialogue box and its buttons within.
<div id="dialogue" style="display:none;">
<div class="room">
Room description here. What do you do?
<div class="buttons">
Pet the cat.
<br>
<div id="cat" style="display:none;">aw yeah kitty time</div>
Turn on the radio.
<br>
<div id="radio" style="display:none;">
<br>
audio file and tracklist here
</div>
</div>
</div>
</div>
<span class="toggle">
[Open/close dialogue.]
</span>
<script type="text/javascript">
var divs = ["cat", "radio", "dialogue"];
var visibleDivId = null;
function divVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for(i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if(visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
</script>
I probably need a third function here because currently all the toggles are grouped together, hence why they're interacting like this, but I don't have the first clue how to accomplish this. I have been looking and haven't found anything that seems to match my needs.
Made a few corrections to your HTML so the href does not refresh the page on click. Also added in a few attributes (aria-controls) to track which div the button controls. I added comments to the JavaScript. There are plenty of Aria attributes they typically help with accessibility but they are super useful for keeping track of things in HTML and passing information to JavaScript.
//create a function to handle the click that takes in the event as a argument
function handleClick(event) {
//find out which div the button controls
const ariaControls = event.currentTarget.getAttribute("aria-controls"),
//select the controlled div
controlledAria = document.getElementById(ariaControls);
// if the controlled div is cat
if (ariaControls === "cat") {
// hide the radio div
document.getElementById("radio").classList.add("hide");
// if the controlled div is radio
} else if (ariaControls === "radio") {
// hide the car div
document.getElementById("cat").classList.add("hide");
}
//toggle the hide div on the controlled div
controlledAria.classList.toggle("hide");
}
//select all the buttons
const buttons = document.querySelectorAll("button");
//for each button add an event listener when the button is clicked run the handle click function
buttons.forEach(button => button.addEventListener("click", handleClick))
.hide {
display: none;
}
<div id="dialogue" class="hide">
<div class="room">
Room description here. What do you do?
<div class="buttons">
<button aria-controls="cat">Pet the cat.</button><br>
<div id="cat" class="hide">aw yeah kitty time</div>
<button aria-controls="radio">Turn on the radio.</button><br>
<div id="radio" class="hide">audio file and tracklist here
</div>
</div>
</div>
</div>
<span class="toggle"><button aria-controls="dialogue">[Open/close dialogue.]</button></span>
I'm using elementor for my wordpress site and I wish to have a button in a first div (section) that control if a second and separate div (section) is display or not. I've tried to use the checkbox hack but it's working only if the checkbox is in the div as the content https://css-tricks.com/the-checkbox-hack/
Is there a solution to use CSS or even javascript ? If you advice to me to use javascript I'll put in my function.php file and as I'm begginer in javascript can you please write all the function I have to implement into my function.php file.
Basically it means :
<div>button</div> <div>content to show and hide on click on the button</div>
Best regards,
Clément
You can use Jquery:
1-Put an id to your DIV
<div id = "btn_show"> button </div> <div id = "show"> content to show and hide on click on the button </div>
2-Call jquery to display it
$("#btn_show").click(function(){
$("#show").show();
//or
$("#show").hide();
});
And jquery you can call it with CDN
<script src="https://code.jquery.com/jquery-3.6.0.js"</script>
In javascript without any library this could be very easy but you need to put an id on your divand your button.
<div id="myButton">button</div>
<div id="myDiv">
content to show and hide on click on the button
</div>
Then you just add a script section like this : (it just need to be after your div and your button in the DOM)
<script>
var myDiv = document.getElementById('myDiv');
var myButton = document.getElementById('myButton');
myButton.addEventListener('click', e => {
myDiv.classList.toggle('visible'):
});
</script>
And at last, you need a css like this:
.visible {
display: none;
}
Thanks for all of yours answers! Here what I use:
<button onclick="myFunctionopenclose()">Click Me</button>
<div id="myDiv" style="display:none;">content to hide and show</div>
<script> function myFunctionopenclose() {
var x = document.getElementById("myDiv");
if (x.style.display === "block") {
x.style.display = "none"; }
else {
x.style.display = "block";}}
Best regards,
Clément
I would like to make sure which method is the best and if my code is valid and good.
I did not succeed in renaming the text "hide contact" / "'show contact" to see the result.
.style.display = 'none'; seems a bit too brutal to me without an exit animation.
I opted for the "hide button" version
but if you know how to rename the button it will be a bonus.
I also have jerks on mobile (chrome), I can't understand why .slideToggle is not smooth everywhere.
Method 1 : not working
/* Show/hide rename button text */
jQuery(document).on('click', '#TEST_BTN', function(event) {
event.preventDefault();
$(document).ready(function(){
$("TEST_BTN").click(function(){
if ($(this).text() == 'show contact'){
$(this).html('hide contact;')
}else{
$(this).html('show contact');
}
jQuery('#hidden-content').slideToggle('250','swing','hide');
});
Method 2 : working
/* Hide show contact button */
document.addEventListener("DOMContentLoaded", function(event) {
jQuery('#TEST_BTN').click(function(){
event.preventDefault();
document.getElementById("TEST_BTN").style.display = 'none';
jQuery( '#hidden-content' ).slideToggle('250','swing','hide');
});
});
mmm click inside click for the same element?! it'll not work like this it will add another click event each time you click the element and this is what you'll get after some clicks
var i = 0;
$('button').on('click' , function(){
$('button').click(function(){
console.log(i++);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click Inside Click</button>
Your code should looks like
/* Show/hide rename button text */
$(document).ready(function(){
$("#TEST_BTN").click(function(){
$(this).text($(this).text() == 'show contact' ? 'hide contact': 'show contact')
$('#hidden-content').slideToggle('250','swing','hide');
});
});
I prefer to use classes instead of ids in this case .. It'll much easier especially if you've more than one card .. see the next simple example
/* Show/hide rename button text */
$(document).ready(function(){
$(".TEST_BTN").click(function(){
$(this).text($(this).text().toLowerCase().trim() == 'show contact' ? 'hide contact': 'show contact')
$(this).closest('.card').find('.hidden_content').slideToggle('250','swing','hide');
});
});
.hidden_content{
display : none;
height : 100px;
background : #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">
<button class="TEST_BTN">Show Contact</button>
<div class="hidden_content">Contact Info</div>
</div>
<div class="card">
<button class="TEST_BTN">Show Contact</button>
<div class="hidden_content">Contact Info</div>
</div>
<div class="card">
<button class="TEST_BTN">Show Contact</button>
<div class="hidden_content">Contact Info</div>
</div>
Note: For event.preventDefault() you need to use function(event){ event.preventDefault();
I currently have a setup with three seperate buttons that open three divs. I want one div (namely lockedin) to be open at the start. Furthermore, the divs should close when another is opened by the buttons, which I have accomplished now.
There is one more thing I require and cannot seem to get working properly. Is there a way to show which div is currently active? So when the page is loaded, button2 shows an orange filled button (which I have as an image) and the other two buttons show the white filled button. When another div is selected by means of for example button 1, the button 2 should change to the white filled button, and the button 1 should change to the orange filled button. I have the image SRC's, but just don't know how to select the image based on the active state of its given div.
Thank you in advance.
jQuery(document).ready(function( $ ){
//Start of Jquery
$('.button1').click(function(){
if ($('.product').css('display') === 'none') {
$('.product').slideToggle('slow');
}
$('.developers').slideUp();
$('.lockedin').slideUp();
});
$('.button2').click(function(){
if ($('.lockedin').css('display') === 'none') {
$('.lockedin').slideToggle('slow');
}
$('.product').slideUp();
$('.developers').slideUp();
});
$('.button3').click(function(){
if ($('.developers').css('display') === 'none') {
$('.developers').slideToggle('slow');
}
$('.product').slideUp();
$('.lockedin').slideUp();
});
// End of Jquery
});
.product {
display:none;
color: yellow;
}
.lockedin {
color:yellow;
}
.product_active{
display:none;
}
.developers {
display:none;
color: yellow;
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<img src="http://www.mindaffect.nl/wp-content/uploads/2017/12/product-holder.png" class="button1" alt="Expand"/>
<img src="http://www.mindaffect.nl/wp-content/uploads/2017/12/product_active.png" class="product_active" alt="product_active" />
<img src="http://www.mindaffect.nl/wp-content/uploads/2017/12/lockedin-holder.png" class="button2" alt="Expand"/>
<img src="http://www.mindaffect.nl/wp-content/uploads/2017/12/developers-holder.png" class="button3" alt="Expand"/>
<div class="product">
Testdiv1
</div>
<div class= "lockedin">
Testdiv2
</div>
<div class = "developers">
Testdiv3
</div>
I'm stuck with a jQuery issue that I don't manage to solve.
I've created a menu with sub menu elements. I would like to toggle the height of content by clicking in menu items. The thing is when I click on other item, the content collapse. Kind of tricky to explain, I've put two websites doing the job
http://www.polerstuff.com/ -> When you click on 'shop' and then on 'info', the sub menu stays open. The same trick was seen here http://topodesigns.com/
I guess these two websites are using Shopify.
$(document).ready(function() {
$(".button").on("click", function() {
if($(".content").height() == 0) {
$(".content").animate({height: "300px"});
}
else if($(".content").height() == 300) {
$(".content").animate({height: "0px"});
}
});
});
Here is my jsfiddle
-> Thank a lot in advance.
Here's version of your fiddle that uses the data attribute to target divs with desired content, and another data tag containing desired heights to animate (but there are many other ways).
Clicking on the same button toggles it shut, this is achieved by adding an indicative class.
The 'hiding' divs may contain further divs with classes and layout as required.
$(document).ready(function (){
$(".b").on("click", function (){
var $this = $(this),
target = $this.data('target'),
tall = $this.data('tall'),
content = $(".content");
target = $('.'+target).html(); // get the html content of target divs
content.html(target); // insert said content
if (!$this.hasClass('on')) { // if it hasn't been clicked yet..
$(".b").removeClass('on'); // say that none have been clicked
$this.addClass('on'); // say that just this one has been clicked
content.animate({height: tall}, 200); // animate to the height specified in this buttons data attribute
} else {
content.animate({height: "0px"});
$this.removeClass('on');
}
});
});
.content {
background: coral;
width: 100%;
height: 0px;
overflow:hidden;
}
.hiding{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button class="b" data-target="alpha" data-tall="4em">Button</button>
<button class="b" data-target="bravo" data-tall="7em">Button</button>
<button class="b" data-target="charlie" data-tall="5em">Button</button>
<div class="content">Le contenu</div>
<div class="hiding alpha"> some stuff </div>
<div class="hiding bravo"> other things </div>
<div class="hiding charlie"> bits and pieces </div>