I'm using templates/handlebars but none of the event handlers are triggered when the browser window resizes. Not sure how to capture the resize event in order to dynamically set the div's height to be within the viewport
Here's a sample of what I've tried so far using meteor's event map:
Template.basic.events({
'resize window' : function(evt, tmpl){
alert("test");
},
};
Ideally this handler would be called each time the window is resized so I can use $(window).height() to set the div's height in the html using tmpl.find('#main-div');.
Most problems which directly rely on jQuery can be solved using the onRendered callback like so:
Template.basic.onRendered(function() {
$(window).resize(function() {
console.log($(window).height());
});
});
Technically this works, but because window never gets removed as part of the rendering process, this technique has a big disadvantage: it adds a new resize handler every time the template is rendered.
Because window is always available, you can instead use the created and destroyed callbacks to register and unregister the handlers:
Template.basic.onCreated(function() {
$(window).resize(function() {
console.log($(window).height());
});
});
Template.basic.onDestroyed(function() {
$(window).off('resize');
});
Note, however, that stopping the resize handler in onDestroyed may not really be what you want. See this question for more details.
Also note that in the current version of meteor, you can check the number of event handlers like so:
$._data($(window).get(0), "events").resize.length
Related
I have a problem when creating plugin. The problem came up when setting new value for variable width.
width variable need to calculate again, if user resizes his browser.
If i attach resize event inside loop, it will make trouble performance.
I came up with the idea to create closure function for wrapping all CODE. So, when the user resize his browser, i call this function again.
JS :
var self = this,
onScrollbarY = function() {
self.each(function() { // loop it
var el = $(this),
elLog = el.find(".scrollbarYLog"),
width = $(window).innerWidth(), // this value will change based on users browser width
onMouseOver = function() {
elLog.html(width);
};
elLog.on("mouseover", onMouseOver);
});
};
onScrollbarY(); // call it immediatly
$(window).on("resize", onScrollbarY); // if users resize its browser, call it again for getting new browser width
Is this the correct way to accompolished it? or there are other option which more efficient rather than attach all code again?
The reason why you had a performance problem in the first place is that every time you called .on('resize', ...), you registered a function that runs on that event. So after 5 resize events, you had 5 functions that were called every time, which is what caused the slow-down.
There are two ways to approach this problem:
only attach one handler to that event (what you ended up doing); or
use the .one('resize', ...) event handler to register a function that will only be triggered on the first next resize event.
Use case #1 is what the majority of developers use and recommend. You create a function (like your onScrollbarY) and you register that function using .on() to be called each time the resize event happens from the moment you register it.
The case #2 is very rare and you probably don't want to use .one() unless you only want to handle the first occurence of that event, and none after that. If you wanted to handle more than one, you would have to call .one() again after the event happens to tell it to listen for that event again.
EDIT: You can simplify your code to the following:
var $window = $(window),
width = $window.innerWidth(), // we know the initial width
$elLog = $(".scrollbarYLog"), // we find the scrollbar element
onResize = function() {
width = $window.innerWidth();
},
onMouseOver = function() {
$elLog.html(width);
};
// register the resize function with the "resize" event
$window.on("resize", onResize);
// register the mouseover function with the "mouseover" event on the scrollbar
$elLog.on("mouseover", onMouseOver);
// there is no need to call onResize(), as we've already set the width variable
I Found resize code in my page is triggeing more than once during orientation change in devices. Suspecting this is due to other events like page scroll happening during page mode change from Landscape to Portrait and vice versa. I need to write logic in window resize but its calling more than once. Is there any way we can avoid other events impacting window resize
Window resize event fires multiple times during each window resize. As Rory McCrossan points out above, the event fires once for each pixel it changes.
An option is to use a debounce function, such as that described by David Walsh:
https://davidwalsh.name/javascript-debounce-function
Here is another useful article, describing the difference between throttling and debouncing:
https://css-tricks.com/the-difference-between-throttling-and-debouncing/
Finally, you can use the less elegant (but equally effective) method of using a global variable to keep track of when you wish to allow the resize event to fire.
var ok_to_resize=true;
$(function(){
$(window).resize(function(){
if (ok_to_resize){
//run your resize code
ok_to_resize = false;
setTimeout(function(){
ok_to_resize = true;
},500);
}
}); //END window.resize
}); //END document.ready
I get multiple pages saying that the resize event can be on a body or div element:
http://www.w3schools.com/jsref/event_onresize.asp
http://v3.javascriptmvc.com/docs/jQuery.event.special.resize.html#&who=jQuery.event.special.resize
but then I tried it in jsfiddle or in a standalone page and never can get a resize event on an element:
http://jsfiddle.net/sgHck/1/
http://jsfiddle.net/sgHck/8/
Can body or div get a resize event at all? If not, what if we need to shrink a section down in the page, and part of the page relies on the scroll event to properly place another element, and the resize event for the document, not the window, will also be needed as well?
After digging around a bit it appears that they can have resize events just not quite in the way you want.
You can add a resize event like this
$('#content').resize( function(){
//stuff to do
}
or
$('#content').on('resize', function(){
//stuff to do
}
which you are already doing, but these just don't fire when the elements are resized by javascript code or anything like that. the only way to trigger it this way is with
$('#content').trigger('resize');
which you can really do with any string. This does propagate up through the dom tree. Say you had the #content inside of a body with a 'resize' event on both of them. If you trigger the #content it will also trigger the body. However, if you trigger the event with body it will not trigger the #content.
However it seems you can get the type of functionality you want with the jquery-ui resizable method http://jqueryui.com/resizable/. After you make something resizable with
$('#content').resizable({options});
it should trigger the resize event if they are changed.
This question already has answers here:
How to detect DIV's dimension changed?
(28 answers)
Closed 7 years ago.
I have a very simple question, or at least it seems that way.
I have a DIV element which will be resized at one moment. I want to be able to capture the resizing moment.
Something like this:
function myFunction(){
alert('The DIV was resized');
}
divElement.addEventListener("resize", myFunction, false);
Does anyone know the answer?
Thanks
As of December 2011, there's no built-in event to detect when a div resizes, just when a window resizes.
Check out this related question: Detecting when a div's height changes using jQuery, and this plugin from the solution to that question: http://benalman.com/projects/jquery-resize-plugin/
With jQuery resize event, you can now bind resize event handlers to
elements other than window, for super-awesome-resizing-greatness!
Why is a plugin needed for the resize event?
Long ago, the powers-that-be decided that the resize event would only
fire on the browser’s window object. Unfortunately, that means that if
you want to know when another element has resized, you need to
manually test its width and height, periodically, for changes. While
this plugin doesn’t do anything fancy internally to obviate that
approach, the interface it provides for binding the event is exactly
the same as what’s already there for window.
For all elements, an internal polling loop is started which
periodically checks for element size changes and triggers the event
when appropriate. The polling loop runs only once the event is
actually bound somewhere, and is stopped when all resize events are
unbound.
Sample Code
// You know this one already, right?
$(window).resize(function(e){
// do something when the window resizes
});
// Well, try this on for size!
$("#unicorns").resize(function(e){
// do something when #unicorns element resizes
});
// And of course, you can still use .bind with namespaces!
$("span.rainbows").bind( "resize.rainbows", function(e){
// do something when any span.rainbows element resizes
});
You can try this plugin - http://benalman.com/code/projects/jquery-resize/examples/resize/
There are various examples. Try resizing your window and see how elements inside container elements adjusted.
Example with js fiddle
In that resize() event is bound to an elements having class "test" and also to the window object and in resize callback of window object $('.test').resize() is called.
e.g.
$('#test_div').bind('resize', function(){
console.log('resized');
});
$(window).resize(function(){
$('#test_div').resize();
});
See this
My first thought is to use a custom event system. You can find a pure javascript one here ( http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/ )
After including his code, you can do something like this:
function myFunction(){
alert('The DIV was resized');
}
div_elm = document.getElmentById('div-to-resize');
EventTarget.call(div_elm);
div_elm.addListener("resize", myFunction);
Then later, just add one line to wherever you are resizing the div.
div_elm.width += 100 //or however you are resizing your div
div_elm.fire("resize");
I think that should work for you.
EDIT:
If you are not the one coding the resizing, then my first thought is something like this:
var resizeScannerInterval_id = (function(div) {
var width = div.offsetWidth;
var height = div.offsetHeight;
var interval_id = setInterval(function() {
if( div.offsetWidth != width || div.offsetHeight != height )
width = div.offsetWidth;
height = div.offsetHeight;
div.fire();
}
},250);
})(document.getElementById('div-id'))
There is a very efficient method to determine if a element's size has been changed.
http://marcj.github.io/css-element-queries/
This library has a class ResizeSensor which can be used for resize detection. It uses a event-based approach, so it's damn fast and doesn't waste CPU time.
Please do not use the jQuery onresize plugin as it uses setTimeout() loop to check for changes. THIS IS INCREDIBLY SLOW AND NOT ACCURATE.
I am defining a resize handler that positions some elements on the screen, like this:
$(window).resize(function() {
// Position elements
}
I also want to execute this functionality when the page first loads, so I just add the following right after the above code:
$(window).resize();
This works just fine. However, I'm wondering if I may trigger any side effects, harmful or not, by calling this function - I really just want to execute my own resize handler. Of course, I could do the following to make sure that I execute only my handler:
var positionElements = function() {
// Position elements
}
$(window).resize(positionElements);
positionElements();
However, I'm new to JavaScript and I want to keep my code as concise as possible - this adds some boiler plate code to the mix.
Edit: In fact, my code can be shortened even more by using chaining. Like this:
$(window).resize(function() {
// Position elements
}).resize();
I cant see how it should be harmful, anything that could be triggered by a resize that is actually destructive should be avoided in the first place. What you are doing by using calling $(window).resize() is the same as the user resizing the window.
TL;DR; Yes its safe.