Detect when a window is resized using JavaScript ? - javascript

Is there any way with jQuery or JavaScript to trigger a function when the user ends to resize the browser window?
In other terms:
Can I detect mouse up event when user is resizing the browser window? Otherwise:
Can I detect when a window resize operation is finished?
I'm currently only able to trigger an event when the user start to resize the window with jQuery

You can use .resize() to get every time the width/height actually changes, like this:
$(window).resize(function() {
//resize just happened, pixels changed
});
You can view a working demo here, it takes the new height/width values and updates them in the page for you to see. Remember the event doesn't really start or end, it just "happens" when a resize occurs...there's nothing to say another one won't happen.
Edit: By comments it seems you want something like a "on-end" event, the solution you found does this, with a few exceptions (you can't distinguish between a mouse-up and a pause in a cross-browser way, the same for an end vs a pause). You can create that event though, to make it a bit cleaner, like this:
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
You could have this is a base file somewhere, whatever you want to do...then you can bind to that new resizeEnd event you're triggering, like this:
$(window).bind('resizeEnd', function() {
//do something, window hasn't changed size in 500ms
});
You can see a working demo of this approach here
​

Another way of doing this, using only JavaScript, would be this:
window.addEventListener('resize', functionName);
This fires every time the size changes, like the other answer.
functionName is the name of the function being executed when the window is resized (the brackets on the end aren't necessary).

This can be achieved with the onresize property of the GlobalEventHandlers interface in JavaScript, by assigning a function to the onresize property, like so:
window.onresize = functionRef;
The following code snippet demonstrates this, by console logging the innerWidth and innerHeight of the window whenever it's resized. (The resize event fires after the window has been resized)
function resize() {
console.log("height: ", window.innerHeight, "px");
console.log("width: ", window.innerWidth, "px");
}
window.onresize = resize;
<p>In order for this code snippet to work as intended, you will need to either shrink your browser window down to the size of this code snippet, or fullscreen this code snippet and resize from there.</p>

If You want to check only when scroll ended, in Vanilla JS, You can come up with a solution like this:
Super Super compact
var t
window.onresize = () => { clearTimeout(t) t = setTimeout(() => { resEnded() }, 500) }
function resEnded() { console.log('ended') }
All 3 possible combinations together (ES6)
var t
window.onresize = () => {
resizing(this, this.innerWidth, this.innerHeight) //1
if (typeof t == 'undefined') resStarted() //2
clearTimeout(t); t = setTimeout(() => { t = undefined; resEnded() }, 500) //3
}
function resizing(target, w, h) {
console.log(`Youre resizing: width ${w} height ${h}`)
}
function resStarted() {
console.log('Resize Started')
}
function resEnded() {
console.log('Resize Ended')
}

Related

jQuery scroll function fire once when element becomes visible

Hi guys I am using the scroll function on this script but it fires each time a user scrolls. I want it to only fire once when the user scrolls down to #ror. I tried using the fired variable to check if it has already been fired but that didn't seem to work. I know some people have answered this before but this is where i got the fired solution from and cant get it to work only once. Anyone think they can help please?
$( window ).scroll(function() {
var fired = 0;
console.log(fired);
if(fired == 0){
$('#ror').html('');
$('#ror').goalProgress({
goalAmount: 100,
currentAmount: 75,
textBefore: 'progress bar',
textAfter: '',
offset: 10,
});
fired=1;
}
});
You need to move the fired variable outside the scroll function.
As you are doing it now you are reinitializing the fired variable and setting it to 0 each time the scroll event gets fired.
var fired = 0;
$(window).scroll(function() {
console.log(fired);
if(fired == 0){
$('#ror').html('');
$('#ror').goalProgress({
goalAmount: 100,
currentAmount: 75,
textBefore: 'progress bar',
textAfter: '',
offset: 10,
});
fired=1;
}
});
To detect when a given #target scrolls into view, you can look at it's top position, and check if that position is already inside the viewport.
$('#target').offset().top - $(window).outerHeight() > $(window).scrollTop();
That left part of the equation is constant (as long as you don't move anything around, or change the size of the viewport). Therefore it may be wise to move that outside your event handler function. You need to keep in mind that the scroll event is rather expensive, since it fires constantly when you are scrolling, and the browser is already quite busy with the rendering of the viewport.
When the work is done, you can remove the event handler.
$(window).off(event);
So your final code would look something like this:
var triggerAtY = $('#target').offset().top - $(window).outerHeight();
$(window).scroll(function(event) {
// #target not yet in view
if (triggerAtY > $(window).scrollTop()) {
return;
}
// run your task
// remove this event handler
$(this).off(event);
});
Have a look at the demo: https://jsfiddle.net/6whnfa02/1/
Docs:
http://api.jquery.com/offset/
http://api.jquery.com/outerHeight/
http://api.jquery.com/scrollTop/
http://api.jquery.com/off/
$(window).scroll(function(event) {
var eT = $('#ror').offset().top,
wH = $(this).height(),
wSt = $(this).scrollTop();
if(wSt > (eT-wH)) {
alert('you have scrolled to the ror!');
//detach scroll event handler, as we dont want it to fire again
$(this).off(event);
}
}
The above code checks if user has scrolled down to an element. If yes, alert something and detach the scroll event handler for window. You can refer jquery documentation to see the meaning of offset, height and scrollTop.
Now, as #Pevera pointer out, it is costly to attach event handler to window scroll, you should be aware of that. If you have some heavy code execution inside scroll callback, it will hamper in scrolling the page. So, if you have to attach handler to window scroll, run the scroll callback code within a timeout callback. It ensures to run the scroll callback code after certain delay which helps to scroll the page better. Rewriting the above code with timeout will look like this:
var timeout = null;
$(window).scroll(function (event) {
if (!timeout) {
// set a timeout to run after 250ms
timeout = setTimeout(function () {
clearTimeout(timeout);
timeout = null;
var eT = $('#ror').offset().top,
wH = $(this).height(),
wSt = $(this).scrollTop();
if (wSt > (eT-wH)){
alert('you have scrolled to the ror!');
//detach scroll event handler, as we dont want it to fire again
$(this).off(event);
}
}, 250);
}
});
Everytime user scrolls the page, a timeout is set to run after(atleast) 250ms. In the timeout callback, we remove this timeout handler and check if user has scrolled to the element. If yes, we alert something and detach the scroll handler for window so that it doesn't run again.
Please refer to this FIDDLE for better understanding.
More info on this stackoverflow post and John Resig's blog post.

Execute javascript code ONLY if width is higher than x pixels

I'm trying to execute a javascript function ONLY if the width is bigger than 1200pixels.
The code I need to execute works, but the check for the screen size doesn't:
window.addEventListener("resize", function(){
if (document.documentElement.clientWidth > 1203) {
<<<some other code that's working>>>
}
}, true);
All this code is in a javascript file outside the document.ready function.
EDIT: When you drag your screen window around, it isn't working like normal css queries. This is the problem. It works if you refresh your page, but if you change the width of your browser, then it doesn't adjust, it needs the reload right now.
That's my issue.
You need to add an else clause to get the behaviour you want. Otherwise the resize event will only work going one way, as you described.
window.addEventListener("resize", function(){
// fire when above 1203
if (document.documentElement.clientWidth > 1203) {
console.log('Greater!');
}
// fire when below 1203
else {
console.log('Smaller!');
}
}, true);
Here's a link to the fixed jsfiddle that planet260 wrote: http://jsfiddle.net/4dnemh2j/4/
Here's my example again: https://jsfiddle.net/9n5hmpua
The problem is the true you're passing to addEventListener.
See the useCapture section here: EventTarget.addEventListener
Events which are bubbling upward through the tree will not trigger a listener designated to use capture
So you want:
window.addEventListener("resize", function(){
if (document.documentElement.clientWidth > 1203) {
<<<some other code that's working>>>
}
}, false); <----change here
You can use jQuery to achieve this
$( window ).resize(function() {
console.log($( window ).width());
var windowwidth = $( window ).width();
if (windowwidth > 500) {
console.log("Greater than 500");
/*Do your work here*/
}
});

Will $(window).resize() fire on orientation change?

Im using this to run some code when a browser window is resized: $(window).resize(callback)
I also need to run this code when the orientation is changed in phones and tablets. Will the above fire on this event?
Some devices/browsers do, some not. You need to decide your supported browsers and devices.
If you want to be on secure side you should use the resize event and get/check the sizes inside in it; if you know your desired devices go with a simple orientation change:
Easy solution:
// Listen for orientation changes
window.addEventListener("orientationchange", function() {
// Announce the new orientation number
alert(window.orientation);
}, false);
More secure/supported
// Listen for resize changes
window.addEventListener("resize", function() {
// Get screen size (inner/outerWidth, inner/outerHeight)
}, false);
David Walsh wrote a good article about resize and orientation change event.
More about orientation change and sizes here:
http://davidwalsh.name/orientation-change
the answer is imho: no
but:
$(window).on('resize orientationchange', function(){
//do stuff
});
should have you covered
careful, this can trigger twice depending on the browser
My solution:
Generate an event when orientationchange doesn't do it
use a throttle to prevent to much update on resize (lodash library for instance)
window.addEventListener("resize", throttle(function() {
//to do when resize
}, 50), false);
window.addEventListener("orientationchange", function() {
// Generate a resize event if the device doesn't do it
window.dispatchEvent(new Event("resize"));
}, false);
Quirksmode directly tested this question and found that the native resize event fired on orientation change in all browsers other than Opera Mini: https://www.quirksmode.org/dom/events/resize_mobile.html
A simple solution is to pass a value based on the event type..
window.addEventListener('resize', function () {
myFunction('resize');
});
window.addEventListener("orientationchange", function() {
myFunction('orientation');
});
function myFunction(value) {
if (value == 'resize') {
// do something
} else if (value == 'orientation') {
// do something else
}
}
since orientationchange event has been deprecated, it's now possible to use screen.orientation.onchange
Deprecated: Window: orientationchange event
i.e.
const resizeScreen = debounce(async () => {
await animateWithNewDimensions();
}, 50);
window.screen.orientation.onchange = resizeScreen;
https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation#browser_compatibility
Too bad Safari is not supporting this :/

window.resize - Won't fire until I've manually changed the browser width

I have a little code snippet here:
$(window).resize(function() {
if ($(window).width() <= 768) {
$('.menu-item-810').click(function () {
$('.squares').slideDown(2000);
});
}
});
That says when the browsers window width is less than or equal to 768px, when you click on the element that has a class of .menu-item-810, slideDown the .squares element.
That is what I want, and it does work.. but only 99.8% correctly.
When the screen width is larger than 768px, the .squares element has a different jQuery effect, it fades in and out, instead of sliding. I needed it to slideDown instead, when in tablet/mobile view, so I wrote the above snippet.
Like I said, it all works, but say I've opened any browser, resized it to 768px or less width, browsed to the site and then click on .menu-item-810. Nothing happens. It's only when I then manually resize the browser again, by any amount, that the jQuery fires. So if I've just resized the browser again, and then click .menu-item-810, the .squares element slides down like expected, but only if I manually resize the browser. I thought that the jQuery would be listening from the start if I wrapped that snippet in $(document).ready() but that doesn't work either, it just has the same behavior as without.
Anyhoo, any help is as always massively appreciated. Hopefully I'm just missing something simple.
Thanks guys!
Actually, this makes no sense? The resize event handler fires thousands of times when the window is resized, and binding a click event handler inside the resize handler will get you thousands of click handlers.
Attach one single click handler, and check the windows width inside it
$('.menu-item-810').click(function () {
if ($(window).width() < 768) {
$('.squares').slideDown(2000);
}
});
Once your javascript has loaded, it needs a resize event to fire in order to trigger your code. - it doesn't know if the window has been resized prior to the handler being initialised.
Put the same snippet in your document.ready() function to do an initial check for window size:
$(document).ready(function() {
if ($(window).width() < 768) {
$('.menu-item-810').click(function () {
$('.squares').slideDown(2000);
});
}
});
In the order of your code, it is first checking the window size, and only then, if it is small, adds your event handler.
It sounds like what you want is to always call the event handler, and then change the action depending on the side.
$(window).resize(function() {
$('.menu-item-810').click(function () {
if ($(window).width() <= 768) {
$('.squares').slideDown(2000);
}
});
});
Actually, now that i think some more, you don't even need to set the handler upon resize. Just set it on document load, and check the size when it gets clicked.
$(document).ready(function() {
$('.menu-item-810').click(function () {
if ($(window).width() <= 768) {
$('.squares').slideDown(2000);
}
});
});

Detect div movement nd run function at certain intervals jQuery

On my website I have a a div (.wrapper) that moves co ordinates absolutely when the mouse wheel is scrolled, or the user uses his arrow keys/spacebar etc.
At certain points, say when the div.wrapper is -1000 pixels left, Id like a function to happen.
Is there anyway I can check for this without using an interval?
setInterval(function(){
if($('.wrapper').css('left') <= 100 + 'px'){
alert('foo');
} else {
alert ('bar');
};
}, 5000);
There's no event to detect changes in CSS properties. The usual way to do this is to put the call the handler explicitly after updating the left property.
You can move the code that changes the value into a separate function:
function setLeft(left){
$('.wrapper').css('left', left);
if($('.wrapper').css('left') <= 100 + 'px'){
alert('foo');
} else {
alert ('bar');
};
}
If you wanted to you could trigger inside the setLeft function and put the checking code into an event handler.
Another thing works is creating a wrapper function for .css that triggers the event:
var originalCssFunction = $.prototype.css;
$.prototype.css = function(){
originalCssFunction.apply(this, arguments);
// Check conditions and trigger event
}

Categories

Resources