Does getting the offsetHeight of an element have a side effect? - javascript

In the code for Bootstrap collapse, in the hide() method, I see the following line:
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
I don't understand what the point of the .offsetHeight at the end is unless it has a side effect, because it's not being assigned to anything. Does it have a side effect?

Some old browsers like old versions of IE had the problem of sometimes not reflowing (re-rendering the presentation) after you performed some actions.
Mearly querying some properties like offsetHeight forces the DOM to recalculate and redraw the objects on the screen.
So, the side effect is forcing a reflow (redraw) of the screen. Quirky, but an old trick for old browsers.
Here is a question where this is suggested as a solution for an old version of Google Chrome where it did not work properly without it.

here is a useful comment from bootstrap team:
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow

Related

Force IE to 'redraw' an element with JavaScript to fix CSS bug?

Im experiencing an IE bug. The CSS counter property doesn't work in IE9 for elements that are hidden on page load (eg tabs).
css counter not working in internet explorer for hidden content - how to fix?
As I posted above, I've been able to fix this by setting some inline CSS with JavaScript. I set padding-left to 0 (even though the element already had no left padding) when its unhidden. This makes IE 'redraw' the element and the CSS is then applied correctly.
This isn't and ideal solution however. If the design changed to have left padding on the element then my JavaScript fix would break the layout. What other method can I use to make IE 'redraw' the element? Is there a standard way to do this?
Paul Irish has compiled a list for you
What forces layout / reflow. The comprehensive list.
All of [the properties or methods found at this link], when requested/called in JavaScript, will trigger the browser to synchronously calculate the style and layout*. This is also called reflow or layout thrashing, and is common performance bottleneck.
I don't want to post the entire list here to avoid plagiarizing, since I am essentially adding nothing to the answer; I am simply pointing you to it.
However, I will say that while Paul Irish warns that using these is a "common performance bottleneck", they can be used strategically to force reflow when desired. This is especially useful in browser-specific scenarios.
If you want to limit the reflow to just IE9, you will want to wrap your layout-thrashing calls inside a feature detection check.

Trigger a function when elements need re-rendered in an extension?

I have a function that positions an element in my Firefox extension, and I need that function to be called whenever an event causes the window/chrome layout to change.
Events would be:
When a new window is created, after the chrome is rendered.*
When a window is re-sized.
Any other event that might cause the chrome layout to change size or shape?
(*) Right now, the function runs when a new window is created using:
window.addEventListener("load",myfunction);
But this runs before the chrome is rendered, and element sizes have wonky values. I need it to run after Firefox determines the actual size and placement of the chrome elements.
What are the events I would need to bind to, and how do I bind them?
I was in a similar situation, and didn't really find a good solution. However, the non-standard MozAfterPaint event may help, but comes with a somewhat sizable performance penalty however (so make sure you remove it once you don't need it anymore).
The resize event should do the trick.
There are tons of things that may cause things to change. New CSS/Images loading, toolbar customization, etc. 1. and 2. should cover most (all?), however.
The devtools layoutview ("Box Model") seems to use MozAfterPaint as well.
If possible, you should try to avoid having to calculate sizes yourself, however, by making use of the XUL/HTML flexbox model and CSS without fixed sizes (or min/max sizes only).

Strange IE8 problem with a select that runs AJAX

