Detect change in orientation using javascript - javascript

Is it possible to detect change in orientation of the browser on the iPad or Galaxy Tab using javascript? I think it's possible using css media queries.

NOTE: orientationChange is deprecated
Instead use screen.orientation using the screenOrientation interface
var orientation = (screen.orientation || {}).type || screen.mozOrientation || screen.msOrientation;
if (orientation === "landscape-primary") {
console.log("That looks good.");
} else if (orientation === "landscape-secondary") {
console.log("Mmmh... the screen is upside down!");
} else if (orientation === "portrait-secondary" || orientation === "portrait-primary") {
console.log("Mmmh... you should rotate your device to landscape");
} else if (orientation === undefined) {
console.log("The orientation API isn't supported in this browser :(");
}
However note the support as of July 2022
The screen.orientation is not supported by Safari at all
Older answers
The older orientationChange should still work for Safari
window.addEventListener("orientationchange", function() {
alert(window.orientation);
}, false);
MDN:
window.addEventListener("orientationchange", function() {
alert("the orientation of the device is now " + screen.orientation.angle);
});
or jQuery mobile orientationchange
$(window).on("orientationchange", function( event ) {
$("#orientation").text( "This device is in " + event.orientation + " mode!");
});
Older answer
http://www.nczonline.net/blog/2010/04/06/ipad-web-development-tips/
Safari on the iPad does support the window.orientation property, so if necessary, you can use that to determine if the user is in horizontal or vertical mode. As reminder of this functionality:
window.orientation is 0 when being held vertically
window.orientation is 90 when rotated 90 degrees to the left (horizontal)
window.orientation is -90 when rotated 90 degrees to the right (horizontal)
There is also the orientationchange event that fires on the window object when the device is rotated.
You can also use CSS media queries to determine if the iPad is being held in vertical or horizontal orientation, such as:
<link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css">
<link rel="stylesheet" media="all and (orientation:landscape)" href="landscape.css">
http://www.htmlgoodies.com/beyond/webmaster/toolbox/article.php/3889591/Detect-and-Set-the-iPhone--iPads-Viewport-Orientation-Using-JavaScript-CSS-and-Meta-Tags.htm
<script type="text/javascript">
var updateLayout = function() {
if (window.innerWidth != currentWidth) {
currentWidth = window.innerWidth;
var orient = (currentWidth == 320) ? "profile" : "landscape";
document.body.setAttribute("orient", orient);
window.scrollTo(0, 1);
}
};
iPhone.DomLoad(updateLayout);
setInterval(updateLayout, 400);
</script>

You can use mediaMatch to evaluate CSS media queries, e.g.
window
.matchMedia('(orientation: portrait)')
.addListener(function (m) {
if (m.matches) {
// portrait
} else {
// landscape
}
});
CSS media query fires before the orientationchange. If you are looking to capture the end of the event (when the rotation has been completed), see mobile viewport height after orientation change.

In 2022, instead of adding a window orientationchange listener (listener not recommended due to deprecation) you should listen for a screen.orientation change event:
if (screen.orientation) { // Property doesn't exist on screen in IE11
screen.orientation.addEventListener("change", callback);
}
All browsers except IE and Safari now support it. (here is a screenshot of screen from IE11:
... notice that orientation is not a supported attribute of screen in IE11)
The Screen Orientation API is thoroughly documented. The main focus is the ScreenOrientation interface, which extends Screen. Here are 2 screenshots of the orientation attribute of Screen, which shows how the angle changes from 0 (portrait) to 90 (landscape) on an Android device:

You can use the orientationchange event like so:
window.addEventListener('orientationchange', function(event) {
/* update layout per new orientation */
});

I realized that nobody mentioned what happens when the device is held upside-down in this thread.
window.orientation returns -90 or 90 when held horizontal. It returns 0 or 180 when held vertical. Some devices do and some don't support being held upside-down. I recommend,
window.addEventListener("orientationchange", function() {
if ( window.orientation == 0 || window.orientation == 180) {
// WHEN IN PORTRAIT MODE
} else {
// WHEN IN LANDSCAPE MODE
}
}, false);
Also note that window.orientation returns undefined on desktops.

