I'm using the W3C accordion on my website, and only want the accordion to be active when the page is under 768px. So far, I have the script adjusted so that the "panel" div's will toggle, but they initially are displayed, rather than hidden. Is there a line I can add to the code to initially hide the panel div's when the resolution is under 768px? I've tried adding display:none to the element in the css sheet, but the toggle script won't override it.
Hope this makes sense!
<script>
if (screen.width < 768) {
var acc = document.getElementsByClassName("filterAccordion");
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.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
}
</script>
I have a feeling you can manage this in CSS..
#media only screen and (max-width: 768px) {
.filterAccordion {
display: none;
}
}
As for the accordian and mentioned by Quentin.. W3Schools is probably not the best source of information.. For general modules like this perhaps Bootstrap(3/4) might be a more ideal framework if you are open to use one at all.
Edit : MediaQueries
Here's a working solution. Please note that I have commented out some code to demonstrate it in desktop view. Please uncomment that and your code should work in "mobile only" scenario.
document.querySelector('.accordion').addEventListener('click', function (e) {
/*if (screen.width < 768) {*/
var currentTarget = e.target;
if (e.target.classList.contains('accordion-title')) {
var allDesc = Array.prototype.slice.call(document.querySelectorAll('.accordion-description'));
allDesc.forEach(function (el) {
el.classList.add('hidden-xs');
});
e.target.nextElementSibling.classList.remove('hidden-xs');
}
/*}*/
});
/*#media only screen and (max-width: 767px) {
.hidden-xs {
display: none;
}
}*/
/* Comment below code and uncomment above */
/* For demo purpose only */
.hidden-xs {
display: none;
}
.accordion-title,
.accordion-description {
padding: 20px;
margin-bottom: 10px;
}
.accordion-title {
background-color: #ccc;
border-radius: 3px;
border: 1px solid;
}
<div class="accordion">
<div class="accordion-title">Title 1</div>
<div class="accordion-description hidden-xs">Some description</div>
<div class="accordion-title">Title 2</div>
<div class="accordion-description hidden-xs">Some description</div>
</div>
Related
I have these accordions that open and close. I'd also like the accordion to scroll to the top of the page when it's clicked.
HTML:
<button class="accordion"><h2>Title</h></button>
<div class="panel">
<p>some text</p>
</div>
Javascript that works to open and close the accordion:
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[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 panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
Javascript I tried to add to make it scroll to the top but it doesn't work:
$('button').click(function() {
$(this).animate({
scrollTop:0
}, 1000);
});
So, I think you can change your approach.
Considering you're using jQuery, your HTML can be like this:
...
<div class="accordion">
<div class="accordion-header">Your accordion header</div>
<div class="accordion-content">Your Accordion Content</div>
</div>
...
your Javascript like this:
function scrollToElement($el, time = 500){
$([document.documentElement, document.body]).animate({
scrollTop: $el.offset().top
}, time);
}
function setupAccordion(){
$('.accordion .accordion-header').click(function(){
let $parent = $(this).parent();
$parent.toggleClass('active');
scrollToElement($parent);
});
}
$(document).ready(function(){
setupAccordion();
});
And your CSS like this:
.accordion-header{
border-bottom:1px solid #ccc;
padding:1em;
cursor:pointer;
font-weight:bold;
}
.accordion-content{
max-height:0;
opacity:0;
visibility:hidden;
transition:all 0.2s ease;
padding:0;
}
.accordion.active .accordion-content{
max-height:500px;
visibility:visible;
opacity:1;
padding:1em;
}
Playground: https://jsfiddle.net/m0fbq2j4/
I'm using this code:
#media screen and (max-width: 850px) {
#side-menu {
display: none;
}
button {
display: block;
}
}
to hide my side menu and display a button when I resize window. I also want to show and hide menu when the button is pressed. To do that I'm using this code:
function showMenu() {
var sideMenu = document.getElementById("side-menu");
if (sideMenu.style.display === "none") {
sideMenu.style.display = "block";
}
else {
sideMenu.style.display = "none";
}
}
When I hide with button the menu does not reappear when I resize window. I believe this is happening because the javaScript changes the primary style to display: none, so once it's out of range it applies the primary style. Now it's display: none so it doesn't appear again. How can I get it to work how I intend it to? Also, it takes two clicks to show menu for some reason.
<ul id="side-menu">
<li>example1</li>
<li>example2</li>
<li>example3</li>
<li>example4</li>
</ul>
html just in case you need it.
You must check if the display === "block" first to fix the multiple click issue.
Included media query to manage window width that is greater than 850px to show list and hide button.
EDIT: updated snippet to use the list provided in the original question.
function showMenu() {
var sideMenu = document.getElementById("side-menu");
if (sideMenu.style.display === "block") {
sideMenu.style.display = "none";
}
else {
sideMenu.style.display = "block";
}
}
#media screen and (min-width: 850px) {
#side-menu {
display: block;
}
button {
display: none;
}
}
#media screen and (max-width: 850px) {
#side-menu {
display: none;
}
button {
display: block;
}
}
<div id="side-menu">
<ul>
<li>example1</li>
<li>example2</li>
<li>example3</li>
<li>example4</li>
</ul>
</div>
<button onclick="showMenu()">click me</button>
//swap none with block to fix double button press
function showMenu() {
var sideMenu = document.getElementById("side-menu");
if (sideMenu.style.display === "block") {
sideMenu.style.display = "none";
}
else {
sideMenu.style.display = "block";
}
}
/* add this to fix menu show*/
#media screen and (min-width: 850px) {
#side-menu {
display: block !important;
}
button {
display: none;
}
}
#media screen and (max-width: 850px) {
#side-menu {
display: none;
}
button {
display: block;
}
}
<div id="side-menu">
<ul>
<li>example1</li>
<li>example2</li>
<li>example3</li>
<li>example4</li>
</ul>
</div>
<button onclick="showMenu()">click me</button>
Thanks ksa and StackSlave
The drop-down menu works fine on the laptop.
On the mobile device it comes up as a single bar. When I select the hamburger icon, the drop-down are displays as they should. When I select one of the buttons, the link works. But if I instead hit the hamburger icon the second time, the hamburger and complete bar disappear. The only way to bring the navbar back is to do a browser refresh.
I have tried several responsive navbar code selections and this is the closest to a working responsive navbar.
HTML code
...
<nav>
<div class="topnav" id="myTopnav">
Home
New Here
<div class="dropdown">
<button class="dropbtn">Ministries
<i class="fa fa-caret-down"></i>
</button>
<div class="dropdown-content">
Adult
Member Care
Outreach
Youth
</div>
</div>
Donate
...
Contact
About
☰
</div>
</nav>
CSS code
...
/* When the screen is less than 600 pixels wide, hide all links, except for the first one ("Home"). Show the link that contains should open and close the topnav (.icon) */
#media screen and (max-width: 600px) {
.topnav a:not(:first-child), .dropdown .dropbtn {
display: none;
}
.topnav a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens (display the links vertically instead of horizontally) */
#media screen and (max-width: 600px) {
.topnav.responsive {position: relative;}
.topnav.responsive a.icon {
position: absolute;
right: 0;
top: 0;
}
.topnav.responsive a {
float: none;
display: block;
text-align: left;
}
.topnav.responsive .dropdown {float: none;}
.topnav.responsive .dropdown-content {position: relative;}
.topnav.responsive .dropdown .dropbtn {
display: block;
width: 100%;
text-align: left;
}
}
...
javascript code
/* Toggle between showing and hiding the navigation menu links when the user clicks on the hamburger menu / bar icon */
function navBarIcon() {
var x = document.getElementById("myTopnav");
if (x.className === "topnav") {
x.className += " responsive";
} else {
x.className = "topnav";
}
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
//* Loop through all dropdown buttons to toggle between hiding and showing its dropdown content - This allows the user to have multiple dropdowns without any conflict */
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
for (i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", function() {
this.classList.toggle("active");
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
});
}
As I mentioned, the code works except when the hamburger icon is hit a second time to close the navbar. It goes beyond closing, but rather disappears.
Modified javascript and it works now.
/* Toggle between showing and hiding the navigation menu links when the user clicks on the hamburger menu / bar icon */
function navBarIcon() {
var x = document.getElementById("myTopnav");
if (x.className === "topnav") {
x.className += " responsive";
} else {
x.className = "topnav";
}
}
//* Loop through all dropdown buttons to toggle between hiding and showing its dropdown content - This allows the user to have multiple dropdowns without any conflict */
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
for (i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", function() {
this.classList.toggle("active");
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
});
}
//Overlay mobile menu open
$('#burger-icon').on('click', function(e) {
e.stopPropagation();
document.getElementById('fp-menu').style.height = "100%";
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
if (screen.width < 1000) {
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "white";
}
//changes the social icons to white if in mobile view.
document.getElementById('instagram').src = "instagram_white.svg";
document.getElementById('linkedin').src = "linkedin_white.svg";
document.getElementById('twitter').src = "twitter_white.svg";
//gets rid of the pipe in menu that is visible for the desktop version
//removes sidetabs while in overlay menu
pipe.style.display = "none";
contact.style.display = "none";
case_studies.style.display = "none";
//changes how the elements are displayed when overlay is triggered
$('#fp-menu .news').removeClass("col-sm-2");
$('#fp-menu .portfolio').removeClass("col-sm-3");
$('#fp-menu #social').removeClass("col-sm-6");
}
});
function closeOverlayMenu() { //closes the overlay mobile menu
// e.stopPropagation();
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "black";
}
//changes icons to black on slide up of overlay
document.getElementById('instagram').src = "instagram.svg";
document.getElementById('linkedin').src = "linkedin.svg";
document.getElementById('twitter').src = "twitter.svg";
//restores elements of the original homepage that were hidden for overlay
pipe.style.display = "block";
contact.style.display = "block";
case_studies.style.display = "block";
$('#fp-menu .news').addClass("col-sm-2");
$('#fp-menu .portfolio').addClass("col-sm-3");
$('#fp-menu #social').addClass("col-sm-6");
};
document.getElementsByTagName('body')[0].onresize = function() {
closeOverlayMenu();
};
//overlay mobile menu close
$('#closebtn').on('click', function(e) {
e.stopPropagation();
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
//if overlay mobile menu is down, close it by clicking the X
if (screen.width < 1000) {
closeOverlayMenu();
console.log(document.querySelectorAll("#social"));
}
});
//overlay menu styling
.overlay {
height: 0;
width: 100%;
position: fixed;
z-index: 999;
top: 0;
left: 0;
background-color: #000000;
overflow-x: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
top: 5%;
width: 100%;
text-align: center !important;
margin-top: 90px;
.row{
padding: 50px 30px 50px 30px;
.column{
float: left;
width: 33.33%;
padding: 0 5px 0 5px;
}
}
img {
width: 50px;
}
div {
padding: 30px 0 30px 0;
}
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #FFFFFF;
}
.overlay a:hover, .overlay a:focus {
color: #f1f1f1;
}
#closebtn {
display:block;
position: relative;
top: 5px;
right: 20px;
font-size: 60px;
}
#social{
position: relative;
top: 10px;
a {
padding: 5% 5% 5% 5%;
}
}
#fp-menu{
display: block;
color: $menu_black;
}
.pipe{
display: block;
transition: 0.4s;
}
<div id="fp-menu" class="overlay">
<div id="closebtn" style="color: white;">X</div>
<div class="column overlay-content">
<!-- <div class="column"> -->
<div class="col-sm-2 news">
NEWS
</div>
<div class="col-sm-1 pipe">
|
</div>
<div class="col-sm-3 portfolio">
PORTFOLIO
</div>
<div id="social" class="col-sm-6">
<img id="instagram" src='instagram.svg' />
<img id="linkedin" src='linkedin.svg' />
<img id="twitter" src='twitter.svg' />
</div>
</div>
</div>
So the weirdest thing, I've got 1 function that is to trigger under 2 conditions: when the window is resized and when the exit button is clicked.
This relates to an overlay menu that's actually intended for mobile users.
The functions work as they are supposed to, in both cases, when I have the inspection console open in chrome. However, when I close this and return to the normal browser window, the functions cease to execute.
On the mobile it is fine. I have only encountered this problem on the desktop/laptop (as I tried it on different desktops [iMacs] and 2 laptops [Macbooks, but the type of hardware I don't think matters]).
Currently the icons in the "#social" div are not being changed to white, which is what I expect to happen when opened, and when closed, they return to black. They are staying black throughout the execution.
Has anyone ever experienced this before? This is related to a Wordpress platform site. Totally custom built, no themes.
Please let me know if this description helps. If any code is needed, please let me know.
Ps: I thought it was a caching problem, on the terminals or on the server, and I cleared the cache on both but the issue still persists.
function closeOverlayMenu(){//closes the overlay mobile menu
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "black";
}
//changes icons to black on slide up of overlay
document.getElementById('instagram').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/instagram.svg";
document.getElementById('linkedin').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/linkedin.svg";
document.getElementById('twitter').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/twitter.svg";
//restores elements of the original homepage that were hidden for overlay
pipe.style.display="block";
contact.style.display="block";
case_studies.style.display="block";
$('#fp-menu .news').addClass("col-sm-2");
$('#fp-menu .portfolio').addClass("col-sm-3");
$('#fp-menu #social').addClass("col-sm-6");
};
I would expect that the function would trigger without the dev console being active. Please let me know if any further description or information would help.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm trying to apply CSS to a specific class when clicking on a <a href="" class="" id="">
I'm using a modal which it should cover the whole screen when clicked but for some reason when clicked, everything is covered except the Header (logo/menu).
What I wanted to do is apply z-index when I click on the modal and apply a revert z-index when I close the modal when clicking the x button.
Is something that it can be done?
Yes, I've tried to find something that I can use but no luck at all.
Update:
EXAMPLE HERE
If you see the photo, you'll see that the x button is behind the MENU.
<a class="vPlay vPlay-btn clickformodal" href="#modal-our-work-1" data-toggle="modal" data-video="241737557"><img src="/wp-content/uploads/2018/04/play1.png" /></a>
When this is clicked, the modal opens.
Now the idea is to apply a z-index to the header so it doesn't go above the modal as in the photo, but only when this button is clicked ( or better said for that id="clickformodal" )
Then, when a close button is clicked, to apply another z-index style to the header so it appears when modal is closed.
Does it make sense?
another update:
tried this code from a user suggestion but not working
let open = document.selectElementByClassName("clickformodal");
let header = document.selectElementByClassName("mk-header");
let close = document.selectElementByClassName("close");
open.addEventListener('click', function () {
header.classList.add("headerbefore");
});
close.addEventListener('click', function () {
header.classList.remove("headerafter");
});
Thanks!!! :)
let open = document.getElementByClassName("class-name-of-open-button")[0];
let header = document.getElementByClassName("class-name-of-header")[0];
let close = document.getElementByClassName("class-name-of-x-button")[0];
open.addEventListener('click', function () {
header.classList.add("newStyle");
})
close.addEventListener('click', function () {
header.classList.remove("newStyle");
})
//in css file
newStyle {
z-index: -9999;
}
If using ids instead of classes use selectElementById instead of selectElementByClassName. You can also use querySelectorAll which should cover either.
If that doesn't work, try posting your css classes/ids that are applied to the header. There could be something funky there causing it.
Give your modal an id in the html, and target it with JS.
<button id="open-modal">Open Modal</button>
<div id="modal">
/* Other elements */
</div>
Javascript would look something like this:
const openModal = document.getElementById('open-modal');
const modal = document.getElementById('modal');
openModal.addEventListener('click', function () {
modal.style.zIndex = '1000';
})
Hello try the code below, added some comments to help you figure out what to do.
<div class="modal" id="my-modal">
hello
</div>
<button data-toggle="modal" data-target="my-modal">Toggle</button>
<style>
.addIndex { z-index: 9999999; }
.modal{position: absolute; top: -100%; left: 0; background: rgba(0,0,0,0.3);
z-index: 9999; width: 100%; height: 100%; transition: all 0.5s ease-in-out; }
.modal.show{top: 0;}
</style>
<script>
var modal = document.querySelectorAll("*[data-toggle=modal]");
[].forEach.call(modal, function(md){
if (md.hasAttribute('data-target'))
{
var target = md.getAttribute("data-target");
var loadtarget = document.getElementById(target);
//open modal
md.addEventListener("click", function(e){
// add css addIndex class name to modal
// it then become class="modal show addIndex"
loadtarget.className += 'show addIndex';
var closebtn = document.createElement("span");
closebtn.className = "closebtn";
closebtn.innerHTML = '×';
loadtarget.appendChild(closebtn);
// close modal
closebtn.addEventListener("click", function(){
// revert to original css class name
// it become class="modal"
loadtarget.className = "modal";
loadtarget.removeChild(closebtn);
});
});
}
});
</script>
Hope this helps; Happy coding
It would probably be best to use Vue or something like that but here's what I came up with just using vanilla JS. Hope it helps!
(function() {
// makeshift router
function changeView(num) {
var views = document.querySelectorAll('div.view');
for (var x = 0; x < views.length; x++) {
views[x].style.display = 'none';
}
document.getElementById('view-' + num).style.display = 'block';
}
// event listeners for links
var links = document.querySelectorAll('div.navbar-link');
for (var x = 0; x < links.length; x++) {
links[x].onclick = function() {
changeView(parseInt(this.getAttribute('data-view')));
}
}
// load init view
changeView(1);
})();
div.view {
position: absolute;
height: 100%;
width: 100%;
z-index: 0;
box-sizing: border-box;
padding: 50px 15px;
color: #FFF;
display: none;
}
div#navbar {
position: absolute;
top: 0px;
z-index: 1;
width: 100%;
background-color: yellow;
}
div#navbar div {
display: inline-block;
cursor: pointer;
margin: 5px 15px;
}
div#navbar div:hover {
opacity: 0.5;
}
div#view-1 {
background-color: red;
}
div#view-2 {
background-color: blue;
}
div#view-3 {
background-color: green;
}
<div id="navbar">
<div class="navbar-link" data-view="1">Homepage</div>
<div class="navbar-link" data-view="2">Projects</div>
<div class="navbar-link" data-view="3">Contact</div>
</div>
<div id="view-1" class="view">Homepage</div>
<div id="view-2" class="view">Projects</div>
<div id="view-3" class="view">Contact</div>