How to back to className when menu is hide - javascript

I would like to make mobile menu witch changing background color and height from(10% to 100%. When menu is active nav—active hover all page for darkening)
const nav = document.getElementById("navigation");
const burger = document.getElementById("mobileBurger");
const menu = document.getElementById("mobileMenu");
burger.addEventListener("click", function() {
nav.classList.toggle("nav--active");
if (nav.classList.contains("nav--scroll")) {
nav.classList.remove("nav--scroll");
}
console.log(nav.classList.contains("nav"));
});
window.addEventListener("scroll", function() {
let scrolled = window.pageYOffset;
if (scrolled >= 40) {
nav.classList.add("nav--scroll");
} else nav.classList.remove("nav--scroll");
});
When nav is „nav—scrolled”, and I click on button, then I would like to leave only class=„nav nav—active”. Ok I did this, but how to back to „nav—scrolled” after hide menu. Of course only when it had this class?

I took a stab at it for you, but the html would be helpful to test it.
Notice moved the scroll check to a separate function to call when needed.
const nav = document.getElementById("navigation");
const burger = document.getElementById("mobileBurger");
const menu = document.getElementById("mobileMenu");
burger.addEventListener("click", function() {
// toggle returns a true or false based on if it adds/removes
if( nav.classList.toggle("nav--active") == false) {
// if it added (made inactive), lets check and see if scroll also applies.
checkScrolled();
} else {
if (nav.classList.contains("nav--scroll")) {
nav.classList.remove("nav--scroll");
}
}
console.log(nav.classList.contains("nav"));
});
window.addEventListener("scroll", function() {
checkScrolled();
});
function checkScrolled() {
let scrolled = window.pageYOffset;
if (scrolled >= 40 && nav.classList.contains("nav--scroll") == false) {
nav.classList.add("nav--scroll");
} else {
nav.classList.remove("nav--scroll");
}
}

Related

Javascript not functioning when clicking the back button

I have this code in place
let showAboutSection = () => {
if(userInfo.logged && userInfo.subscriber && !userInfo.in_trial) {
let section = document.querySelector('.cbt-tabs')
if(section) {
if(!section.classList.contains('touched')) {
section.style.display = 'block'
section.classList.add('touched')
return
}
}
}
setTimeout(showAboutSection, 500)
}
showAboutSection()
But if you click on the back button or on one of my navigation tabs without refreshing the screen, it does not function. Please help!

Nav Shrink on Scroll or Resize