From "Cross-device, cross-browser portrait-landscape detection"
This is about finding out whether a mobile device is in portrait or landscape mode; you don't need to care about its orientation. For all you know, if you hold your iPad upside down, it's in portrait mode.
$(window).bind("resize", function(){
screenOrientation = ($(window).width() > $(window).height())? 90 : 0;
});
90 means landscape, 0 means portrait, cross browser, cross device.
The window.onresize event is available everywhere, and it's always fired at the right time; never too early, never too late. As a matter of fact, the size of the screen is always accurate as well.
The JavaScript version would be this, correct me please if I am wrong.
function getScreenOrientation() {
screenOrientation = window.outerWidth > window.outerHeight ? 90 : 0;
console.log("screenOrientation = " + screenOrientation);
}
window.addEventListener("resize", function(event) {
getScreenOrientation();
});
getScreenOrientation();

window.orientation is what you're looking for. there's also an onOrientationChange event
works for android, iphone and, i'm mostly sure, for ipad

Adding to the #mplungjan answer, I found better results using the webkit "native" (I don't really how to called it) event, 'deviceorientation'.
In the Mozilla Developer network they have a good explanation about how to normalize between webkit and Gecko that helped me to solve this problem.

An easy to use snippet :
function doOnOrientationChange()
{
switch(window.orientation)
{
case -90:
case 90:
// alert('landscape');
$('#portrait').css({display:'none'});
$('#landscape').css({display:'block'});
break;
default:
// alert('portrait');
$('#portrait').css({display:'block'});
$('#landscape').css({display:'none'});
break;
}
}
window.addEventListener('orientationchange', doOnOrientationChange);
// First launch
doOnOrientationChange();

orientationChange is deprecated and also not supported in some browsers,
innerHeight and outerHeight sometimes give inconsistent results in ios
so we can use document.documentElement to check orientation along with resize event
const { clientWidth, clientHeight } = document.documentElement;
if (clientHeight > clientWidth) {
setOrientation("portrait-secondary");
} else {
setOrientation("landscape-primary");
}

As of 2022
Once you get ready like this,
let theDeviceIsRotated;
function handlePortraitOrLandscape() {
setTimeout(afterAnUnnoticableDelay,100); // This solves the wrong-firing-order issue on Samsung Browser.
function afterAnUnnoticableDelay() {
if (screen.orientation) { // Mainly for Android (as of 2022)
// Returns 0 or 90 or 270 or 180
if (screen.orientation.angle == 0) { theDeviceIsRotated="no"; }
if (screen.orientation.angle == 90) { theDeviceIsRotated="toTheLeft"; }
if (screen.orientation.angle == 270) { theDeviceIsRotated="toTheRight"; }
if (screen.orientation.angle == 180) { theDeviceIsRotated="upsideDown"; }
} else { // Mainly for iOS (as of 2022)
// Returns 0 or 90 or -90 or 180
if (window.orientation == 0) { theDeviceIsRotated="no"; }
if (window.orientation == 90) { theDeviceIsRotated="toTheLeft"; }
if (window.orientation == -90) { theDeviceIsRotated="toTheRight"; }
if (window.orientation == 180) { theDeviceIsRotated="upsideDown"; }
}
}
}
handlePortraitOrLandscape(); // Set for the first time
window.addEventListener("resize",handlePortraitOrLandscape); // Update when change happens
you can
if (theDeviceIsRotated == "no") {
// Do your thing
} else if (theDeviceIsRotated == "toTheLeft") {
// Do your thing
} else if (theDeviceIsRotated == "toTheRight") {
// Do your thing
} else if (theDeviceIsRotated == "upsideDown") {
// Do your thing
} else {
// The mysterious 5th orientation nobody has ever seen yet
}
but note that
RESIZE does not fire when switching from 90 to 270 directly (without triggering a portrait view in between)
THEREFORE WE CANNOT RELY ON
window.addEventListener("resize",screenOrientationHasChanged);
AND THERE IS THE EXACT SAME PROBLEM WITH
window.screen.orientation.addEventListener('change',screenOrientationHasChanged);
ALSO WITH
window.addEventListener("orientationchange",screenOrientationHasChanged);
THIS SADLY MEANS THAT AS OF 2022 THERE IS NO RELIABLE WAY TO DETECT SCREEN ORIENTATION CHANGE even by using setInterval
BECAUSE neither screen.orientation.angle nor screen.orientation.type is updated when you go from 90 to 270 without triggering a portrait view in between.
So the following is not any better than resize on mobile devices
if (screen.orientation) {
window.screen.orientation.addEventListener('change',screenOrientationHasChanged); // https://whatwebcando.today/screen-orientation.html
} else {
window.addEventListener("orientationchange",screenOrientationHasChanged); // https://developer.mozilla.org/en-US/docs/Web/API/Window/orientationchange_event
}
You may try to lock the screen orientation to avoid errors but that does not work on iOS as of 2022 and it only works with fullscreen mode on Android.

