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" />
Related
I have a dynamically generated iFrame on my page that loads a website using a variable object.
All that is well understood. My challenge now is that in some cases, say if I am viewing on mobile, the frame width exceeds my mobile device width.
// STATIC VALUE
let screenSize = {
"height": window.innerHeight,
"width" window.innerWidth:
}
// DYNAMICALLY GENERATED VARIABLE
let frameValue = {
"url": "https://example.com",
"height": 913,
"width": 1600
}
//Using this variable, the iframe property is set as follows using javascript
$('#dynamicFrame').attr('src', frameValue.url);
$('#dynamicFrame').width(frameValue.width);
$('#dynamicFrame').height(frameValue.height);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- HTML DYNAMIC iFRAME -->
<iframe src="" id="dynamicFrame" frameBorder="0" width="100%" height="100%" scrolling="auto"> </iframe>
Need:
I would like an algorithm (or perhaps some code) to perhaps scale or zoom the iframe whilst keeping its aspect ratio.
Meaning I want the content to of frameValue.url (example.com) to load in the iframe as it would while considering frameValue.width & frameValue.height.
Notes:
I don't mind having the iframe look smaller or have dark bands around the edge just like when you watch videos on a mobile device or use zoom or Microsoft teams on a mobile device whilst the person sharing the screen is on a desktop device.
Please feel free to comment if you need further explanation. Thank you.
Is there any reason you aren't using a CSS solution? It'd be a much cleaner solution than setting the height/width attributes.
#dynamicFrame {
/* Swap for your desired aspect ratio */
aspect-ratio 16/9;
width: 100%;
height: auto;
}
Depending on the screen size and orientation, one of the following formulas may be useful.
NB:The orientation can be determined using the dimensions provided. i.e landcape = width > height
let scale = 0;
// If the window is potrait and the frame is landscape orientation
scale = screenSize.height * (1 / frameValue.height);
// If the window is landscape and the frame is potrait, one of the following applies.
scale = dimensions.height/dimensions.width).toFixed(2);
// OR
scale = dimensions.width/dimensions.height).toFixed(2);
// Set the iFrame Dynamic Scale Value
iframe.style.transform = `scale(${scale})`;
I'm attempting to get the viewport height in mobile browsers WITHOUT the height of the browser bar but all of the solutions I've attempted have come up short.
What others have suggested is using the below, however it does not work for me. I still get a blank white bar at the bottom of the window when scrolling
var screenHeight = window.innerHeight;
$('.mobile-nav-wrapper').height(screenHeight)
I believe what you are looking for is scrollHeight
The scrollHeight property returns the entire height of an element in
pixels, including padding, but not the border, scrollbar or margin.
You can try this:
document.body.scrollHeight
Solution 1:
I don't have an answer using jQuery. But using a plain/vanilla JavaScript wouldn't cause any issue :).
Following script allows you to detect the Viewport size (height and width) reliably.
https://github.com/tysonmatanich/viewportSize
Sample usage:
<script type="text/javascript">
var width = viewportSize.getWidth();
var height = viewportSize.getHeight();
</script>
I have used it in couple of projects, were i have to re-initialize some widgets based on current Viewport width/height rather than using window width/height (Window width/height calculation isn't consistent in all browsers - some include scroll bar size 16px as a part of window width and some doesn't).
Sample Test page:
http://tysonmatanich.github.io/viewportSize/
Solution 2: (Just for reference - Not an answer to OP's question, though it is related so I thought that it can remain)
Well modernizr has a very good addition Modernizr.Mq. Through which you can cross check which break point range you are in...
if(Modernizr.mq("(min-width:320px)")){
//Do job 1
}
else if (Modernizr.mq("(min-width:768px)")){
//Do job 2
}
or
based on height
Modernizr.mq("(min-height: 800px)")
http://tysonmatanich.github.io/viewportSize/
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.
I am creating a webpage on mobile, which will fit 100% width of the screen.
However, when I created some elements with JavaScript and set the width to window.innerWidth, they would be much wider than the static elements that set width: 100% in CSS. (on iPhone 6(s))
The width: 100% sets these elements to 375px, which I think is right, since the screen resolution is 1334 x 750. However the window.innerWidth is 488px, for whatever reason I really don't understand.
Is this a bug of the browser I am testing, or I miss something for retina screen?
By the way, I use width:480px;max-width:100% to set the static elements. The view-port meta is like <meta name="viewport" content="width=device-width, initial-scale=1.0">
Pixel ratio and sidebars can cause the innerwidth of window to be different depending on the device. If you need to check window width in javascript so your media queries match up. Use the window.matchmedia function.
JS
if ( window.matchMedia('max-width:800').matches ){
console.log('tablet mode');
}
I am working on a document with the structure like this:
<html>
<head>
<script src="http:http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Title</h1>
<div id="main">
<div id="head">Some text</div>
<div id="content"><canvas id="canvas"></canvas></div>
<div id="foot">Some more text (and a table)</div>
</div>
</body>
</html>
This is, of course, a bit simplified, but shows the real structure of the document.
Now, I want to extend #canvas so that my document is as wide and as high as possible without anything getting out of the viewport (i.e., without getting scroll bars on my document).
CSS-only solutions are not O.K. for at least two reasons:
This is done dynamically, on request. Depending on some other factors, user may chose the content of #canvas to be bigger or smaller than that. What I want is a "Make optimal size" button (I know how to make the button itself -- this is only about determining the sizes).
The canvas element will not end up with the determined size, but slightly changed, to be a multiplier of some parameter, i.e., if height is the maximal allowable height we compute, the canvas will get its height actually set to factor * Math.floor(height / factor).
I have managed to get the proper width using jQuery:
canvas.width = 0;
canvas.height = 0;
var t = $(canvas);
var w = $(window).width() - (t.outerWidth(true) - t.width());
$(canvas).parents().map(function() {
t = $(this);
w -= t.outerWidth(true) - t.width();
});
This simply takes the width of the viewport and chips away borders, paddings and margins of #canvas and all its parents, after setting canvas to size 0x0 (to prevent miscalculations if it is currently to wide and the document already has scrollbars). This works as intended, however, I've been unsuccessful in doing something similar for the height (and making it work and all modern browsers).
Among other things, I have tried using elements' position().top (which seems to behave differently in SeaMonkey, Chrome and Firefox) and I've tried playing with $(window)/$(document)/other elements' height(), innerHeight() and outerHeight(), but none of these worked.
Edit:
Maybe an additional explanation would help. The canvas is a gameboard. Think chess (although its not chess). So, the user can chose to play on a grid of mxn tiles (m,n being integers chosen via jQueryUI spins; each tile is factor wide and high). So, I want to give the user a button which would essentially say "make the board as big as possible without me needing to scroll while playing".
Edit (a possible solution)
This seems to do the trick:
h = window.innerHeight - $(main).position().top - $(main).outerHeight(true);
I've tested it under SeaMonkey (where $(window).height() was not working as expected), Firefox and Chrome. I have no way of testing IE newer than IE8 (where, as I expected, canvas itself doesn't work).