I'm trying to apply a series of classes to a nav that cause it to shrink if the window is either resized or scrolled passed a certain point. However, I believe my conditions are cancelling each other out, and I'm not sure how to structure the if-statements or if it is better to just pass a variable.
Here's what I am trying to accomplish:
If the window is resized between a certain set of media queries, shrink the nav
If the window is outside of those break-points, and the user scrolls passed 1 (I used one just for example purposes in my code so I could see it right away) the nav will shrink and if they scroll up again, it will become it's full size
My code is here:
$(document).ready(function() {
var logo = $('.logo');
var topLevelListItems = $('.mainNav li');
var navShrink = false;
var mQ = window.matchMedia( '(min-width: 100px) and (max-width: 770px)' );
$(window).resize(function() {
if ( mQ.matches ) {
$('nav').addClass('shrink');
$('.nav-fixedWidth').addClass('shrink');
logo.addClass('shrink');
topLevelListItems.addClass('shrink');
navShrink = true;
}
else{
$('nav').removeClass('shrink');
$('.nav-fixedWidth').removeClass('shrink');
logo.removeClass('shrink');
topLevelListItems.removeClass('shrink');
navShrink = false;
}
});//end of resize function
$(window).onscroll(function(){
if( !(mQ.match) && $(this).scrollTop >= 1 ) {
$('nav').addClass('shrink');
$('.nav-fixedWidth').addClass('shrink');
logo.addClass('shrink');
topLevelListItems.addClass('shrink');
navShrink = true;
} else {
$('nav').removeClass('shrink');
$('.nav-fixedWidth').removeClass('shrink');
logo.removeClass('shrink');
topLevelListItems.removeClass('shrink');
navShrink = false;
}
});//end of scroll function
});//end of doc
Could it simply be a typo in your onscroll function?
i.e you have:
if( !(mQ.match) && $(this).scrollTop >= 1 ) { ...
should it not be:
if( !(mQ.matches) && $(this).scrollTop >= 1 ) { ...

Restore scroll position after mobile menu is closed

I'm having a mobile menu that opens and closes using jquery by adding a css class that has display:block while the menu div has display:none.
The jquery code has a part where it is supposed to close the menu when a click is registered outside the menu div. Everything works execept the: $("body").scrollTop(scrollpos) . This was supposed to scroll the user back where he left off after the scrollTop(0) took place and the menu has closed, but it does not scroll at all the scroll is stuck at the top. Any help will be appreciated. Thank you.
EDIT: Here is an example: https://jsfiddle.net/mufwwudj/
$(function () {
var menutoggle = $(".menu-toggle");
var sidenav = $(".side-nav");
menutoggle.click(function () {
var scrollpos = $('body').scrollTop();
if (!$("body").hasClass("m-nav-open")) {
$("body").scrollTop(0).addClass("m-nav-open");
}
$(document).mouseup(function (e){
if (!sidenav.is(e.target) && sidenav.has(e.target).length === 0 && !menutoggle.is(e.target) && menutoggle.has(e.target).length === 0){
if ($("body").hasClass("m-nav-open")) {
$("body").scrollTop(scrollpos).removeClass("m-nav-open");
}
}
});
});
});
One problem here is that you are assigning a new mouseup event every time the menutoggle.click function runs.
$(document).mouseup(function (e){
if (!sidenav.is(e.target) && sidenav.has(e.target).length === 0 && !menutoggle.is(e.target) && menutoggle.has(e.target).length === 0){
if ($("body").hasClass("m-nav-open")) {
$("body").scrollTop(scrollpos).removeClass("m-nav-open");
}
}
});
Only the first one passes the conditional, even though each one will fire and scrollpos will always equal whatever it was in the first mouseup event listener.
I don't know how you are testing it, or what the HTML looks like but if you are at the top of the page the first time you click it, scrollpos in the mouseup event will always be 0.
Try assigning the mouseup event once, and putting scrollpos outside both so it can be accessed in both.
$(function () {
var menutoggle = $(".menu-toggle");
var sidenav = $(".side-nav");
var scrollpos;
menutoggle.click(function () {
scrollpos = $('body').scrollTop();
if (!$("body").hasClass("m-nav-open")) {
$("body").scrollTop(0).addClass("m-nav-open");
}
});
$(document).mouseup(function (e){
if (!sidenav.is(e.target) && sidenav.has(e.target).length === 0 && !menutoggle.is(e.target) && menutoggle.has(e.target).length === 0){
if ($("body").hasClass("m-nav-open")) {
$("body").scrollTop(scrollpos).removeClass("m-nav-open");
}
}
});
});
function ScrollOnTopo() {
window.scrollTo(0, 0); //It scrolls page at top
}
This function may be useful to you.

React.js Scroll Threshold for Revealing Navigation

Using React.js, another dev wrote this code to toggle the appearance of a navigation element called ArticleNav. It reveals itself as your scrolling down but hides itself when you scroll back up.
onScroll: function () {
var mainColumn = document.getElementsByClassName('main-column')[0];
var firstTextElement = mainColumn.querySelector('.dek');
if (!firstTextElement) {
firstTextElement = mainColumn.querySelector('.body-text');
}
if (window.scrollY >= firstTextElement.offsetTop) {
if (!this.state.hideForArticleNav) {
this.setState({hideForArticleNav: true});
}
} else {
if (this.state.hideForArticleNav) {
this.setState({hideForArticleNav: false});
}
}
}
This works great but the use of if (window.scrollY >= firstTextElement.offsetTop) makes this jump back and forth too rapidly and I wanted to create a, let's say..., 50px threshold to confirm that the user is actually scrolling in the opposite direction.
Do y'all have any recommendations on how to approach this? I am more jQuery-minded than React, so all of my normal fixes don't exactly translate here.
I feel like I'm missing part of your question. Can't you simply add 50 px to the firstTextElement.offsetTop?
window.scrollY >= firstTextElement.offsetTop + 50
It sounds like you have a good setup to determine whether the user is scrolling up or down, so instead of setting this.state.hideForArticleNav you could set this.state.lastDirectionChangeOffset to the current window offset when the direction changes. Then you can check against that state value to see if it's +/- 50px.
onScroll: function () {
var mainColumn = document.getElementsByClassName('main-column')[0];
var firstTextElement = mainColumn.querySelector('.dek');
if (!firstTextElement) {
firstTextElement = mainColumn.querySelector('.body-text');
}
if (window.scrollY >= firstTextElement.offsetTop) {
if (!this.state.hideForArticleNav) {
this.setState({ lastDirectionChangeOffset: window.scrollY });
}
} else {
if (this.state.hideForArticleNav) {
this.setState({ lastDirectionChangeOffset: window.scrollY });
}
}
if (window.scrollY > this.state.lastDirectionChangeOffset + 50) {
this.setState({ hideForArticleNav: true })
} else if (window.scrollY < this.state.lastDirectionChangeOffset - 50) {
this.setState({ hideForArticleNav: false })
}
}

Having trouble in speeding up scroll animation using javascript

I have below code. What it does is when user scrolls up/down the contents of the div scrolls accordingly but smoothly. At the moment, the code works ok but the scrolling up/down animation is too slow. How can I make it a bit faster?
Below is JS code
function onMouseScroll (e) {
var detail = e.detail,
wheelDelta = e.wheelDelta;
if (detail) {
if (wheelDelta && (f = wheelDelta/detail)) {
detail = detail/f;
} else {
detail = -detail/1.35;
}
} else {
detail = wheelDelta/120;
}
scroll(offset + detail);
e.preventDefault();
e.stopPropagation();
return false;
}
You can change the speed at line 23. If you decrease the number, the speed increases.
detail = wheelDelta/120;

Categories