Related

Hide entire browser toolbar on demand in safari iOS 16 w/ javascript

I'm attempting to produce kind of like a Fullscreen experience while on landscape mode but nothing seems to work so far. I got a video that fakes going fullscreen mode as I have my own controls, unfortunately iOS doesn't support entering fullscreen on nothing except HTML5 <video> tags, so since I'm forced to use Fullscreen API and can't control those native buttons' visibility while on fullscreen state, I need to do something else which is faking it.
I want to produce the same effect as when going to "Aa button" on Search Bar > Hide Toolbar. It collapses everything and shows almost the entire screen space.
I tried going the CSS way or the window.scrollTo(0, 1) trick. Not working in my case as I have a fixed non-scrollable container holding the video and occupying the entire screen.
Also tried with this and many other codepens & jsfiddles on my Safari, none worked.
/*!
Intelligent auto-scrolling to hide the mobile device address bar
Optic Swerve, opticswerve.com
Documented at http://menacingcloud.com/?c=iPhoneAddressBar
*/
var bodyTag;
var executionTime = new Date().getTime(); // JavaScript execution time
// Document ready
//----------------
documentReady(function() {
// Don't hide address bar after a distracting amount of time
var readyTime = new Date().getTime()
if((readyTime - executionTime) < 3000) hideAddressBar(true);
});
// Run specified function when document is ready (HTML5)
//------------------------------------------------------
function documentReady(readyFunction) {
document.addEventListener('DOMContentLoaded', function() {
document.removeEventListener('DOMContentLoaded', arguments.callee, false);
readyFunction();
}, false);
}
// Hide address bar on devices like the iPhone
//---------------------------------------------
function hideAddressBar(bPad) {
// Big screen. Fixed chrome likely.
if(screen.width > 980 || screen.height > 980) return;
// Standalone (full screen webapp) mode
if(window.navigator.standalone === true) return;
// Page zoom or vertical scrollbars
if(window.innerWidth !== document.documentElement.clientWidth) {
// Sometimes one pixel too much. Compensate.
if((window.innerWidth - 1) !== document.documentElement.clientWidth) return;
}
// Pad content if necessary.
if(bPad === true && (document.documentElement.scrollHeight <= document.documentElement.clientHeight)) {
// Extend body height to overflow and cause scrolling
bodyTag = document.getElementsByTagName('body')[0];
// Viewport height at fullscreen
bodyTag.style.height = document.documentElement.clientWidth / screen.width * screen.height + 'px';
}
setTimeout(function() {
// Already scrolled?
if(window.pageYOffset !== 0) return;
// Perform autoscroll
window.scrollTo(0, 1);
// Reset body height and scroll
if(bodyTag !== undefined) bodyTag.style.height = window.innerHeight + 'px';
window.scrollTo(0, 0);
}, 1000);
}
// Quick address bar hide on devices like the iPhone
//---------------------------------------------------
function quickHideAddressBar() {
setTimeout(function() {
if(window.pageYOffset !== 0) return;
window.scrollTo(0, window.pageYOffset + 1);
}, 1000);
}
Any clue on how to produce this "fullscreen landscape" effect on mobile browser (Safari/Chrome) ?

