I have two menus that fade in and out on scroll. But when I resize the window I want to stop this event. I've tried plenty of stuff, searched a lot but nothing worked. I'm missing something. Here's what I have:
var scrollHandler = $(window).scroll(function() {
var top = $(window).scrollTop();
if (top > 0) {
$('.menu').fadeOut('fast', function() {
$('.second-menu').fadeIn('fast');
});
} else {
$('.second-menu').fadeOut('fast', function() {
$('.menu').fadeIn('fast');
});
}
})
scrollHandler;
if ($(window).width() < 768) {
$(window).off("scroll", scrollHandler);
}
Any help would be great, thanks!
The $(window).width() is only evaluated at runtime (i.e. the width of the viewport when the script is executed). It is not reactive in the sense that it will be updated on-the-fly when the viewport is resized.
Therefore, if you want to listen to changes in the width, you will have to place the logic within the window resize event callback:
$(window).resize(function() {
if ($(window).width() < 768) {
$(window).off('scroll');
}
});
Moreover, there are several issues with your code.
The scrollHandler should reference/define the function, not the outcome of the binding
Calling scrollHandler does not do anything. If you make the changes as per #1, then you can simply bind the logic using $(window).on('scroll', scrollHandler);
The .off() method does not accept a second parameter, this is enough: $(window).off('scroll')
After refactoring, your code will look something like this:
var scrollHandler = function() {
var top = $(window).scrollTop();
if (top > 0) {
$('.menu').fadeOut('fast', function() {
$('.second-menu').fadeIn('fast');
});
} else {
$('.second-menu').fadeOut('fast', function() {
$('.menu').fadeIn('fast');
});
}
};
// Bind scrollHandler firing to scroll event
$(window).on('scroll', scrollHandler);
$(window).resize(function() {
if ($(window).width() < 768) {
$(window).off('scroll');
}
});
Note:
If you want to get the best performance out of this, you should throttle the resize event so that the callback function is not fired too frequently. Lodash/Underscore.js have utility functions for that (_.throttle()), and there is also a jQuery plugin available.
In Lodash/Underscore.js:
$(window).resize(_.throttle(function() {
if ($(window).width() < 768) {
$(window).off('scroll');
}
}, 100));
Using Ben Alman's jQuery plugin:
$(window).resize($.throttle(100, function() {
if ($(window).width() < 768) {
$(window).off('scroll');
}
}));
Related
I have this issue that I'm not being able to work correctly.
I have a navbar that must change on scroll(this part works fine) but it must also change when window/viewport is < 991px.
It actually does work, but I must scroll to apply the effect.
Here's my code:
$(document).ready(function()
{
var $navbar = $('.navbar');
// ----------
$(function()
{
$(window).scroll(function()
{
if(($(window).scrollTop() > 60 && $(window).on('load resize').width() > 992) || ($(window).on('load resize').width() < 992))
{
$navbar.addClass("compressed");
}
else
{
$navbar.removeClass("compressed");
}
});
});
});
If I shrink the broswer, nothing happens. At the first scroll, it works correctly. How should I trigger it when load or resize the window?
Thanks!
Just replace this:
$(window).scroll(function() {...});
with this:
$(window).on("load scroll resize", function() {...});
That will result in the function being called on any of the listed events.
I just write a script to auto positioning an element on my page.
$(document).ready(function(){
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll < 180) {
$(".header-bottom").removeClass("scroll-menu");
if ($(window).width() > 991) {
$(".header_user_top").css("position", "absolute");
$(".header_user_top").css("top", "initial");
$(".header_user_top").css("right", "60px");
$(".header_user_top").css("z-index", "1");
}
} else {
$(".header-bottom").addClass("scroll-menu");
if ($(window).width() > 991) {
var rightContainer = ($(window).width() - ($('#header div.header-bottom div.container').offset().left + $('#header div.header-bottom div.container').outerWidth()));
$(".header_user_top").css("position", "fixed");
$(".header_user_top").css("top", "-22px");
$(".header_user_top").css("right", rightContainer+60+"px");
$(".header_user_top").css("z-index", "99");
}
}
});
});
It's working but if I resize browser window the script doesn't reload.
If I refresh the page it's working.
I have add window.onresize = function(){ location.reload(); }to my script to fix this problem but I'm looking for a better solution.
Any idea?
Use on function to call multiple event:
$(window).on("load resize scroll",function(e){
// do something
}
Call function which is handling size on windows.resize also
function handleSize(){
// You code to handle size
}
window.resize=handleSize();
i am using window.scroll event to load content on div just when buttom of scroll reached.
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$(window).unbind('scroll');
loadMoreCommentsOnArticle();
}
});
function loadMoreCommentsOnArticle(){
$(window).bind('scroll');
var dynamicData = fetchData();
$('#parentElement').append(dynamicData);
}
scroll is not binding after once bind initially. maybe by $(window).unbind('scroll'). But i am trying to bind scroll again using $(window).bind('scroll'); but it is not working.
By not using $(window).unbind('scroll') . Scroll event is firing ample of times in no time.
I am using this way according to Rory
var $window = $(window);
function windowScroll() {
if ($window.scrollTop() + $window.height() > $(document).height() - 100) {
window.off('scroll');
loadMoreCommentsOnArticle();
}
}
$window.scroll(windowScroll);
The issue is because when you re-bind the scroll event in loadMoreCommentsOnArticle() you're not providing a function to run. You can solve the issue by extracting the scroll logic out to it's own function to make binding/rebinding easier.
Also note that bind() and unbind() are deprecated. You should use on() and off() instead.
var $window = $(window);
function windowScroll() {
if ($window.scrollTop() + $window.height() > $(document).height() - 100) {
$window.off('scroll');
loadMoreCommentsOnArticle();
}
}
$window.scroll(windowScroll);
function loadMoreCommentsOnArticle() {
$window.on('scroll', windowScroll);
$('#parentElement').append(fetchData());
}
function fetchData() {
console.log('loading data...')
return '<div>More data...</div>';
}
#parentElement div {
height: 3000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parentElement">
<div>Some data...</div>
</div>
i want for specific width, specific click animations but it's not working. Why?
Here an example:
From 0 - 959px > anim1 From 960 - 1279px > anim2 From 1280 - 1699 > anim3 From 1700 - open end > anim4
Here is my Code:
$(document).ready(function(){
if ($(window).width() > 959) {
$("#mains").click(function(){
anim1();
});
}
});
$(document).ready(function(){
if ($(window).width() > 1279) {
$("#mains").click(function(){
anim2();
});
}
});
$(document).ready(function(){
if ($(window).width() > 1699) {
$("#mains").click(function(){
anim3();
});
}
});
$(document).ready(function(){
if ($(window).width() < 1700) {
$("#mains").click(function(){
anim4();
});
}
});
You are binding the animation on $(document).ready() based on the screen size. For example when the DOM is ready and the window width is less than 1700 only the function with anim4() will be used. What you need to do is place the window width check inside a single binding.
For example:
$(document).ready(function(){
$("#mains").click(function() {
if ($(window).width() < 959) {
// do something
} else if ($(window).width() < 1700) {
// do something else, etc.
}
});
});
It seems you have mistaken the conditionals. Also you can use just one document ready event handler and use an if else if statement to distinguish between cases. The statements should specifically set the width borders. Something like:
if ($(window).width() < 969 ) {
anim1();
} else if ($(window).width() >= 970 && $(window).width() < 1200) {
anim2();
}
The widths are as everyone can see examplary.
Except that there could be errors in anim* functions, but those errors would definitely mess up the code.
You are binding events on the basis of width size. I would recommend to check width in event handler and perform action accordingly
$(document).ready(function () {
$("#mains").click(function () {
if ($(window).width() > 959) {
anim1();
}
if ($(window).width() > 1279) {
anim2();
}
if ($(window).width() > 1699) {
anim3();
}
if ($(window).width() < 1700) {
anim4();
}
});
});
Read through your existing code and think about what it will do if the window width happens to be 1750:
Your first if test with > 959 will be true so it will bind a click handler that does anim1().
The second if test with > 1279 will also be true so it will bind another click handler that does anim2().
The > 1699 test would also be true, binding a third click handler that does anim3().
The fourth if test would be false since it has < rather than >, but in fact for a width of 1750 you want anim4() to run.
So then a click would call the first three animations.
What you need is an if/else if/else if/else structure so that only one of the four animX() functions is used. Also you probably want to do the test inside the click handler so that it uses the window width at the time of the click, not the width at the time the page loads. So:
$(document).ready(function() {
$("#mains").click(function() {
var w = $(window).width();
if (w < 960)
anim1();
else if (w < 1280)
anim2();
else if (w < 1700)
anim3();
else
anim4();
});
});
Note that at the beginning of the click handler I've put the $(window).width() into the (imaginatively named) w variable to save having to repeat those two function calls in the else if statements.
Try
$(document).ready(function(){
if ($(window).width() > 1699) {
anim3();
}else if($(window).width() > 1279){
anim2();
}else if($(window).width() > 959){
anim1();
}
});
I try to unload function if browser window less than 944px. I start to write this
$(window).resize(function() {
if ($(window).width() >= '944') {
$(window).load(function() {
$('#slider').nivoSlider();
});
} else {
alert($(window).width());
if ($(window).width() <= '944') {
$(window).unload(function() {
$('#slider').nivoSlider();
});
}
}
});
but i stuck. I want if the user enters, verify resolution and if more than 944px to load jquery function, however if browser is resize or less resolution than 944px, function will be unload.
i have a different solution for your problem; you can prepare a new slider mask (just like slider but without nivoSlider functions) for <944px window width, when browser width <944px niveSlider will be hide and your mask will be seen.
check it out:
$(window).resize(function() {
windowWidth = $(this).width();//you need to use this for changable values
if ( windowWidth > 943) {
$('#sliderMask').hide();
$('#slider').show();
$(window).load(function() {
$('#slider').nivoSlider();
});
} else if ( windowWidth < 944) {
$('#slider').hide();// hide your nivoSlider
$('#sliderMask').show();// show your basic slider mask
}
});
please note that: you need to use $(this) to get current value.
here is jsfiddle example for you; check the console log from your browser's developer panel