I stumbled upon an issue with a menu that I want to open by adding a "Open" class when scrolled above certain value. The issue is that I want it to open only ONCE after that value so it appears for the user, and then is up to the user to open and close it by a toggle.
I used this method:
<script type="text/javascript">
jQuery(function() {
//caches a jQuery object containing the header element
jQuery(window).scroll(function() {
var scroll = jQuery(window).scrollTop();
if (scroll >= 1150) {
jQuery(".menubar").addClass("open");
}
});
});
</script>
The issue is that after the 1150 value, it keeps poping up after every scroll within this value.
How do I make it stop and make this event happen only once?
Thank you in advance!
Check if the class is already existing. Or use a variable if the class changes too easily:
var isOpened = false;
jQuery(function() {
//caches a jQuery object containing the header element
jQuery(window).scroll(function() {
var scroll = jQuery(window).scrollTop();
// The original if statement, testing for `.hasClass()`
// if (scroll >= 1150 && !$(".menubar").hasClass()) {
if (scroll >= 1150 && !isOpened) {
isOpened = true;
jQuery(".menubar").addClass("open");
}
});
});
You can set a flag and then just check against that flag.
jQuery(function() {
var menuBarOpenedOnce = 0;
//caches a jQuery object containing the header element
jQuery(window).scroll(function() {
var scroll = jQuery(window).scrollTop();
if (scroll >= 1150 && menuBarOpenedOnce === 0) {
jQuery(".menubar").addClass("open");
menuBarOpenedOnce = 1;
}
});
});
Related
This is a #id link to one page:
This is the #id link to another:
I have WP Rocket Installed, have tried to disable the JS settings but it didn't work either.
I am a novice so your advise is much appreciated.
// PAGE SCROLLER
// PUSHES ANCHOR BELOW DEPTH OF NAVBAR
(function($){
$(document).ready(function () {
$(document).on('click','.navbar-collapse.in',function(e) {
if( $(e.target).is('a') && $(e.target).attr('class') != 'dropdown-toggle' ) {
$(this).collapse('hide');
}
});
function scroll_if_anchor(href) {
href = typeof(href) == "string" ? href : $(this).attr("href");
if (screen.width <= 320) {
var fromTop = 120;
} else if (screen.width <= 768) {
var fromTop = 124;
} else {
var fromTop = 90;
}
// If our Href points to a valid, non-empty anchor, and is on the same page (e.g. #foo)
// Legacy jQuery and IE7 may have issues: http://stackoverflow.com/q/1593174
if(href.indexOf("#") == 0) {
var $target = $(href);
// Older browser without pushState might flicker here, as they momentarily
// jump to the wrong position (IE < 10)
if($target.length) {
$('html, body').animate({ scrollTop: $target.offset().top - fromTop });
if(history && "pushState" in history) {
history.pushState({}, document.title, window.location.pathname + href);
return false;
}
}
}
}
// When our page loads, check to see if it contains and anchor
scroll_if_anchor(window.location.hash);
// Intercept all anchor clicks
$("body").on("click", "a", scroll_if_anchor);
});
})(jQuery);
First you need to check the error $ is not a function (https://prnt.sc/12ald0n) and need to solve it. For better example you can take reference from here https://api.jquery.com/scrolltop/ to scroll top functionality.
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 ) { ...
I have a working script which adds a class to the body after scrolling 80px.
This works but I need it to work too after having already scrolled and then refreshing the page.
So maybe replace the scroll part by position?
// fixed header
$(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 80) {
$("body").addClass('fixed');
} else {
$("body").removeClass("fixed");
}
});
});
$(window).scroll will only fire once a scroll event occurs. If you want to check for the scroll position when the page loads, you should do this outside of the $(window).scroll callback, like this:
function updateScroll() {
if ($(window).scrollTop() >= 80) {
$("body").addClass('fixed');
} else {
$("body").removeClass("fixed");
}
}
$(function() {
$(window).scroll(updateScroll);
updateScroll();
});
you're right. you need to check the event and the initial value:
window.addEventListener('load', function() {
var scroll = $(window).scrollTop();
if (scroll >= 80) {
$("body").addClass('fixed');
}
//no removing needed cause refresh did it
});
window.onscroll = function () { scrollFunction() };
function scrollFunction() {
if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) {
document.querySelector(".fixed-top").classList.add("headerFix");
} else {
document.querySelector(".fixed-top").classList.remove("headerFix");
}
}
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.
I have 4 divs like;
<div class="diva">diva</div>
<div class="divb">divb</div>
<div class="divc">divc</div>
<div class="divd">divd</div>
They are 400px wide and high. I want to alert a when div b scrolls to top of page, and did using scroll function and scrollTop method. Each time when scroll, it check if scrollTop() if lager than 400, and alert a. But if I don't click the on the ok button of alert window, if I continue scrolling, multiple alerts will come, and I have to close them all.
But I just want one alert, and even if I continue scrolling, I want no more alerts. Also if the scrollTop is below 400px, I want to alert b (here also, I don't want repeats). If I got alert a, and if I scroll in opposite direction, and if scrollTop becomes below 400px, I want alert b, no problem for that.
Here is the fiddle.
please add this script on your file JS and try this script:
$(document).ready(function() {
$(window).scroll(function(){
var xx = $(document).scrollTop();
if(xx > jQuery(".divb").height()){
alert("a");
}else{
alert("b");
}
});
});
You are popping alerts on a 'scroll' event which happens every time you scroll..
if this is just a debugging annoyance, what you can do is use console.log('a') instead - example
If you wanted the actual function to run once for each time you reach it you can do this:
var a = false;
$(window).scroll(function(){
var xx = $(document).scrollTop();
if(xx > 400){
if (!a) {
alert("a");
a = true;
}
}else{
if (a) {
alert("b");
a = false;
}
}
});
fiddle for this example
The easiest way to avoid any confusion would be to keep state of scroll actions.
Demo: http://jsfiddle.net/abhitalks/uwUvC/1/
var last = 0, // last scroll-top to determine scroll direction
scrolledUp = false, // to cache state of scroll up
scrolledDown = false; // to cache state of scroll down
$(window).scroll(function (event) {
var current = $(this).scrollTop();
if (current > last) { // if scrolled down
if (current > 400 && !scrolledDown) { // check position and state
alert("A");
scrolledDown = true; // reset scroll down state
}
} else { // if scrolled up
if (current < 400 && scrolledDown && !scrolledUp) {
alert("B");
scrolledUp = true; // reset scroll up state
}
}
last = current; // keep current position to check direction
});
This way you are sure about when you are scrolling up and when you are scrolling down. Keep state of scroll in respective variables and check them.
The alerts fire only once in each direction.