Orientation lock doesn't work on iOS devices [duplicate]

I am trying to get the current screen orientation of iOS however my function which work on chrome dev tool emulator and desktop but it doesn't work on iOS.
Here is my function:
export type ScreenOrientation = "landscape" | "portrait";
export function getScreenOrientation(): ScreenOrientation
{
if (window.screen.availHeight > window.screen.availWidth)
return "portrait";
else
return "landscape";
}
and here is how my program rougthly do to detect the screen orientation change and to use the function:
import { getScreenOrientation } from "../../Utils/getOrientation";
const shoWPortraitModeError = getScreenOrientation() == "landscape" ? false : true;
window.onorientationchange = function () {
const newState = getScreenOrientation() == "landscape" ? false : true;
console.log("window.onorientationchange: ", newState)
shoWPortraitModeError = newState;
};
I tried using window.screen.height and window.screen.width however it didn't worked. Here is the function:
export type ScreenOrientation = "landscape" | "portrait";
export function getScreenOrientation(): ScreenOrientation
{
if (window.screen.availHeight > window.screen.availWidth)
return "portrait";
else
return "landscape";
}
I launch the iOS safari debugger on a mac vm and I noticed that the window.screen value doesn't changes when I turn the screen:
It made me wonder what are the different property I can use to detect the screen orientation on ios ?
After digging around in the intelisense of the dev console of the safari debugger, I found that you can use window.innerHeight and window.innerWidth properties to detect the screen orienation.
Here is how you can use the function:
export type ScreenOrientation = "landscape" | "portrait";
export function getScreenOrientation(): ScreenOrientation
{
if (window.innerHeight > window.innerWidth)
return "portrait";
else
return "landscape";
}
If you want to do some CSS, you can use media queries.
https://developer.mozilla.org/en-US/docs/Web/CSS/#media/orientation
Basically you can use #media (orientation: landscape) {}
If you want it in JS, for other purposes, you can use:
let orientation = (screen.orientation || {}).type || screen.mozOrientation || screen.msOrientation;
if (orientation === "landscape-primary") {
console.log("That looks good.");
} else if (orientation === "landscape-secondary") {
console.log("Mmmh... the screen is upside down!");
} else if (orientation === "portrait-secondary" || orientation === "portrait-primary") {
console.log("Mmmh... you should rotate your device to landscape");
} else if (orientation === undefined) {
console.log("The orientation API isn't supported in this browser :(");
}
Despite being deprecated, this works on iOS 16 Safari (late 2022):
// rotate right
window.orientation // -90
// rotate left
window.orientation // 90
I'm currently (early 2023) using this little line that returns the angle of the orientation which I can interpret myself:
let orientation = (screen.orientation.angle || window.orientation);
A value other than 0 means it is not portrait, and 90 means reverse portrait.

Mobile screen/viewport size detection - Javascript

I want to report the screen size of a mobile device and update on orientation change but am getting all sorts of strange errors e.g. width almost always 980px.
This works fine on desktop when resizing but not mobile (reporting landscape or portrait is fine though)
Tried on ipad, samsung galaxy tab, google nexus phone and iphone 4
Here's what I'm using:
// get dimensions
_getScreenWidth = function() {
var screenWidth = window.innerWidth;
var screenHeight = window.innerHeight;
var el = document.getElementById('dimensions');
_handleOrientation();
el.innerHTML = 'Width: '+screenWidth +' :: Height: '+screenHeight + "<br /><br />" + _doc_element.className;
};
// portait or landscape
_handleOrientation = function() {
if (device.landscape()) {
_removeClass("portrait");
return _addClass("landscape");
} else {
_removeClass("landscape");
return _addClass("portrait");
}
};
// resize event
var resizeTimeout;
window.onresize = function() {
clearTimeout(resizeTimeout);
// handle normal resize
resizeTimeout = setTimeout(function() {
_getScreenWidth();
}, 250); // 250ms delay
}
You will not get width in physical pixels. Instead, you'll receive "CSS pixels". This is why you getting strange errors. For orientation detecting, you can use "CSS pixels", just compare width to height.
I'm not sure what device.landscape() is supposed to be, but the device object doesn't exist, at least not in standard browsers.
all sorts of strange errors
In my case, that was due to undefined _addClass and _removeClass functions, _doc_element object and as mentioned above, device.landscape().
To fix device.landscape(), you can define landscape as a mode where width > height. Then it's just a simple comparison:
isLandscape = function() {
return window.innerWidth > window.innerHeight;
}
Here is example on jsfiddle with all of the errors fixed. Tested on iPhone 6 and it's setting correct classes.

