I've currently encountered this issue on Microsoft Edge 44.18362.449.0 which I do not know how to solve.
I applied an event listener on the window in order to perform some resizing actions. This works perfectly on Chromium-based browsers and IE11. For some reason on Edge when I try printing out the window.innerWidth in the resize function it stops at 562px. This means the event listener does not trigger when the window size goes under 562px.
Did anyone encounter this issue before?
I try to test the below code with the MS Edge legacy browser 44.18362.449.0, IE 11 browser, and Google Chrome browser.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
<div id="result"></div>
<script>
function displayWindowSize()
{
var w = window.innerWidth;
var h = window.innerHeight;
document.getElementById("result").innerHTML = "Width: " + w + ", " + "Height: " + h;
}
window.addEventListener("resize", displayWindowSize);
displayWindowSize();
</script>
</body>
</html>
Output:
Based on my test result, I noticed that the MS Edge legacy browser can minimum show the 562 px of window width but user can still decrease the size by resizing the window width but the MS Edge legacy browser will keep displaying the width 562 px.
Generally, the browsers stop resizing at some point and it shows that value as a height or width. Here, the issue is that the MS Edge legacy browser shows the minimum 562 px of width but the user can still decrease the window width.
I suggest you press ALT + J key in the MS Edge legacy browser window and it will launch the Feedback hub. You can try to provide feedback regarding this issue.
Related
The window.innerWidth on Chrome iOS 87.0.4280.77 seems to be incorrect after orientation change event. When viewing on the iPhone, on initial load the innerWidth is 414px. After changing the phone orientation to landscape and then back to portrait, the innerWidth becomes 326px.
I've also checked the innerwidth using https://whatismyviewport.com and it shows the same innerwidth values as my code.
On initial load, before orientation change
After orientation change to landscape and back to portrait
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
</head>
<body>
<script type="text/javascript">
alert("innerWidth1:"+window.innerWidth); // initial innerwidth before orientation change
window.addEventListener('orientationchange', function() {
alert("innerWidth2:"+window.innerWidth); // innerwidth after orientation change
});
</script>
</body>
</html>
Has anyone else encountered this issue before?
Thank you
It seems the window.innerWidth reading has not changed when the orientationChange function is run, but if we set a timeout and read it again it has changed to its expected value.
Set the Pause in this snippet to see the effect. Note that (at least on Safari on IOS14.2 on iPad) a pause of 0ms is sufficient to force a reassessment of innerWidth.
I have tried to find official documentation of this behaviour but have so far failed, though there is quite a bit of discussion out there. It's as if the system has to 'repaint' the window and while doing so finds out the actual innerWidth. Anyway, a practical workaround seems to be to introduce the setTimeout, perhaps with 1ms pause 'just in case' rather than 0ms (I've seen Firefox not fire a repaint on 0ms on some systems in the past). Also, requestAnimationFrame did not result in getting the right width.
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
</head>
<body>
<div id="info"></div>
Pause: <button onclick="pause = 10000">10000</button> <button onclick="pause = 10">10</button> <button onclick="pause = 0">0</button>
<script type="text/javascript">
const info = document.getElementById('info');
let pause = 10000; //number of ms to wait before read innerHTML again
info.innerHTML = "innerWidth1:"+window.innerWidth; // initial innerwidth before orientation change
window.addEventListener('orientationchange', function() {
info.style.color = 'red';
info.innerHTML = "innerWidth on orientation change before pause:"+window.innerWidth;
setTimeout(function() {info.style.color = 'blue';
info.innerHTML = "innerWidth after orientation change and a pause of: " + pause + 'ms ' + window.innerWidth}, pause); // innerwidth after orientation change
});
</script>
</body>
</html>
When in google chrome's device mode, what does window.innerWidth return? Is it the viewport of the device (plus any scroll bars)?
I'm getting different values for the device's width x height (the dimensions on top of the page - the device's viewport?) and window.innerWidth x window.innerHeight (browser's viewport?). Is this supposed to happen?
Here's a picture of what I'm getting, and the code I used.
<!doctype html>
<html>
<head></head>
<body>
<script>
var image;
window.onload = function() {
image = document.getElementById("img");
checkWindowSize();
window.addEventListener('resize', function(event){
checkWindowSize();
});
}
function checkWindowSize() {
var width = window.innerWidth,
height = window.innerHeight;
console.log("window.innerHeight: ", window.innerHeight, " window.innerWidth: ", window.innerWidth);
}
</script>
<img id="img" class="vid-img-filter" src="http://i.imgur.com/jkhFJMn.jpg" alt="">
</body>
</html>
window.innerWidth and innerHeight return the dimensions of the visual viewport. In desktop browsers, this is generally the browser's window dimensions. On mobile the situation is a bit more complicated because of pinch zoom.
When you load a page without a <meta name="viewport"> tag, a default layout width is used (e.g. Chrome uses 980px). When the browser loads the page it does so maximally zoomed out. It looks like your device size above has a width of 425px so the browser zooms out when the page is loaded to see the whole 980px. If you have content that's wider than this (e.g. your image) it'll zoom out even further. Seeing as how your window.innerWidth is 1248, that implies a scale factor of about 30%.
tl;dr: innerWidth/innerHeight reflect viewport with the pinch-zoom factor applied and the page is loaded fully zoomed out.
EDIT: This has since changed in Chrome. window.innerWidth now returns the layout viewport width. To get the visual viewport width, use window.visualViewport.width. See this article for more details.
I'm not sure if this is a recent update (since the last responses), but I was able to find the viewport height/width by using:
window.screen.width
and
window.screen.height
This was particularly useful when I was trying to test whether the screen was phone-sized or not.
We're currently having success with something like:
const widths = [window.innerWidth];
if (window.screen?.width) {
widths.push(window.screen?.width);
}
const width = Math.min(...widths);
The conditional check is there because I'm not sure how widespread the screen width API is. You may need to adjust this not to use certain newer JS features depending on what devices you are targeting/your build process.
This could potentially go a bit weird if you have a window that is wider than the screen, but for us that isn't a problem.
This gives us a width that matches the one at the top of the Responsive screen tool, even when contents overflow horizontally. This is important for us because we needed the UI to change in order to prevent that overflow, but the overflow was interfering with the width number we used to trigger the adjustment.
I'm not sure if this is important, but we are also using:
<meta name="viewport" content="width=device-width, initial-scale=1" />
I have a code below that tries to determine whether someone is accessing my site from a mobile or desktop, by the innerWidth of their device. However, when I tried to get the innerWidth from my mobile, it shows that the width of my mobile is 980px? There's no way the width of my mobile is anywhere near that wide though. The width of my mobile is around: 300px, and the height is around 500px. On, my desktop though, it shows 1280px, which is correct. My questions is, why is it showing the wrong width for my mobile? Unless there's something I'm not understanding correctly?
<?php
include("ajaxLink.php");
?>
<script>
$(function(){
var width = window.innerWidth;
alert(width);
if (width > 500) {
alert("going to index");
window.location = "/";
} //end of if (width > 500)
else {
alert("going to mobile");
window.location = "mobile.php";
} //end of else (width <= 500)
});
</script>
window.innerWidth represents viewport pixels on most mobile devices and not physical pixels. You should be able to get around this through clever use of doctype declaration (such as.. actually declaring a doctype) as well as including a meta viewport tag in a head section. Here's a quote from this article that goes into detail about your specific question:
But when the viewport has not been constrained, and an HTML5 doctype (or none at all) is used, innerWidth will suddenly start to represent values much larger than the physical screen: and represent the width of the viewport canvas upon which the page has been rendered.
On a portrait iPhone, for example, the default viewport is 980 pixels. On a landscape iPhone it is, well, according to window.innerWidth, 981 (yes, really).
I would try this:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
</head>
According to quirksmode, window.outerWidth also jumps from being actual pixels to viewport pixels when zooming.
On a web page, I need to test if there is a horizontal scrollbar or not (so that I programmatically change the css of some other element). Is there some way to get that information using jquery (or pure javascript)?
I tested
function isHorizontalScrollbarEnabled() {
return $(document).width()!=$(window).width();
}
but it does not seem to work with all browsers (does not work for example with a recent Samsung phone I tested). I need it to work with all browsers, including recent mobile devices.
Thank you!
EDIT 1
I tested the solutions provided by plalx and laconbass, tested IE8, Firefox, Chrome and iPad. Works with IE, Firefox & Chrome but not as I want on the iPad.
The problem seems related to the zooming feature on mobile devices: even though, when I zoom in on the iPad, a horizontal scrollbar appears, document, window and document.body widths do not change (was also the same problem with the Samsung phone I tested earlier today).
Here is the code I used to test:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<title>test</title>
</head>
<body>
<div style="width: 500px; background: red;" id="test">click here to test</div>
<script type="text/javascript">
var i = 1;
$("#test").click(function(){
$(this).html("Test #" + (i++)
+ "<br>document width=" + $(document).width() + ", windows width=" + $(window).width()
+ "<br>document width=" + $(document).width() + ", body width=" + $(document.body).width()
);
});
</script>
</body>
</html>
Any idea how to detect the presence of a horizontal scrollbar that also works after zooming in/out on a mobile device like iPad?
//scrol 1px to the left
$(document).scrollLeft(1);
if($(document).scrollLeft() != 0){
//there's a scroll bar
}else{
//there's no scrollbar
}
//scroll back to original location
$(document).scrollLeft(0);
This works because JQuery won't be able to scroll the screen if no scrollbar is available
EDIT 2: I got a downvote because this doesn't work for nothing but the page so I built a generic solution based on #Pabs123's answer, only for fun:
function hasScrollX( selector ){
var e = $(selector), fn = 'scrollLeft';
return e[fn](1) && e[fn]() > 0 && e[fn](0) && true;
}
or even
jQuery.fn.hasScrollX = function( ){
var fn = 'scrollLeft';
return this[fn](1) && this[fn]() > 0 && this[fn](0) && true;
}
See it here, and how it can be easily adapted to detect vertical scrollbar presence.
EDIT: Tested & working on chrome and firefox. As jQuery team does the crossbrowsing work, i suggest the use of jQuery rather than native javascript.
I were curious about how to do this in an elegant way than the suggested previously (which actually work)
The following comparison work to me
$(document).width() > $(window).width()
you can see it in action with scroll bar and without it
I'm working on a web app that is targeted to browsers on desktop, tablet and smartphone.
The web app has a light box implemented using Colorbox with an iframe. When the browser window is resized or the tablet/phone has it's orientation changed, Javascript code queries the window dimensions so that it can resize some elements of the light box.
The issue I'm having is that everything works fine on desktop (Windows: IE, Firefox, Chrome, Mac: Safari), iPad & iPhone but not on the Android smartphone (HTC) and Android Emulator.
Android always returns different values for screen.width, screen.height, window.innerWidth & window.innerHeight when they're queried from inside the window's resize event, which fires multiple times.
Why is the Android browser returning such a wide variance in values and how can I reliably detect the width and height of the browser window?
On Android, window.outerWidth and window.outerHeight are reliably the screen size. Depending on your version of Android, innerWidth/Height is usually incorrect.
Here's a really good writeup on the situation.
Below is differentiation based on readings with Samsung Tab running Android 4.1
screen.height - gives actual device height including task bar and
title bar
window.innerHeight - gives the height excluding task bar, title bar
and address bar(if visible)
window.outerHeight - gives the height excluding task bar and title
bar height, (no matter address bar is visible or hidden, outerHeight
include the address bar height.)
I took me hours to find a workaround.
The only constant among window.innerHeight, window.outerheight, etc was screen.height.
This code gave me the outerheight:
screen.height / window.devicePixelRatio - window.screenTop
Also, in order to support older versions of android, place your code in a setTimeout
I hope this is helpful =)
I'm using this to make it work between ios and android.
var screenHeight = (ionic.Platform.isIOS()) ? window.screen.height : window.innerHeight * window.devicePixelRatio;
Try this, and check your mobile reading
<script>
var total_height=screen.height*window.devicePixelRatio;
alert(total_height);
</script>
It should match the screen size (height) of your phone specifications.
var throttle = (function () {
var timer;
return function (fn, delay) {
clearTimeout(timer);
timer = setTimeout(fn, delay);
};
})(),
var callback = function (w, h) {
alert(w + ' ' + h);
}
window.onresize = throttle(function () {
width = Math.min(window.innerWidth, window.outerWidth);
height = Math.min(window.innerHeight, window.outerHeight);
callback(width, height);
}, 60);
Dan's answer fix the inconcistancy between android's browser..
so I post how I detect/change mobile viewport and adapt it when rotated
(don't know if usable for any one...
var lastorg=0; //set the begining of script
thisorg=parseInt(window.innerWidth)/parseInt(window.innerHeight); //for ratio to detact orietation
if(((lastorg<1 && thisorg>1) ||(lastorg>1 && thisorg<1) ||lastorg==0 )){ //is start or change
$("#viewport").attr('content', 'width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1'); // reset viewport to device
mywidth = Math.min(window.innerWidth, window.outerWidth); //Dan's way to fix the inconsistancy
myheight = Math.min(window.innerHeight, window.outerHeight);
lastorg=thisorg; //update the lastorg
wr=parseInt(mywidth)/1280; // the minimum desire width
hr=parseInt(myheight)/630; // the minimum desire height
if(hr<wr){
vscale=hr;
if(hr<1){ // if it if small screen, so desktop pc wouldn't change
windowHeight=630;
windowwidth=mywidth/hr;
}
}else{
vscale=wr;
if(wr<1){
windowwidth=1280;
windowHeight=myheight/wr;
}
}
$("#viewport").attr('content', 'width=device-width, initial-scale='+vscale+',minimum-scale='+vscale+', maximum-scale='+vscale); //reset viewport toresize window
if(thisorg>1){
$("#pro").fadeOut(500);
}else{
$("body").prepend("<div id=pro style='position:absolute;width:800px;height:30px;padding:30px;left:"+(windowwidth/2)+"px;top:"+(windowHeight/2)+"px;margin-left:-430px;margin-top:-45px;;border:1px solid #555;background:#ddeeff;text-align:center;z-index:99999;color:#334455;font-size:40px;' class=shadowme>Please rotate your phone/tablet</div>");//tell user to rotate
}
}
In my case, the setTimeout hook was not useful.
After some digging, I discover that different Android versions (and devices) have different devicePixelRatio values.
If the devicePixelRatio is equal or greater than 1, the actual number of pixels in the screen (for the html page point of view) is given by window.screen.width (or ...height).
But, if the window.screen.width is less than 1 (it happens in some old Android devices), the actual number of pixels becomes: window.screen.width/devicePixelRatio.
So, you just have to cope with this.
w = window.screen.width;
h = window.screen.height;
if(window.devicePixelRatio < 1){
w = window.screen.width/window.devicePixelRatio;
h = window.screen.height/window.devicePixelRatio;
}