Jquery ignores if-statement when resizing - javascript

I've written a function which makes my top-bar ($header) fixed if you scroll down on device ( < 992 ) which works fine. And when I resize, I use the function fixedTopCheck() again and it removes the .fixed class (in the else statement). This also works fine. But then when I scroll, it suddendly gives top the class .fixed again. So this part is getting ignored if ($(window).width() < 992) (which only happens when resizing, if I refresh with a window above 992px it works fine).
So is this resizing messing with the recognition of $(window).width()? (When I console log it, it shows the correct width size).
My code:
$(function()
{
var $header = $('header.top');
var $input = $header.find('input[type=search]');
var $search = $header.find('div.search');
var $container = $('main#content');
var $searchBtn = $search.find('button.icon-search');
var $closeBtn = $search.find('span.icon-cross');
$closeBtn.css('display', 'none');
function fixedTopCheck()
{
if ($(window).width() < 992)
{
$(window).on('scroll', function()
{
if ($(window).scrollTop() > 75)
{
$searchBtn.css('display', 'inline-block');
$closeBtn.css('display', 'none');
// Turn top into fixed menu
$header.addClass('fixed');
$container.addClass('fixed');
// Hide search bar and make it smaller
$input.css('display', 'none');
// Prevent search button to search
$searchBtn.on('click', function(e) {
e.preventDefault();
});
// Open search bar when clicking button
$(document).on('click','.icon-search',function()
{
$searchBtn.unbind('click');
$input.css('display', 'inline-block');
$searchBtn.css('display', 'none');
$closeBtn.css('display', 'inline-block');
$input.focus();
});
// Close search bar when clicking button
$(document).on('click','.icon-cross',function()
{
$searchBtn.on('click', function(e)
{
e.preventDefault();
});
$input.css('display', 'none');
$searchBtn.css('display', 'inline-block');
$closeBtn.css('display', 'none');
});
}
else
{
// Reverse fixed menu
$header.removeClass('fixed');
$container.removeClass("fixed");
$input.css('display', 'inline-block');
// Return search function
$searchBtn.unbind('click');
// Reset search form when going top and search form is still opened
$searchBtn.css('display', 'inline-block');
$closeBtn.css('display', 'none');
}
});
}
else
{
console.log("hello");
// Remove fixed top
if($header.hasClass("fixed"))
{
$header.removeClass("fixed");
}
if($container.hasClass("fixed"))
{
$container.removeClass("fixed");
}
$searchBtn.css('display', 'inline-block');
$closeBtn.css('display', 'none');
}
}
fixedTopCheck();
// if window is resized check again
$( window ).resize(function() {
fixedTopCheck();
});
});

Your code is following a lot of bad practices.
dont nest your event listeners inside each other. this will cause setting an event listener on the same component everytime its container event triggers (on each resize is VERY heavy aswell).
instead of using bind and unbind, make a check the width inside each event and follow actions depending on that.
another solution for replacing bind and unbind in your case is to keep the default button events, but disable the button so it cannot be clicked instead of unbind.
This will answer your question:
adding events inside resize, will not make them only work on that size in the if statement, you have to put the event outside the resize event and check whenever that event happens on the scroll and size.

When the page is loaded and the width of the page is <992px, the scroll event is created. When you resize to >992px the scroll event will still exist.
I would recommend binding the scroll event only once on page load (not after each resize) and check the width inside of that method to decide what it should do when it's scrolling.

Related

Sidemenu toggle when div hits top