I've got a strange error with IE8 and postcode lookups. It may not be postcode lookups as such that's causing it - just an AJAX call that modifies a select. I've set up a test page here. If you click on Find Address, and then double click (quite quickly) on one of the addresses that is within the boundary of the red-bordered div, you see the below bug in IE8.
Note: I'm finding it inconsistent to reproduce the bug, but if you scroll the list of addresses right to the bottom and then double click fast on Holly Cottage it should reproduce the bug.
If anyone can shed on light on this quirky behaviour it'd be much appreciated. Is this an IE8 bug?
I've found the problem - browsers do not like having javascript:void() set for the href attribute. If you want to have a working anchor whose default action is canceled, then use # for the href attribute, then have the event handler for that anchor return false to cancel the browser's default action.
Erm... right... sorry for my eagerness to post an answer and not double check that the problem was properly solved.
I'm finding it difficult to find the problem. I'm only going to hazard a guess here: the two effects running and ending at the same time confuses IE8, causing the div to be set to a height of 1px. This of course assumes a bug in the jQuery implementation of the effect queue, which I definitely cannot vouch for. It's just my theory at the moment - my unfamiliarity with IE developer toolbar prevents me from investigating further.
It's a problem with You running animations I suppose.
Your asynchronous action triggers some sliding animations.
First:
Try logging endings of all animations (put a callback function in the slide* call and log some text to console.) to see if they run in correct order - I suppose they don't and that's the problem.
Second:
Try adding .stop() before every asynchronously triggered animation so that it breaks other animations working at the same time.
Third:
If the above didn't help try this for every animation:
if($(this).data('running')==0){
$(this).data('running',1).slideUp(function(){$(this).data('running',0)});
}else{ /*call with timeout or ignore...*/ }
It's a basic semaphore on an element.
OR
You can use .animate and animation queues in jQuery properly, but it'd be a bit of an overkill for this case (I think).
My first reaction is it may be a CSS issue. If I find the default value, and click the 'Find Address' link one time, I see a similar (though not identical) layout problem. The height on each section looks collapsed, as if the floating sections aren't picking up the correct content height. If I incrementally specify a height on each contentRow or switch the display from block-none-block on pcodeLookupAddressEdit_risk_address, the formatting is corrected.
I don't know the specific cause, but, you may want to check the CSS and the show/hide behavior on the slide.

Javascript/jQuery outerHeight()

Does $('#idOfLememt').outerHeight(); yield same result for all browsers? Any thing different for IE7?
Just go to http://api.jquery.com/outerHeight/ with the different browsers you want to test and see for yourself (on Mac OS X so can't check IE for you). It looks like the DOM in the demo has all possible styles that would affect this included.
Most of the time you can rely on jQuery to do it's thing and give you consistent results across browsers, that's one of it's main reasons for being after all.
Edit: Of course this won't be the case if the browser messes up with something else, for example if your container isn't fixed height and IE renders something inside your container with a different height for whatever reason then the result would be different. You are however pretty much guaranteed to always get the same result as the amount of pixels used on screen.
Like SLaks said it should work fine.
There is one downfall you might run into though if you aren't explicitly setting margins and padding in your CSS. outerHeight() will include padding and border always and if includeMargin is true than it will also include margins. With some padding/margin discrepancies across browsers... ahem... IE... you may get different calculations unless you've explicitly set the border, padding and margin on the element in question.
It should work fine. (Unless you have other layout issues)

Triggering the refresh event in Internet Explorer

On a dynamic site of mine I faced a problem that consists in the following:
In Internet Explorer 6 after changing the size of the div element with the help of JavaScript, its child elements that are 100% in height do not refresh right away (ie. do not stretch to their new size) but only when the parent div is clicked. It seems to me that the document needs some update. I'd like to ask if there is sort of a command (like that in Flash) that updates the document after some dynamic changes get happened? In brief, how can this problem be settled?
Requiring reflow in IE6 is a very common problem with a massive CSS/JS base. Usually all you have to do is change a parameter on the element that requires a reflow, like, for example, set display:none and then back. This will cause browser to reflow objects in and around current object. Most of the time you will have to do it from JavaScript. If you don't want to do display, try changing height/width or add/remove flow or clear parameters. They all will cause reflows of the page.
However, most of the time if you are running into reflow issues in IE6 it usually means that either you have way too much CSS on the page, or you are using CSS for things it shouldn't be used for (like laying out elements on the page that in HTML go in a wrong order, i.e. element1, element2, element3 in HTML; element2, element1, element3 in display). I would suggest cleaning up your CSS and most of the times, reflow problems will go away.
If you have to click on it to refresh, then why no try to simulate a click, after the size update. Simulating mouse clicks in JavaScript
I know that I have been burned (more than once unfortunately) to have returned invalid xml for an ajax response. IE in particular is very non-forgiving in this respect. It might be worth validating the response just to be sure. In some of my cases, the bad XML caused JS to fail and not "seem to work".

Categories

Resources