I created this function to handle the toggle for my mobile nav.
const mobileNav = document.getElementById('mobile-nav');
let tabs = document.getElementsByClassName('nav_tabs');
//nav toggle control
mobileNav.onclick = (event) => {
event.preventDefault();
for(let i = 0; i < tabs.length; i++) {
if(tabs[i].style.display === "block"){
tabs[i].style.display = "none";
} else {
tabs[i].style.display = "block";
}
}
};
It's working on great on mobile. The problem is when I resize, the toggle is still set to display none and the toggled menu options are not visible. I have tried using this JS Media Query to reset the display block based on a min-width of 786px but it is not reseting the menu.
// media query event handler
if (matchMedia) {
const dsktp = window.matchMedia("(min-width: 768px)");
dsktp.addListener(WidthChange);
WidthChange(dsktp);
}
function WidthChange(elem) {
for(let i = 0; i < elem.length; i++) {
tabs[i].style.display = "block";
}
}
Here's a codepen of the problem.
Your code does not work because of this code (pay attention to the comments):
if (matchMedia) {
const dsktp = window.matchMedia("(min-width: 768px)");
dsktp.addListener(WidthChange); // <-- add function as handler
WidthChange(dsktp);
}
function WidthChange(elem) { // elem argument it is not the dom elements here
for(let i = 0; i < elem.length; i++) {
tabs[i].style.display = "block";
}
}
So you should rewrite your code this way:
if (matchMedia) {
const dsktp = window.matchMedia("(min-width: 768px)");
dsktp.addListener(WidthChange);
WidthChange(dsktp);
}
function WidthChange(mediaQueryEvent) {
for(let i = 0; i < tabs.length; i++) {
tabs[i].style.display = mediaQueryEvent.matches ? "block" : "none";
}
}
Check my fork of your pen.
Related
I wanted to make a specific form show and the other forms disappear when I click on one of four dropdown buttons. When I tested the code, no from is showing when I clicked on a button.
Here is my javascript code:
function showClass(className)
{
var allItems = document.getElementsByClassName('change-form');
for (var i = 0; i < allItems.length; i++)
{
allItems[i].style.display = "none";
}
var formItems = document.getElementsByClassName(className);
for (var i = 0; i < formItems.length; i++)
{
formItems[i].style.display = "block";
}
}
It shows the form if I remove the top for loop.
Edit: Sorry guys I made a typo
Your code is going in and hiding all the items and then showing them right away. What you want to do is split the hide and show into different functions to trigger them at different times.
function showClass(className)
{
var formItems = document.getElementsByClassName(className);
for (var i = 0; i < formItems.length; i++)
{
formItems[i].style.display = "block";
}
}
function hideClass(className){
var allItems = document.getElementsByClassName(className);
for (var i = 0; i < allItems.length; i++)
{
allItems[i].style.display = "none";
}
}
If you want to be able to swap them with one function you could use this:
function swapHide(className){
var firstItem = document.getElementsByClassName(className)[0];
var isDisplayed = firstItem.style.display == "block"
if(isDisplayed){
hideClass(className);
}else{
showClass(className)
}
}
I wrote some JS that involves targeting the DOM, specifically a text input form. It only changes the display for the last element of the array when the user types in 95827. If the user types in 95828 or 95604, the display isn't filtered properly.
Here's a link to the full code.
I was told it may have to do with the removeDisplay function and how it's iterating through display (divs), but still can't manage to fix it.
Still new to DOM Manipulation.
var display = document.querySelectorAll(".display");
var zipCodeSearch = document.querySelector("#site-search");
var ants = document.querySelector("#ants");
const antZipCodes = [95828, 95604, 95827];
zipCodeSearch.addEventListener('change', function(e) {
// for(var i = 0; i < antZipCode.length; i++) {
// if(antZipCode[i] === Number(e.target.value)) {
// removeDisplay(displayNone);
// addDisplay(ants);
// }
// }
pestDisplay(antZipCodes, ants, display, e);
});
function removeDisplay(items) {
for(var i = 0; i < items.length; i++) {
items[i].style.display = "none";
}
}
function addDisplay(item) {
item.style.display = "block";
}
function displayAll(items) {
for(var i = 0; i < items.length; i++) {
items[i].style.display = "block";
}
}
function pestDisplay(arr, id, display, e) {
for(var i = 0; i < arr.length; i++) {
if(arr[i] === Number(e.target.value)) {
removeDisplay(display);
addDisplay(id);
} else {
displayAll(display);
}
}
}
function albumCoverDisplay() {
var i = 0;
for (i = 0; i < albumCover.length; i++) {
albumCover[i].addEventListener("click", function() {
for (var i = 0; i < albumCover.length; i++) {
albumInfo[i].style.display = "none";
}
albumInfo[i].style.display = "block";
});
}
}
Looks like you want to be able to hide other albumCover elements on clicking one of them.
There are a couple of mistakes
Your inner for-loop re-localize the scope of i, use different variable
i's value (assuming another variable is used in inner for-loop) will not remain same when the click will happen.
Make it
function albumCoverDisplay()
{
for (let i = 0; i < albumCover.length; i++) //use let instead of var
{
albumCover[i].addEventListener("click", function() {
for (var j = 0; j < albumCover.length; j++)
{
albumInfo[j].style.display = "none";
}
albumInfo[i].style.display = "block";
});
}
}
I've with inspect with my navigator my script and I finded the problem but I can't resolve this.
When, I've click on my element, he open a list, if click outside of this dropdown (On the document.body) and once again I click on this dropdown I can't selected a new value on my list. I think it's probably on my object.
let open = document.querySelectorAll('.sub-container div');
for (let loop = 0; loop < open.length; loop++) {
open[loop].addEventListener('click', () => {
let tabLi = {};
let list = open[loop].querySelectorAll('.tryit li')
let cross = open[loop].querySelector('h3 .clear-filters');
for (let l = 0; l < list.length; l++) {
list[l].addEventListener('click', (e) => {
e.stopPropagation();
if (!list[l].classList.contains('active-dropdown')) {
list[l].classList.add('active-dropdown');
tabLi[l] = list[l];
console.log(tabLi)
cross.style.display = 'block';
} else {
list[l].classList.remove('active-dropdown');
delete tabLi[l];
if (Object.keys(tabLi).length === 0) {
cross.style.display = 'none';
}
}
});
cross.addEventListener('click', (e) => {
e.stopPropagation()
list[l].classList.remove('active-dropdown');
delete tabLi[l];
cross.style.display = 'none';
})
}
})
}
I wrote this line of code to animate the pictures on my webpage:
var SlideShow = function (container) {
this.images = [];
this.curImage = 0;
for (i = 0; i < container.childElementCount; i++) {
this.images.push(container.children[i]);
this.images[i].style.display = "none";
}
var nextSlide = function(){
for (var i = 0; i < this.images.length; i++) {
this.images[i].style.display = "none";
}
this.images[this.curImage].style.display = "block";
this.curImage++;
if (this.curImage >= this.images.length) {
this.curImage = 0;
}
window.setTimeout(nextSlide.bind(this), 3000);
};
nextSlide.call(this);
};
SlideShow(document.getElementById("testslide"));
The slide show works, pictures change but the style is boring. I want it to either slide in from the right to the left or fade in or something similar, any style at all other than just changing. How do I achieve this?