So I've got a side-menu which toggles open when a certain div hits the top of the window.
The menu also has a toggle button to open and close it.
I'm having a problem where the the script continues to close the menu on scroll after it's been opened manually via the toggle button.
Is there any way of opening and closing the menu only once the div has passed the top of the screen, rather than the script constantly checking?
My script:
var stickyTop = $('#section1').offset().top;
$(window).on( 'scroll', function(){
if ($(window).scrollTop() >= stickyTop) {
$('.be-toggled').removeClass('toggled');
} else {
$('.be-toggled').addClass('toggled');
}
});
});
Move your function to a variable, then you can call $(window).off() to remove the window listening to the scroll event. My example isn't exactly what you need but it should give you the on/off concept when using a function.
var stickyTop = $('#section1').offset().top;
var doToggle = function() {
if ($(window).scrollTop() >= stickyTop) {
$('.be-toggled').removeClass('toggled');
} else {
$('.be-toggled').addClass('toggled');
}
$(window).off( 'scroll', doToggle);
});
$(window).on( 'scroll', doToggle);

jQuery scroll function only works once

I am trying to add a class to the header if the user scrolls past the div #home - and remove the class when you scroll back to the top.
The issue is, when you scroll past the div it adds the class but when you keep scrolling and then scroll back up, the class does not get removed. The event is only firing once...
I created this jsFiddle here - https://jsfiddle.net/breezy/9evksr7y/
It works in my jsFiddle file but not on my actual web page, I've also tried this...
$(window).on( 'scroll', function() {
var header = $('#header'),
target = $("#home").offset().top;
var interval = setInterval(function() {
if ($(window).scrollTop() > 400) {
// alert("made it!");
header.addClass('fixed');
clearInterval(interval);
} else {
header.removeClass('fixed');
}
}, 250);
});
But it still does not work. Any idea what I am doing wrong?
Thanks
Edit: The issue was that one of my other functions in the same document was conflicting w/ this scroll function.
So I made some minor tweaks to the code. Not sure what the issue was but this seemed to work for me on my webpage.
$(window).on('scroll', function() {
var header = $('#header'),
target = $("#home").offset().top;
if ($(window).scrollTop() > target) {
header.addClass('fixed');
} else {
header.removeClass('fixed');
}
});

Responsive Jquery toggle command

I am having an issue with my code. Whenever, I load up the page in the browser or in a mobile device, and I try to toggle it suddenly toggles multiple times when I just clicked on it once. I am trying to use this syntax code to make it responsive.
My CodePen
$(window).resize(function() {
$(".textcontent").hide();
if ($(window).width() <= 480) {
jQuery(function($) {
$(document).ready(function() {
$(".textcontent").hide();
$(".titleheader").click(function() {
$(this).toggleClass("active").next().slideToggle("fast");
return false;
});
});
});
}
});
The text toggles more than once because you are binding the click handler each time the resize event fires. Each bind attaches another handler so, depending on how many times the resize event fires, you might end up with many click handlers firing at once.
I suggest that you bind or unbind your click handler depending on the screen width, like so:
$(function() {
// function to toggle a text section
function toggleText(elm) {
$(elm).toggleClass("active").next().slideToggle("fast");
}
// resize event handler
$(window).on('resize', function() {
if ($(window).width() <= 480) {
// if window <= 480, unbind and rebind click handlers, and hide all text content
$(".titleheader").off('click').on('click', function() {
toggleText(this);
});
$(".textcontent").hide();
} else {
// if the window > 480, unbind click handlers and hide all text
$(".titleheader").off('click');
$(".textcontent").show();
}
}).trigger('resize'); // initialize - trigger the resize once upon load
});
WORKING EXAMPLE
You might also want to throttle or "debounce" your resize handler so it won't fire continuously in IE, Safari, and Chrome.
EDIT:
An alternate method is to set a flag to indicate whether the layout is "small" or "large". Then, only change the layout if the flag does not indicate the desired layout:
$(function() {
// layout flag (defaults to "not small")
var small = false;
// function to toggle a text section
function toggleText(elm) {
$(elm).toggleClass("active").next().slideToggle("fast");
}
// resize event handler
$(window).on('resize', function() {
if ($(window).width() <= 480) {
// if window <= 480 and the layout is "not small", bind click handlers and hide all text content
if (!small) {
console.log('made small');
$(".titleheader").on('click', function() {
toggleText(this);
});
$(".textcontent").hide();
// set the layout flag to "small"
small = true;
}
} else {
// if the window > 480 and the layout is "small", unbind click handlers and hide all text
if (small) {
console.log('made large');
$(".titleheader").off('click');
$(".textcontent").show();
// set the layout flag to "not small"
small = false;
}
}
}).trigger('resize'); // initialize - trigger the resize once upon load
});
WORKING EXAMPLE

