Get Android Chrome Browser Address bar height in JS - javascript

How do I get the height of the address bar in JavaScript in the Chrome browser for Android (marked by red rectangle in left picture)? I need to know that as it disappears while scrolling down and I need to react to that because the viewport height is different then.
One solution I already figured out:
Get viewport height at initial state:
var height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
Get viewport height when the address bar has disappeared
Compute difference between both values
Problem is that you have to be in the second state to know that.

Because 100vh will be larger than the visible height when the URL bar is shown. According to this.
You can calculate the height of the URL bar by creating a 0-width element with 100vh height.
<div id="control-height"></div>
#control-height {
height: 100vh;
width: 0;
position: absolute;
}
Then using javascript compare window.innerHeight with the height of this element.
const actualHeight = window.innerHeight;
const elementHeight = document.querySelector('#control-height').clientHeight;
const barHeight = elementHeight - actualHeight;

The thing you're are looking for is url bar resizing. Since Android's chrome v56, it's recommended by David Bokan to use vh unit on mobile. There is a demo in that article, clicks the link to get more informations and how to use it on mobile.
When the user is scrolling down the page, a window.resize event is throwed.
You could update your page by catching this event with an event listener.
More informations : mobile chrome fires resize event on scroll

Best approach for me was to have something like that:
$(document).ready(function(){
var viewportHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var isPortrait = viewportHeight > viewportWidth;
$( window ).resize(onresize);
function onresize() {
var newViewportHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var newViewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var hasOrientationChanged = (newViewportHeight > newViewportWidth) != isPortrait;
var addressbarHeight = 130;
if (!hasOrientationChanged && (newViewportHeight != viewportHeight)) {
addressbarHeight = Math.abs(newViewportHeight - viewportHeight);
if (newViewportHeight < viewportHeight) {
// Android Chrome address bar has appeared
} else {
// Android Chrome address bar has disappeared
}
} else if(hasOrientationChanged) {
// Orientation change
}
viewportHeight = newViewportHeight;
viewportWidth = newViewportWidth;
isPortrait = viewportHeight > viewportWidth;
}
});

Had the same issue today, turns out there is no easy way to figure out the height of the url bar directly. As far as I know, none of the directly accessible variables in javascript can tell you how much the size of "100vh" really is.
On mobile browsers, 100vh may or may not include the height of the url bar, which leaves us in a tricky situation, if we want to size a div to the exact height of the visible content area of the browser during load.
I figured out a workaround though that worked pretty neat for me, here's what I did:
add a dummy property on your html root element with a size of 100vh. In my case, i used the "perspective" attribute, which worked for me
then you can get the address bar size with the following code:
var addressBarSize = parseFloat(getComputedStyle(document.documentElement).perspective) - document.documentElement.clientHeight

I had a container with dynamic content that had to always have at least viewport's full height (and be scrollable if the content doesnt fit on the screen).
So if you need a fixed height, just replace "min-height" with "height" in my solution.
That's how I dealt with it.
// calculate min-height on init
$(".content-container").css("min-height", `${window.innerHeight}px`);
// recalculate the min-height everytime the bar appears or disappears
$(window).resize(() => {
$(".content-container").css("min-height", `${window.innerHeight}px`);
});
It works for android's address bar and also safari's bars (in safari mobile there can be top and the bottom bar aswell).
Then to make the transition smooth, you can apply a css rule:
.content-container{
transition: min-height 500ms ease;
}

Related

Any known javascript or css that causes Chrome to not scroll vertically on a MacBook display?

I have a weird issue where my div is not scrolling vertically in Chrome on my MacBook display. If I move the window (without resizing it or anything) to a different display vertical scrolling works. If I scroll horizontally first that "unlocks" the vertical scrolling. Only in Chrome, only on the MacBook display.
I can't share the page here, but I can try to re-produce it with some different content if that is helpful. Thought I would check if it is a known issue first. I have some jquery resizing things going on that might be a lead.
setTimeout(function() {
var table_p = $("#table");
var position = table_p.position();
var viewheight = $(window).height() - position.top - 10;
table_p.height(viewheight);
$(window).resize(function() {
var table_p = $("#table");
var position = table_p.position();
var viewheight = $(window).height() - position.top - 10;
table_p.height(viewheight);
});
}, 250);
Turns out setting a height in the css for #table fixed the problem, even though the height is replaced by js soon after.

How to redesign ionic app layout so it looks good on all devices?

For example I want to set the height of a button or a header and make it 20% of the devices's vertical viewport. I can go and change it in the CSS file. But that doesn't take different screensizes into account. For example setting the attribute "height" of that button (or any other element) to 20%, but that means it is 20% of it's parent element, but not the height of the screen size of a given device. I can set it to a specific value in px. But that means the button's height is fixed.
I could do it with viewport: vh, vw.
.myButton {
height: .2vh;
}
But this is not supported on older devices (~Android 4.4). I'm thinking of doing it with vanilla JavaScript:
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
viewPortWidth = w.innerWidth || e.clientWidth || g.clientWidth,
viewPortHeigth = w.innerHeight|| e.clientHeight|| g.clientHeight;
button.height = viewPortHeigth * .2 + "px";// height of button will be dependent on device's viewport height
But I wonder whether there is another method that is recommended by experienced developers or the ionic team.
How can I set certain elements to a certain value relative to the device's size.
What worked best for me was media-queries.
For more information about this topic and more alternatives see here:
https://forum.ionicframework.com/t/support-for-various-mobile-devices-ios-android-phones-tablets-how-to-manage/17406

