Why does $(window).width() change while the page is loading? - javascript

I noticed that my scripts were setting widths incorrectly, so I tried the following snippet:
var prev;
setInterval(function(){
if($(window).width()!=prev)
console.log(prev=$(window).width());
},1);
This printed 2 different values: 1464 and 1481. Since these are 17px apart, I'm almost certain this is caused by scrollbars. The second value is the correct value.
Why does $(window).width() change without resizing the window? Shouldn't it return the browser window's width, which should be constant?

$(window).width() returns the width of the window object excluding scrollbars (otherwise known as the viewport width). Depending on the operating system and browser, the vertical scrollbar can often subtract from the viewport width. This means you should call this function once all your content has been loaded, and you'll need to call it again if the content changes.
Putting this in the $.ready() function won't guarantee that you'll get the correct width with respect to the final page content. This is because $.ready fires when the DOM is loaded, but there might still be images/fonts that can affect the layout. It's very possible that a scrollbar can get added after you call $.ready(). The easiest solution to this problem is to place your call inside the $(window).load() function instead, as this fires when all content has been loaded, and there's nothing more to render.
Generally speaking, it's a good idea to set the width on DOM ready, window load, window resize, and any time the content changes. This can be done like so:
$(function() {
var window_width;
function set_window_width() {
window_width = $(window).width();
// do something with window_width
}
set_window_width(); // set width on DOM ready
$(window).on('load resize', set_window_width); // set width on window load and resize
function custom_load_content() {
// load / change content
set_window_width();
}
});
Most (if not all) of the time, the viewport width is what you want. You're probably using the width to perform some calculations and/or resize some elements, and this should always be relative to the viewport, because your CSS is relative to the viewport. But, if for some reason you want to get the width including scrollbars, you can use window.innerWidth instead (source).

$(window).width() is affected by the margin, border and padding.
These can change as the DOM is being loaded.
As mentioned above, make sure you are waiting until $(document).ready() before you start looking at / twiddling with the DOM objects.
More info here http://api.jquery.com/width/

In most of the cases, the window width changes with the content, so there must be some ajax call coming which changes some content of the window. You can use browser debug tool and open the network traffic window to see what comes when the window width changes, debug into the javascript file to find which part of window changes with that ajax call, this may help you to find the reason.

Related

Listen when #content area is longer than window height (native or Vue.js)

I have a content area that has controls as the footer. The controls always sit below the content area. When the content area is longer than the window.innerHeight I want to pin (position: fixed) the footer to the bottom of the window, so the controls are always visible. If the content area is less then the window height then it sits under it again (position: relative).
I think I have achieved this when the window is resized. However I also want to listen for the #content div as it contains a textarea which can get longer than the window when the user types in it. I need some kind of event listener for this too.
window.addEventListener('resize', function() {
var viewportHeight = window.innerHeight
var contentHeight = document.getElementById('content').clientHeight;
if (contentHeight > viewportHeight) {
console.log('Larger')
} else {
console.log('Smaller')
}
}, true)
I'm using Vue.js so either this or native Javascript, I'm not using jQuery.
Well it's not that easy. Since I don't know Vue.js I can only tell you about native JS solutions - there are two ways:
1) If the content changes only on some particular actions eg. user editing textarea, then you can attach your height checker function to the corresponding event(s).
2) The more general solution would be to set function which will watch for changes continuously like setInterval or requestAnimationFrame.
First example is better from performance point of view but might be harder to implement, it depends on how many things can change size of your content.

windows.onload vs resize different width

I need to adjust several elements in width and height in relation to window width. So I am using
window.onload = function() {
slideSizeUpdate();
};
$(window).resize(slideSizeUpdate);
to call my function.
After window resize everything is displayed correctly - but not onload. I guessed that this had something to do with the window-width-value.
So, I printed the width value of window and recognized that - onload - my window width had a value 'x' and when I resized for 1px left or right value 'x' of window width increased / decreased + / - 18px.
I assume that this causes the problems on my website onload. Does anybody know the reason for this and has anybody a solution how to fix it? That would be great!
EDIT
Its not that onload doesn't work at all. Its just the wrong values that it seems to get when it reads out the window width.
You can do like this:
$(window).on('load resize',function(){
slideSizeUpdate();
}).resize(); // trigger resize when page is loaded
Consider this scenario:
Some of the content is hidden via CSS. The resulting page is short and no horizontal scrollbar is required.
You calculate the window width on load event at which point scrollbars are not there.
You un-hide the content and now the page is tall and requires horizontal scrollbar.
The width of the window decreases by 17px (usual width of scrollbar) without you noticing.
If this is the case then one solution is to force the window horizontal scrollbar using CSS. You can use the following (although I recommend searching more on StackOverflow):
html {
overflow-y: scroll;
}

How to get updated width of content after a css change?

