How do I run a jquery function on window events: load, resize, and scroll?
Here is my code
I'm trying to detect if a div is viewable and then if it is run some ajax code...
<script>
function topInViewport(element) {
return $(element).offset().top >= $(window).scrollTop() && $(element).offset().top <= $(window).scrollTop() + $(window).height();
}
</script>
<script>
topInViewport($("#mydivname"))
{
// ajax code goes here
}
You can use the following. They all wrap the window object into a jQuery object.
Load:
$(window).load(function () {
topInViewport($("#mydivname"))
});
Resize:
$(window).resize(function () {
topInViewport($("#mydivname"))
});
Scroll
$(window).scroll(function () {
topInViewport($("#mydivname"))
});
Or bind to them all using on:
$(window).on("load resize scroll",function(e){
topInViewport($("#mydivname"))
});
You can bind listeners to one common functions -
$(window).bind("load resize scroll",function(e){
// do stuff
});
Or another way -
$(window).bind({
load:function(){
},
resize:function(){
},
scroll:function(){
}
});
Alternatively, instead of using .bind() you can use .on() as bind directly maps to on().
And maybe .bind() won't be there in future jquery versions.
$(window).on({
load:function(){
},
resize:function(){
},
scroll:function(){
}
});
just call your function inside the events.
load:
$(document).ready(function(){ // or $(window).load(function(){
topInViewport($(mydivname));
});
resize:
$(window).resize(function () {
topInViewport($(mydivname));
});
scroll:
$(window).scroll(function () {
topInViewport($(mydivname));
});
or bind all event in one function
$(window).on("load scroll resize",function(e){
Related
posting for the first time on here, just wondering what im doing wrong within this little jquery script I wrote for a external html file containing my menu element. It works on resize just not load. I've tried a standalone $(window).load(); event as well and nothing seems to work. I'm new to jQuery and just know the do's and donts yet!
jQuery(document).ready(function($) {
var vwidth = $(window).width();
var vheight = $(window).height();
var menu = $('#menu_container');
$( window ).on('load resize', function() {
if (vwidth >= 1000) {
menu.css('zoom', '1');
} else {
menu.css('zoom', '0.8');
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
There are two problems here. One already explained by #Mr. Polywhirl.
The other one is the fact that the DOM ready event will excute AFTER the window.load event. That means that by the time jQuery(document).ready executes $(window).load has already happened, so the event registration for window.load it's a bit late. Try this instead...
//this is essentially the same as jQuery(document).ready
$(function(){
toggleZoom();
$(window).on("resize", function(){
toggleZoom();
});
});
function toggleZoom(){
var vwidth = $(window).width();
//this isn't needed in this snippet
//var vheight = $(window).height();
var menu = $('#menu_container');
if (vwidth >= 1000) {
menu.css('zoom', '1');
} else {
menu.css('zoom', '0.8');
}
}
jQuery(document).ready(function($) {
Remove the dollar sign ($) from the function above. You are redefining the global as a function argument for the scope of the jQuery.ready function.
jQuery(document).ready(function() {
Edit
If that does not work, try some of these basic calls and see what the console prints out.
When I click the Run code snippet button, I get the following output:
Document ready()
Window resize()
Window load()
Window load() x2
Window resize()
$(document).ready(function() {
console.log("Document ready()");
});
$(window).on('load', function() {
console.log("Window load()");
});
// or
$(window).on({
load : function() {
console.log("Window load() x2");
},
resize : function() {
console.log("Window resize()");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The correct usage for jQuery ready() function is:
jQuery(document).ready(function(){
//The code you want to execute.
});
For more info look at:
https://api.jquery.com/ready/
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');
}
}));
The function below runs on document load and document resize:
$(window).on("resize", function () {
// code
}).resize();
How can I also trigger the function when the user clicks on <div id="my_div"></div> ?
You can explicitly create the callback function, like..
function callbackFn() {
var $caller = $(this);
// do something...
}
$(window).on('resize', callbackFn);
$('#my_div').on('click', callbackFn);
Move your function to some named function and call it on event:
function myFunction () {
alert('Working');
}
$(window).on("resize", function () {
myFunction();
}).resize();
$('#my_div').click(function () {
myFunction();
});
One way to achive that is by triggering the resize event inside the click event handler:
$('#my_div').on('click', function() {
$(window).trigger('resize');
});
For my site, I inizialized pageScroller by a function that changes scrollOffset depending on the window width.
jQuery(function offset_value(){
if ($(window).width() < 960) {
$(document).ready(function(){
// initiate page scroller plugin
$('body').pageScroller({
navigation: '#nav',
scrollOffset: -40
});
});
} else {
$(document).ready(function(){
// initiate page scroller plugin
$('body').pageScroller({
navigation: '#nav',
scrollOffset: -195
});
});
}
});
However, I need also to reload this function at window resize. For example, if the user rotate the smartphone, the window width changes. So, I added this code:
$(window).resize(function() {
offset_value()
}).resize();
The problem is that the scrollOffset value does not change at window resize, as if the offset_value function was not called.
A (not so elegant) solution is to refresh the entaire page at window resize:
$(window).resize(function() {
location.reload();
return;
});
but I don't like one has to wait for the site to reload at the rotation of the device.
Where is the problem? Any suggestion?
Thanks.
One problem here is that your function declaration makes it inaccessible from outside:
jQuery(function offset_value() { ... });
This declares an anonymous function which can only be referenced by offset_value from the function's own body.
To fix this, you must declare the function outside:
function offset_value()
{
...
}
jQuery(offset_value); // run on document ready
You can also remove the $(document).read() because that's already done when you use jQuery(fn).
Update
To reinitialise the plugin you need to reset the global pageScroller:
pageScroller = {};
$('body').pageScroller({ ... });
You do not need document ready handler which is there inside the function:
jQuery(function offset_value(){
if ($(window).width() < 960) {
// initiate page scroller plugin
$('body').pageScroller({
navigation: '#nav',
scrollOffset: -40
});
} else {
// initiate page scroller plugin
$('body').pageScroller({
navigation: '#nav',
scrollOffset: -195
});}
});
You should not use document-ready handler in your function. Also I would recommend you to create a function and pass it to document-ready handler and window-resize handler
Use
//Create a function
function offset_value() {
if($(window).width() < 960) {
// initiate page scroller plugin
$('body').pageScroller({
navigation: '#nav',
scrollOffset: -40
});
} else {
// initiate page scroller plugin
$('body').pageScroller({
navigation: '#nav',
scrollOffset: -195
});
}
};
//Pass function reference to document-ready handler and window resize
$(document).ready(offset_value);
$(window).resize(offset_value).resize();
this makes the back to top div appear when scrolling down 100 pixels, but if a person is already scrolled down and does a refresh, the page stays scrolled down, but the div is not shown.
<div id="gototopwrap">Back To Top</div>
<script>
$(function(){
$(window).scroll(function() {
$('#gototopwrap').toggle($(document).scrollTop() > 100);
});
});
</script>
i tried doing this, but it didn't work:
$(function myFunction(){
$(window).scroll(function() {
$('#gototopwrap').toggle($(document).scrollTop() > 100);
});
});
myFunction();
also tried it like this, and still nothing:
function myFunction(){
$(window).scroll(function() {
$('#gototopwrap').toggle($(document).scrollTop() > 100);
});
}
myFunction();
i'm already wrapping in document ready. i think the issue is that it's only listening for the the scroll and only acts on scroll.
Trigger the event which will fire your function
$(window).scroll(function() {
$('#gototopwrap').toggle($(document).scrollTop() > 100);
}).trigger("scroll");
Bind both events:
$(window).on('load scroll', function() {
$('#gototopwrap').toggle($(document).scrollTop() > 100);
});
Something like this should work
$(function(){
$(window).scroll(function() {
$('#gototopwrap').toggle($(document).scrollTop() > 100);
});
if($(document).scrollTop() > 100)
{
$('#gototopwrap').toggle();
}
});