JavaScript getting the wrong window size

I am messing around with some code and applying / removing classes based on window size and I'm running into a weird error. I've confirmed that I'm at the default zoom (if that matters), and I've replicated the issue in FF & Chrome.
I have a resize event handler that I'm just using to monitor the javascript window width value vs. the actual value (I have a chrome extension which shows the window & viewport width as you're resizing, and my bootstrap viewports hit exactly as they should at 992px, 1200px etc, so I know that the javascripts value is off for some reason and not vice-versa)
For some reason, as I resize the window, the value for window width that shows in the console.log, is always 21px smaller than the actual screen size. This is the code that I'm using for the test:
var w = 0;
$(function () {
w = $(window).innerWidth() || $(window).width();
})
$(window).resize(function () {
if (w != $(window).innerWidth()) {
w = $(window).innerWidth() || $(window).width();
console.log(w);
}
});
Give this a try:
var iw = $('body').innerWidth();
jsBin demo
answer from: https://stackoverflow.com/a/8340177/504836

JavaScript getBoundingClientRect() changes while scrolling

I want to have the exact distance between the Y-coordinate of an element an the Y-value=0, which I consider as the top of the document.
myElement.getBoundingClientRect().top;
But the value of getBoundingClientRect() seems to change while scrolling. How can I get the real distance between myElement and the Y-coordinate=0 (top of document)?
It is because getBoundingClientRect() gets values with respect to the window(only the current visible portion of the page), not the document(whole page).
Hence, it also takes scrolling into account when calculating its values
Basically, document = window + scroll
So, to get the distance between myElement and the Y-coordinate=0 (top of document), you would have add the value of vertical-scroll also:
myElement.getBoundingClientRect().top + window.scrollY;
Source: https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
getBoundingClientRect needs a bit more care to avoid bugs in scrollY/pageYOffset:
function absolutePosition(el) {
var
found,
left = 0,
top = 0,
width = 0,
height = 0,
offsetBase = absolutePosition.offsetBase;
if (!offsetBase && document.body) {
offsetBase = absolutePosition.offsetBase = document.createElement('div');
offsetBase.style.cssText = 'position:absolute;left:0;top:0';
document.body.appendChild(offsetBase);
}
if (el && el.ownerDocument === document && 'getBoundingClientRect' in el && offsetBase) {
var boundingRect = el.getBoundingClientRect();
var baseRect = offsetBase.getBoundingClientRect();
found = true;
left = boundingRect.left - baseRect.left;
top = boundingRect.top - baseRect.top;
width = boundingRect.right - boundingRect.left;
height = boundingRect.bottom - boundingRect.top;
}
return {
found: found,
left: left,
top: top,
width: width,
height: height,
right: left + width,
bottom: top + height
};
}
The bugs to avoid are:
scrolling in Android Chrome since Chrome Mobile 43 has wrong values for scrollY/pageYOffset (especially when the keyboard is showing and you scroll).
Pinch-zoom in Microsoft IE or Edge causes wrong values for scrollY/pageYOffset.
Some (obsolete) browsers don't have a height/width e.g. IE8
Edit: The above code can be simplified a lot by just using document.body.getBoundingClientRect() instead of adding a div - I haven't tried it though so I am leaving my answer as it stands. Also the body needs margin:0 (reset.css usually does this). This answer simplifies the code down a lot, while still avoiding the bugs in jQuery.offset()!
Edit 2: Chrome 61 introduced window.visualViewport to give correct values for the actual viewport which is probably another way to fix issues; but beware that Android Chrome 66 was still buggy if Settings -> Accessability -> Force enable zoom was ticked (bugs with orientation change, focused inputs, absolutely positioned popup wider than viewport).

Setting the minimum size of a JavaScript popup window

Is there any way to set the minimum size of a popup window through JavaScript?
My problem is that when someone makes it as small as he can the content just looks stupid.
When creating pop-ups, you can only set width and height. But since the pop-up was created, it means you can change the height and width of the window when the pop-up loads.
Simply place an onload event inside your pop-up window:
window.onload = function() {
if (document.body.scrollHeight) {
var winWidth = document.body.scrollWidth;
var winHeight = document.body.scrollHeight;
} else if (document.documentElement.scrollHeight) {
var winHeight = document.documentElement.scrollHeight;
var winWidth = document.documentElement.scrollWidth;
} else {
var winHeight = document.documentElement.offsetHeight;
var winWidth = document.documentElement.offsetWidth;
}
window.resizeTo(winWidth, winHeight);
}
edit: Tested in IE7,8, Chrome, Safari 4, Firefox 3. Working, but you might need to take into account the size of menu+address bars and such, as the window size will be the outer size, and this function will find the size of the content. So to be safe you should probably add a couple of pixels, and also turn off scrollbars in the popup to make sure they won't take up any space.
I do not believe that you can set a minimum using the Javascript new window. I know you can set the size and disable the scroll bars and prevent resizing, but that would answer the minimum, but also impose a maximum as well, which you may not be wanting.
Most browsers have a minimum width and height.
Internet Explorer 7
minimum width > 250px
minimum height > 150px
When using windows.open, you can specify the height and width of the window like this:
window.open ("http://www.stackoverflow.com",
"mywindow","menubar=1,resizable=1,width=350,height=250");
It is not the minimum size though, as the window will not be bigger when there is more room. You would have to check screen space yourself for that.
http://www.htmlgoodies.com/beyond/javascript/article.php/3471221
As seen in the link, you can set the minimum size. If you want to scale it so it gets bigger you must to that from within the popupwindow.

Categories