Accordion looping on resize

I have a menu that is hidden in an accordion when viewing on screens less than 600px.
On screens larger than 600px the menu is visible.
jsfiddle- http://jsfiddle.net/ashatron/zbzqoz2f/
it works ok, but when i resize the window to be greater than 600px, then go back to less than 600px then press view sitemap it loops the animation multiple times.
I think its running the function for every resize event, which is queing up the accordion and then looping it. But I'm not sure how best to order the syntax to get it to work.
Any help would be appreciated!
footernavmenufn = function() {
var current_width = $(window).width();
if (current_width < 600) {
$('.footer-accordion-head').show();
$('.footer-accordion-body').hide();
$('.footer-accordion-head').click(function () {
$(".footer-accordion-body").slideToggle('400');
// console.log('hmmm');
return false;
}).next().hide();
} else {
$('.footer-accordion-head').hide();
$('.footer-accordion-body').show();
}
};
$(document).ready(function () {
footernavmenufn();
});
$(window).resize(function(){
footernavmenufn();
//console.log('OMG-WHY-YOU-NO-WORK');
});
The issue is that everytime window is resized and the condition is met, you're binding a new click event handler, so after a while there'll be multiple event handlers causing chaos. Ideally your code should be something like
$(document).ready(function () {
$('.footer-accordion-head').click(function () {
$(".footer-accordion-body").slideToggle('400');
console.log('hmmm');
return false;
});
$(window).resize(footernavmenufn);
footernavmenufn(); // or $(window).trigger("resize");
});
footernavmenufn = function () {
var current_width = $(window).width();
if (current_width < 600) {
$('.footer-accordion-head').show();
$('.footer-accordion-body').hide();
} else {
$('.footer-accordion-head').hide();
$('.footer-accordion-body').show();
}
};
Updated Fiddle
Why do you have this code? Crazy one. Remove it:
if (current_width < 600) {
$('.footer-accordion-head').show();
$('.footer-accordion-body').hide();
$('.footer-accordion-head').click(function () {
$(".footer-accordion-body").slideToggle('400');
return false;
}
move the click declaration into the $(document).ready function.
at the moment everytime you resize the page that click function is being added again - so the repeat is once per page resize.
forked jsfiddle with change

Only want the function to work when the screen size is a certain width

I have this landing page that has a left navigation when it the screen with 1024 or larger but when the screen goes below 1024 the left navigation appears on the top of the main content of the page and the "Walmart Leverage becomes a button with on click event for the rest of the navigation to come down. the code works until I put the if statement to detect what size the screen is. Probably missing something to the code. Below is the link for the page.
http://dl.dropboxusercontent.com/u/2399619/walmartmilitary/talentbrew-LeverageHome.html
This is the code for the jQuery
$(window).resize(function() {
if( $(this).width() < 1024) {
var $showSubBtn = $("#sn-walmartleverage");
$showSubBtn.click(function(){
if($(this).hasClass("active")) {
$(this).parent().next().hide();
$(this).removeClass("active");
} else {
$(this).addClass("active");
$(this).parent().next().show();
}
return false;
});
}
});
Any help would be much appreciated.
Thanks
You can't put the click event handler inside the window resize event handler, you should just check the window size when the click happens
$("#sn-walmartleverage").on('click', function(e){
e.preventDefault();
if ($(window).width() > 1024) {
$(this).toggleClass('active').parent().next().toggle();
}
});

Categories

Resources