I'm trying to modify the css class of my body element.
Before modifying the class, I check the scroll width of my content:
$(window.document.body).prop('scrollWidth'); // 800px
Now I modify the css class and check the scroll width again:
$(window.document.body).prop('class', someCssClassName);
$(window.document.body).prop('scrollWidth'); // still reports 800px
I know the scroll width should not be 800px after this particular change. I start a timer and keep printing the scroll width, and after a few ms I see it change to 600px.
So it seems like I can't immediately get the updated content width (or I'm misinterpreting what's going on).
Is there a way to get notified when the re-flow is complete, so that I might get the updated width?
I don't want to set a timer and keep checking, if possible.
I'm trying this in an android WebView.. browser.. . So I'm not sure if this behavior will be the same if I try in a desktop browser.
Thank you
To answer the question: accessing the scrollWidth property automatically flushes any style change (forces a reflow) and then returns the computed value. This happens synchronously, hence you don't need to "wait" for the reflow to complete -- the JS will simply freeze while the reflow happens and then return the correct scrollWidth value.
You are actually facing a very specific Blink/WebKit bug in their scrollWidth implementation regarding the body element.
I've simplified your code a bit by removing some unnecessary jQuery abstraction (fiddle):
document.body.className = 'w600px';
console.log(
document.body.scrollWidth, // Firefox: 600, Chrome: viewport width
$(document.body).width() // 600 in both browsers
);
.w600px {
width: 600px;
}
From the CSSOM element.scrollWidth spec:
3. If the element is the HTML body element, the Document is in quirks mode and the element has no associated scrolling box, return max(viewport scrolling area width, viewport width).
It seems like Chrome is not checking whether the document is in Quirks mode and returning the viewport (scrolling) width independent of the document mode.
You should open a Chromium issue in these cases.
Workarounds
It really depends on your use case. $(document.body).width() is usually fine, unless the content overflows the body element's width.
Alternatively, wrap all the page's contents inside of a div and use it to apply the class and to retrieve the scrollWidth from.
Try
function getprop( el, prop ) {
var props = window.getComputedStyle (
$(el).get(0)).getPropertyValue(prop);
return String(props);
};
console.log(getprop("body", "width"))
http://jsfiddle.net/guest271314/6uKH6/5/

Use jQuery to mirror height of a dynamic element

I have a sidebar on my page that I want to always be 100% of the container size. Sadly, I can't tell the element to do this via CSS alone as the page has a variable height due to dynamic content.
Is it possible to use jQuery to find the height of the content container, and adjust the sidebar height to match it?
I found a few jQuery plugins that kind of do what I want, but feel they are over complicated (and I can't seem to get them to work anyway!).
Assuming the id of your container is "container" and the id of your sidebar is "sidebar", you could try the following (untested!)
$(document).ready(function() {
$('#sidebar').height($('#container').height());
});
This should (on document load), resize the sidebar height to the same as the container height.
I'm going to continue on from Damovisa's answer.
$(document).resize(function(){
$('#sidebar').height($('#container').height());
});
However, this could fire an awful lot if you resize the page a lot. You could try this
$(document).resize(function(){
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function() {
$('#sidebar').height($('#container').height());
}, 100);
});
In the second example, it will only resize 100 microseconds after resizing.
This is also assuming that $(document).resize() will be triggered when the page size changes. You could always wrap it in a function, and call it on completion of any slideDown() etc

How to detect when the height of your page changes?

I have a javascript heavy app which has widgets like autocomplete dropdowns and tabs and so forth. Sometimes when dropdowns appear and disappear, or when you switch between tabs, it changes the height of the document. This can cause annoyances if the scrollbar appears and disappears rapidly, because it shifts the page. I would like to detect when a page changes its height, so I can fix the height to the maximum so far, so that if the scrollbar appears it won't disappear only a second later. Any suggestions?
Update: onresize won't work because that's for changes in the size of the viewport/window - I want changes in the length of the document. I hadn't known about the watch function, looks like it will work at least for FF, but IE doesn't support it.
I belive this question has already been answered on stackoverflow here:
Detect Document Height Change
Basically you have to store the current document height and keep checking for a change via a timeoutcall
The element to watch here is document.body.clientHeight (or in jquery $(document).height() )
I think you can trap "onresize" events
here is a link to the w3schools.com description
You can user resize event to trap the change of the size of window using jquery as follows:
$(window).resize(function(){
// your code to check sizes and take action
}
);
Alternately you can track the change in document (not tested)
$(document).resize(function(){
// your code to check sizes and take action
}
);
One idea would be to use the watch() method on the clientHeight property:
document.body.watch("clientHeight", function(property, oldHeight, newHeight) {
// what you want to do when the height changes
});
The function you specify will get executed whenever the specified property changes. At any point you can use the unwatch() method to get it to stop.

Categories

Resources