Good time. There is an accordion menu at this link: https://www.w3schools.com/code/tryit.asp?filename=G3Z0U159KFM3
(to see it, you need to click on the green "Run" button)
This is a simple show / hide menu. How to make the default content was expanded and by clicking could hide it? (i.e. the opposite of the current one)
Dears, please help with this problem.
Well, although the way you described your issue wasn't clear, I think you are trying to do the opposite of the code you provided, so you would like the "contents" menu to be shown by default and when you click on it the menu would collapse back.
First you want to set the .active class by default to the .ContentsAccordion button like so :
<button class="ContentsAccordion active">Contents</button>
And then you want to get the height of your menu and put it into the style element of your .ContentsPanel div with this code :
var pan = document.getElementsByClassName("ContentsPanel");
pan[0].setAttribute('style', 'max-height: ' + pan[0].scrollHeight + 'px;');
and the rest of your code doesn't need any change.
Working example below :
<style>
.ContentsAccordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 18px;
transition: 0.4s;
}
button.ContentsAccordion:after {
content: '\002B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
button.ContentsAccordion.active:after {
content: '\2212';
}
.active, .ContentsAccordion:hover {
background-color: #ccc;
}
.ContentsPanel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
border: 1px #ccc solid;
}
.ContentsAccordionP {
font-size: 16px;
}
</style>
<button class="ContentsAccordion active">Contents</button>
<div class="ContentsPanel">
<p class="ContentsAccordionP">Some text 1</p>
<p class="ContentsAccordionP">Some text 2</p>
<p class="ContentsAccordionP">Some text 3</p>
</div>
<script>
var acc = document.getElementsByClassName("ContentsAccordion");
var i;
var pan = document.getElementsByClassName("ContentsPanel");
pan[0].setAttribute('style', 'max-height: ' + pan[0].scrollHeight + 'px;');
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
});
}
</script>
Related
I have an FAQ page on the website I am building right now. I got the faq section from a template. I tried to use Javascript within my NextJs Projekt but it is not working.
var faq = document.getElementsByClassName("faqpage");
var i;
for (i = 0; i < faq.length; i++) {
faq[i].addEventListener("click", function () {
/* Toggle between adding and removing the "active" class,
to highlight the button that controls the panel */
this.classList.toggle("active");
/* Toggle between hiding and showing the active panel */
var body = this.nextElementSibling;
if (body.style.display === "block") {
body.style.display = "none";
} else {
body.style.display = "block";
}
});
}
var cpt = document.getElementsByClassName("faqbody");
var i;
for (i = 0; i < faq.length; i++) {
cpt[i].addEventListener("click", function () {
/* Toggle between adding and removing the "active" class,
to highlight the button that controls the panel */
this.classList.toggle("active");
/* Toggle between hiding and showing the active panel */
var body = this.nextElementSibling;
if (body.style.display === "block") {
body.style.display = "none";
} else {
body.style.display = "block";
}
});
}
.Faq {
background-color: rgba(46,40,35,255);
padding-top: 50px;
padding-bottom: 150px;
}
.Faq h2 {
color: white;
text-align: center;
font-size: 4vh;
margin-bottom: 20px;
}
.faqcontainer{
display: flex;
justify-content: center;
flex-direction: column;
}
.hrline{
width: 62%;
margin: auto;
margin-top: 20px;
}
.faqpage {
cursor: pointer;
padding: 30px 20px;
width: 60%;
border: none;
font-size: 25px;
font-weight: 600;
outline: none;
transition: 0.4s;
margin: auto;
color: #EC2628;
}
.faqbody{
margin: auto;
/* text-align: center; */
width: 50%;
line-height: 30px;
font-size: 20px;
padding: 0 18px;
display: none;
overflow: hidden;
padding-bottom: 20px;
}
.faqpage:after {
content: '\002B';
/* Unicode character for "plus" sign (+) */
font-size: 35px;
font-weight: 100;
color: white;
float: right;
transition-duration: 0.5s;
}
.active:after {
transform: rotate(45deg);
/* Unicode character for "minus" sign (-) */
font-weight: 100;
}
<div className={styles.Faq}>
<h2>FAQ</h2>
<div className={styles.faqone}>
<h1 className={styles.faqpage}>How can I join the community?</h1>
<div className={styles.faqbody}>
<p>We have a very active community and we welcome new members with open arms! Come and chat with us on Discord.</p>
</div>
</div>
<hr className={styles.hrline}/>
<div className={styles.faqtwo}>
<h1 className={styles.faqpage}>How can I join the community?</h1>
<div className={styles.faqbody}>
<p>We have a very active community and we welcome new members with open arms! Come and chat with us on Discord.</p>
</div>
</div>
<hr className={styles.hrline}/>
<div className={styles.faqthree}>
<h1 className={styles.faqpage}>How can I join the community?</h1>
<div className={styles.faqbody}>
<p>We have a very active community and we welcome new members with open arms! Come and chat with us on Discord.</p>
</div>
</div>
<hr className={styles.hrline}/>
<div className={styles.faqfour}>
<h1 className={styles.faqpage}>How can I join the community?</h1>
<div className={styles.faqbody}>
<p>We have a very active community and we welcome new members with open arms! Come and chat with us on Discord.</p>
</div>
</div>
<hr className={styles.hrline}/>
<Script src="../components/FAQLOC.js"></Script>
</div>
I thought it has something to do with the classes and that javascript cannot grab the classes from nextjs but I also don't know how to solve this problem.
The Snippet is so that you can see all of my CODE!
Can someone help me?
Components on Nextjs are all server-side by default so you don't have access to the document object. Have you tried importing your component dynamically and setting SSR to false? https://nextjs.org/docs/advanced-features/dynamic-import
I have a question.
When I click on a specific text button, I want to make the accordion box automatically calculated in height visible.
Now, the accordion box itself works in a way that clicks like a giant button, not a specific text button.
I want to modify the code that the 'active' class will add when the 'text button' is clicked, rather than the 'accordion box' is clicked.
I don't know how. I need your help.
Thank you!
TEST WEBSITE
if (matchMedia("all and (max-width: 812px)").matches) {
} else {
var acc = document.getElementsByClassName("info-box");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this;
if (panel.style.height) {
panel.style.height = null;
} else {
panel.style.height = panel.scrollHeight + "px";
}
});
}
}
.info-box {
display: block;
position: fixed;
bottom: 0;
left: 0;
height: 62px;
width: 100%;
transition: height 0.3s;
background: transparent;
z-index: 99;
}
.shopbtn {
display: inline-block;
position: fixed;
width: auto;
height: auto;
font-size: 12px;
font-weight: 300;
line-height: 12px;
letter-spacing: 1.4px;
z-index: 9999999999;
bottom: 12px;
left: 12px;
cursor: pointer;
text-transform: uppercase;
}
<div class="info-box" style>
<div class="shopbtn">Information</div>
test test test
</div>
I coded a collapsible button using both CSS and JS, and I would like to place a button nested inside another one.
Is it possibile to dynamically adapt the height of the first/external button so that, when the second/internal button is opened, the height of the first one is increased by the height of the second one?
Here is the code I'm working on
coll = document.getElementsByClassName("col");
conn = document.getElementsByClassName("con");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].setAttribute('data-id', 'con' + i);
conn[i].setAttribute('id', 'con' + i);
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = document.getElementById(this.getAttribute('data-id'));
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
.col {
cursor: help;
border: none;
outline: none;
background: none;
padding: 0;
font-size: 1em;
color: green;
border-bottom: 1px dashed;
transition: .3s;
}
.con {
padding: 0 18px;
margin: 3px 0;
max-height: 0;
overflow: hidden;
transition: .3s ease-out;
background-color: #f1f1f1;
box-shadow: 5px 5px 10px 3px inset rgba(0,0,0,0.60);
}
Does <button class=col>this</button> work?
<div class=con>
<p>Yes!</p>
And what about <button class=col>this</button>?
<div class=con>
<p>Yes, but below text is gone!</p>
</div>
<p>bye bye</p>
</div>
There is something to fix.
EDIT: LAZY SOLUTION
In the javascript replace content.scrollHeight with a high value such as 9999.
Drawback: when the button is opened, the transition from 0 to height starts immediately and is super fast since the space to cover is a lot; when the button is closed, the transition starts at max-height (not the actual height) so visually nothing happens from max-height to actual height, resulting in a delay.
coll = document.getElementsByClassName("col");
conn = document.getElementsByClassName("con");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].setAttribute('data-id', 'con' + i);
conn[i].setAttribute('id', 'con' + i);
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = document.getElementById(this.getAttribute('data-id'));
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = 9999 + "px";
}
});
}
.col {
cursor: help;
border: none;
outline: none;
background: none;
padding: 0;
font-size: 1em;
color: green;
border-bottom: 1px dashed;
transition: .3s;
}
.con {
padding: 0 18px;
margin: 3px 0;
max-height: 0;
overflow: hidden;
transition: .3s ease-out;
background-color: #f1f1f1;
box-shadow: 5px 5px 10px 3px inset rgba(0,0,0,0.60);
}
Does <button class=col>this</button> work?
<div class=con>
<p>Yes!</p>
And what about <button class=col>this</button>?
<div class=con>
<p>And the transition is super fast</p>
</div>
<p>Yes but there is a delay if you close it</p>
</div>
There is something to fix.
I think the true solution is in this page, but I'm not able to adapt it to my case.
No need to calculate dynamic height.
Example with button inside button
{}
Need help to fix Javascript Accordion minimize and maximize issue
Steps to reproduce:
A. Happy path works fine:
Click + for Accordion.
Click Yes radio and the div expands showing buttons.
B. Different path fails (need help to fix this part)
Click + for Accordion.
Click No radio and the div expands not showing buttons (works).
Click - now for Accordion.
Click + again for Accordion.
Click Yes radio now and this fails to expand full (**fix/help needed here).
Problematic JSFiddle
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .accordion:hover {
background-color: #b2b2b2;
}
.accordion:after {
content: '\002B';
color: #777;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2212";
}
.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
h1 {
padding: 20px 0;
font-weight: 400;
text-align: center;
}
p {
margin: 0 0 20px;
line-height: 1.5;
}
</style>
<script>
$(document).on("click",'[name=jenkinsgroup1]',function(e){
$('.toHide').hide();
$("#jenkinsgroup-"+$(this).val()).show('slow');
$("#jenkinsgroup").css('background','#e5e5e5');
});
</script>
</head>
<body>
<h2>Accordion</h2>
<button class="accordion">Section 1</button>
<div class="panel">
<div class='col' id='jenkinsgroup'>
<br> Jenkins Integration?
<input type="radio" name="jenkinsgroup1" value="1">
Yes
<input type="radio" name="jenkinsgroup1" value="2">
No
<div id="jenkinsgroup-1" class="toHide" style="display:none color:black">
<br> ServerUrl
<input id="server" type="text" placeholder="Text input">
<br><br> JobName
<input id="jobname" type="text" placeholder="Text input" style="margin-bottom:10px">
</div>
<div id="jenkinsgroup-2" class="toHide" style="display:none color:black">
</div>
</div>
</div>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight){
panel.style.maxHeight = null;
var ele = document.getElementsByName("jenkinsgroup1");
for(var i=0;i<ele.length;i++)
ele[i].checked = false;
$("#jenkinsgroup").css('background','#ffffff');
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
$('.toHide').hide();
}
});
}
</script>
</body>
</html>
try this https://jsfiddle.net/tjb7tcqk/13/
your click listener has been updated, removed clearing the max-height, added a toggle for #jenkinsgroup and $('.toHide').hide(); has been placed outside the if condition
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {debugger
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight){
var ele = document.getElementsByName("jenkinsgroup1");
for(var i=0;i<ele.length;i++)
ele[i].checked = false;
$("#jenkinsgroup").css('background','#ffffff').toggle()
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
$("#jenkinsgroup").show()
}
$('.toHide').hide();
});
}
This updated JS-fiddle solves your problem. Its a very static approach though, since im passing a fixed height of "128px".
$(document).on("click",'[name=jenkinsgroup1]',function(e){
$('.toHide').hide();
$("#jenkinsgroup-"+$(this).val()).show('slow');
$("#jenkinsgroup").css('background','#e5e5e5');
// new code-block
if (this.value == 1) {
$("div.panel").css("maxHeight", "128px");
}
});
As you can see (above) I've inserted a if-clause that fixes the max-height problem for your B-path.
I hope this helps you getting into the right direction to solve the problem.
On a side-note:
I (myself) consider it bad practice to use jQuery and native-JS syantax together. You should stick to either jQuery or native-Js.
I have 2 questions
Please help me understand some JavaScript to create an accordion menu I got from W3Schools
css
<style>
button.accordion_f {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 14px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
button.accordion_f.active, button.accordion_f:hover {
background-color: #ddd;
color: blue;
}
button.accordion_f:after {
content: '\02795';
font-size: 13px;
color: #777;
float: right;
margin-left: 5px;
}
button.accordion_f.active:after {
color: blue;
content: "\2796";
}
div.panel {
padding: 0 14px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: 0.3s ease-in-out;
opacity: 0;
}
div.panel.show {
opacity: 1;
max-height: 6000px;
}
</style>
JavaScript
<script>
var acc = document.getElementsByClassName("accordion_f");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
</script>
Example use
<button class="accordion_f">3rd party compatibility</button>
<div class="panel">
<p>Offers an easy way to connect your Polar training device with 3<sup>rd</sup> party services.</p>
</div>
This works correctly
If I encapsulate this in another class for example in a pill menu it will not expand the menu, the css seems to work, the background shading etc, when I inspect the element I do not see the script, is the parent class affecting document.getElementsByClassName some how?
<ul class="tabs">
<button class="accordion_f">3rd party compatibility</button>
<div class="panel">
<p>Offers an easy way to connect your Polar training device with 3<sup>rd</sup> party services.</p>
</div>
</ul>
How do I put my script into a function and call it with onclick or onmouseover?
I tried:
<button class="accordion_f" onmouseover="accordion_menu()">Activity</button>
<div class="panel">
<p>Tracks your daily activity at five intensity levels for 24 hours a day, seven days a week, and provides a complete picture of all of your activity. It counts your active time, daily burnt calories, steps, distance from steps and sleep.</p>
</div>
function accordion_menu(){
var acc = document.getElementsByClassName("accordion_f");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick.classList.toggle("active");
acc[i].onclick.nextElementSibling.classList.toggle("show");
}
}
This just opened all panels with a class of accordion_f, not just the active one as I would like.
It is working, I.E was in compatibility mode and ie8 had poor support for document.getElementsByClassName