How can I know if a window cannot scroll anymore to the right?

I have a scrolling function over a recursive TimeOut making a very width window scroll horizontally until it reaches the right end, but I need to know in JavaScript if the scrolling has finished to change the direction and scroll back to the origin.
How can I accomplish this?
function ScrollIt(scrollPos, direction) {
if(direction == 'right')
window.scrollBy(scrollPos,0);
else
window.scrollBy(scrollPos,0);
cTimeOut = setTimeout("ScrollIt(1,'right')",10);
}
Of course I call the function in the onload event the first time.
Thanks in advance.
var w = document.documentElement.clientWidth;
var over = document.documentElement.scrollWidth - w;
window.onscroll = function() {
// Detect webkit browser (Chrome, Safari)
if(window.devicePixelRatio) {
if(document.body.scrollLeft==over) { alert("KABOOM (Webkit)") }
}
else {
if(document.documentElement.scrollLeft == over) { alert("CRUNCH") }
}
}
Tested FF 3.6, IE8, Chrome 3.1, Safari 4.0

Catch browser's "zoom" event in JavaScript

Is it possible to detect, using JavaScript, when the user changes the zoom in a page?
I simply want to catch a "zoom" event and respond to it (similar to window.onresize event).
Thanks.
There's no way to actively detect if there's a zoom. I found a good entry here on how you can attempt to implement it.
I’ve found two ways of detecting the
zoom level. One way to detect zoom
level changes relies on the fact that
percentage values are not zoomed. A
percentage value is relative to the
viewport width, and thus unaffected by
page zoom. If you insert two elements,
one with a position in percentages,
and one with the same position in
pixels, they’ll move apart when the
page is zoomed. Find the ratio between
the positions of both elements and
you’ve got the zoom level. See test
case.
http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
You could also do it using the tools of the above post. The problem is you're more or less making educated guesses on whether or not the page has zoomed. This will work better in some browsers than other.
There's no way to tell if the page is zoomed if they load your page while zoomed.
Lets define px_ratio as below:
px ratio = ratio of physical pixel to css px.
if any one zoom The Page, the viewport pxes (px is different from pixel ) reduces and should be fit to The screen so the ratio (physical pixel / CSS_px ) must get bigger.
but in window Resizing, screen size reduces as well as pxes. so the ratio will maintain.
zooming: trigger windows.resize event --> and change px_ratio
but
resizing: trigger windows.resize event --> doesn’t change px_ratio
//for zoom detection
px_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
$(window).resize(function(){isZooming();});
function isZooming(){
var newPx_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
if(newPx_ratio != px_ratio){
px_ratio = newPx_ratio;
console.log("zooming");
return true;
}else{
console.log("just resizing");
return false;
}
}
The key point is difference between CSS PX and Physical Pixel.
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
Good news everyone some people! Newer browsers will trigger a window resize event when the zoom is changed.
I'm using this piece of JavaScript to react to Zoom "events".
It polls the window width.
(As somewhat suggested on this page (which Ian Elliott linked to): http://novemberborn.net/javascript/page-zoom-ff3 [archive])
Tested with Chrome, Firefox 3.6 and Opera, not IE.
Regards, Magnus
var zoomListeners = [];
(function(){
// Poll the pixel width of the window; invoke zoom listeners
// if the width has been changed.
var lastWidth = 0;
function pollZoomFireEvent() {
var widthNow = jQuery(window).width();
if (lastWidth == widthNow) return;
lastWidth = widthNow;
// Length changed, user must have zoomed, invoke listeners.
for (i = zoomListeners.length - 1; i >= 0; --i) {
zoomListeners[i]();
}
}
setInterval(pollZoomFireEvent, 100);
})();
This works for me:
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
It's only needed on IE8. All the other browsers naturally generate a resize event.
There is a nifty plugin built from yonran that can do the detection. Here is his previously answered question on StackOverflow. It works for most of the browsers. Application is as simple as this:
window.onresize = function onresize() {
var r = DetectZoom.ratios();
zoomLevel.innerHTML =
"Zoom level: " + r.zoom +
(r.zoom !== r.devicePxPerCssPx
? "; device to CSS pixel ratio: " + r.devicePxPerCssPx
: "");
}
Demo
Although this is a 9 yr old question, the problem persists!
I have been detecting resize while excluding zoom in a project, so I edited my code to make it work to detect both resize and zoom exclusive from one another. It works most of the time, so if most is good enough for your project, then this should be helpful! It detects zooming 100% of the time in what I've tested so far. The only issue is that if the user gets crazy (ie. spastically resizing the window) or the window lags it may fire as a zoom instead of a window resize.
It works by detecting a change in window.outerWidth or window.outerHeight as window resizing while detecting a change in window.innerWidth or window.innerHeight independent from window resizing as a zoom.
//init object to store window properties
var windowSize = {
w: window.outerWidth,
h: window.outerHeight,
iw: window.innerWidth,
ih: window.innerHeight
};
window.addEventListener("resize", function() {
//if window resizes
if (window.outerWidth !== windowSize.w || window.outerHeight !== windowSize.h) {
windowSize.w = window.outerWidth; // update object with current window properties
windowSize.h = window.outerHeight;
windowSize.iw = window.innerWidth;
windowSize.ih = window.innerHeight;
console.log("you're resizing"); //output
}
//if the window doesn't resize but the content inside does by + or - 5%
else if (window.innerWidth + window.innerWidth * .05 < windowSize.iw ||
window.innerWidth - window.innerWidth * .05 > windowSize.iw) {
console.log("you're zooming")
windowSize.iw = window.innerWidth;
}
}, false);
Note: My solution is like KajMagnus's, but this has worked better for me.
⬤ The resize event works on modern browsers by attaching the event on window, and then reading values of thebody, or other element with for example (.getBoundingClientRect()).
In some earlier browsers it was possible to register resize event
handlers on any HTML element. It is still possible to set onresize
attributes or use addEventListener() to set a handler on any element.
However, resize events are only fired on the window object (i.e.
returned by document.defaultView). Only handlers registered on the
window object will receive resize events.
⚠️ Do resize your tab, or zoom, to trigger this snippet:
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
body.width = window.innerWidth
body.height = window.innerHeight
console.log(body.width +"px x "+ body.height + "px")
}
getSizes()
⬤ An other modern alternative: the ResizeObserver API
Depending your layout, you can watch for resizing on a particular element.
This works well on «responsive» layouts, because the container box get resized when zooming.
function watchBoxchange(e){
info.textContent = e[0].contentBoxSize[0].inlineSize+" x "+e[0].contentBoxSize[0].blockSize + "px"
}
new ResizeObserver(watchBoxchange).observe(fluid)
#fluid {
width: 200px;
height:100px;
overflow: auto;
resize: both;
border: 3px black solid;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 8vh
}
<div id="fluid">
<info id="info"></info>
</div>
💡 Be careful to not overload javascript tasks from user gestures events. Use requestAnimationFrame whenever you needs redraws.
I'd like to suggest an improvement to previous solution with tracking changes to window width. Instead of keeping your own array of event listeners you can use existing javascript event system and trigger your own event upon width change, and bind event handlers to it.
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
Throttle/debounce can help with reducing the rate of calls of your handler.
According to MDN, "matchMedia" is the proper way to do this https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
it's a bit finicky because each instance can only watch one MQ at a time, so if you're interested in any zoom level change you need to make a bunch of matchers.. but since the browser is in charge to emitting the events it's probably still more performant than polling, and you could throttle or debounce the callback or pin it to an animation frame or something - here's an implementation that seems pretty snappy, feel free to swap in _throttle or whatever if you're already depending on that.
Run the code snippet and zoom in and out in your browser, note the updated value in the markup - I only tested this in Firefox! lemme know if you see any issues.
const el = document.querySelector('#dppx')
if ('matchMedia' in window) {
function observeZoom(cb, opts) {
opts = {
// first pass for defaults - range and granularity to capture all the zoom levels in desktop firefox
ceiling: 3,
floor: 0.3,
granularity: 0.05,
...opts
}
const precision = `${opts.granularity}`.split('.')[1].length
let val = opts.floor
const vals = []
while (val <= opts.ceiling) {
vals.push(val)
val = parseFloat((val + opts.granularity).toFixed(precision))
}
// construct a number of mediamatchers and assign CB to all of them
const mqls = vals.map(v => matchMedia(`(min-resolution: ${v}dppx)`))
// poor person's throttle
const throttle = 3
let last = performance.now()
mqls.forEach(mql => mql.addListener(function() {
console.debug(this, arguments)
const now = performance.now()
if (now - last > throttle) {
cb()
last = now
}
}))
}
observeZoom(function() {
el.innerText = window.devicePixelRatio
})
} else {
el.innerText = 'unable to observe zoom level changes, matchMedia is not supported'
}
<div id='dppx'>--</div>
You can also get the text resize events, and the zoom factor by injecting a div containing at least a non-breakable space (possibly, hidden), and regularly checking its height. If the height changes, the text size has changed, (and you know how much - this also fires, incidentally, if the window gets zoomed in full-page mode, and you still will get the correct zoom factor, with the same height / height ratio).
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
On iOS 10 it is possible to add an event listener to the touchmove event and to detect, if the page is zoomed with the current event.
var prevZoomFactorX;
var prevZoomFactorY;
element.addEventListener("touchmove", (ev) => {
let zoomFactorX = document.documentElement.clientWidth / window.innerWidth;
let zoomFactorY = document.documentElement.clientHeight / window.innerHeight;
let pageHasZoom = !(zoomFactorX === 1 && zoomFactorY === 1);
if(pageHasZoom) {
// page is zoomed
if(zoomFactorX !== prevZoomFactorX || zoomFactorY !== prevZoomFactorY) {
// page is zoomed with this event
}
}
prevZoomFactorX = zoomFactorX;
prevZoomFactorY = zoomFactorY;
});
Here is a clean solution:
// polyfill window.devicePixelRatio for IE
if(!window.devicePixelRatio){
Object.defineProperty(window,'devicePixelRatio',{
enumerable: true,
configurable: true,
get:function(){
return screen.deviceXDPI/screen.logicalXDPI;
}
});
}
var oldValue=window.devicePixelRatio;
window.addEventListener('resize',function(e){
var newValue=window.devicePixelRatio;
if(newValue!==oldValue){
// TODO polyfill CustomEvent for IE
var event=new CustomEvent('devicepixelratiochange');
event.oldValue=oldValue;
event.newValue=newValue;
oldValue=newValue;
window.dispatchEvent(event);
}
});
window.addEventListener('devicepixelratiochange',function(e){
console.log('devicePixelRatio changed from '+e.oldValue+' to '+e.newValue);
});
Here is a native way (major frameworks cannot zoom in Chrome, because they dont supports passive event behaviour)
//For Google Chrome
document.addEventListener("mousewheel", event => {
console.log(`wheel`);
if(event.ctrlKey == true)
{
event.preventDefault();
if(event.deltaY > 0) {
console.log('Down');
}else {
console.log('Up');
}
}
}, { passive: false });
// For Mozilla Firefox
document.addEventListener("DOMMouseScroll", event => {
console.log(`wheel`);
if(event.ctrlKey == true)
{
event.preventDefault();
if(event.detail > 0) {
console.log('Down');
}else {
console.log('Up');
}
}
}, { passive: false });
I'am replying to a 3 year old link but I guess here's a more acceptable answer,
Create .css file as,
#media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
EG:-
#media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
The above code makes the size of the font '10px' when the screen is zoomed to approximately 125%. You can check for different zoom level by changing the value of '1000px'.

Categories