使用 javascript 检测方向变化

发布于 2024-10-29 08:39:56 字数 75 浏览 3 评论 0原文

是否可以使用 JavaScript 检测 iPad 或 Galaxy Tab 上浏览器方向的变化?我认为使用 css 媒体查询是可能的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

琉璃繁缕 2024-11-05 08:39:56

注意: orientationChange 是已弃用

而是使用 screen.orientation 使用 screenOrientation 接口

screenorientation.onchange 事件

window.addEventListener("DOMContentLoaded", () => {
  const output = document.getElementById("o9n");
  const displayOrientation = () => {
    const screenOrientation = screen.orientation.type;
    output.innerHTML = `The orientation of the screen is: ${screenOrientation}`;
    if (screenOrientation === "landscape-primary") {
      console.log("That looks good.");
    } else if (screenOrientation === "landscape-secondary") {
      console.log("Mmmh... the screen is upside down!");
    } else if (screenOrientation === "portrait-secondary" || screenOrientation === "portrait-primary") {
      console.log("Mmmh... you should rotate your device to landscape");
    } else if (screenOrientation === undefined) {
      console.log("The orientation API isn't supported in this browser :(");
    }
  };

  if (screen && screen.orientation !== null) {
    try {
      window.screen.orientation.onchange = displayOrientation;
      displayOrientation();
    }
    catch (e) { output.innerHTML = e.message; }
  }
});
Orientation: <span id="o9n"></span>

但请注意截至 2022 年 7 月的支持

Safari 根本不支持 screen.orientation

在此处输入图像描述


MDN:

window.addEventListener("orientationchange", function() {
    alert("the orientation of the device is now " + screen.orientation.angle);
});

jQuery 移动orientationchange

$(window).on("orientationchange", function( event ) {
  $("#orientation").text( "This device is in " + event.orientation + " mode!");
});

旧的orientationChange和window.orientation应该仍然适用于Safari

window.addEventListener("orientationchange", function() {
  alert(window.orientation);
}, false);

旧的答案

http://www.nczonline.net/blog/2010/04/06/ipad-web-development-tips/

iPad 上的 Safari 确实支持 window.orientation 属性,因此,如果有必要,您可以使用它来确定用户是处于水平模式还是垂直模式。作为此功能的提醒:

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)

当设备旋转时,还有在窗口对象上触发的orientationchange事件。

您还可以使用 CSS 媒体查询来确定 iPad 是处于垂直还是水平方向,例如:

<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>

NOTE: orientationChange is deprecated

Instead use screen.orientation using the screenOrientation interface

which is triggered by the screenorientation.onchange event

window.addEventListener("DOMContentLoaded", () => {
  const output = document.getElementById("o9n");
  const displayOrientation = () => {
    const screenOrientation = screen.orientation.type;
    output.innerHTML = `The orientation of the screen is: ${screenOrientation}`;
    if (screenOrientation === "landscape-primary") {
      console.log("That looks good.");
    } else if (screenOrientation === "landscape-secondary") {
      console.log("Mmmh... the screen is upside down!");
    } else if (screenOrientation === "portrait-secondary" || screenOrientation === "portrait-primary") {
      console.log("Mmmh... you should rotate your device to landscape");
    } else if (screenOrientation === undefined) {
      console.log("The orientation API isn't supported in this browser :(");
    }
  };

  if (screen && screen.orientation !== null) {
    try {
      window.screen.orientation.onchange = displayOrientation;
      displayOrientation();
    }
    catch (e) { output.innerHTML = e.message; }
  }
});
Orientation: <span id="o9n"></span>

However note the support as of July 2022

The screen.orientation is not supported by Safari at all

enter image description here


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!");
});

The older orientationChange and window.orientation should still work for Safari

window.addEventListener("orientationchange", function() {
  alert(window.orientation);
}, false);

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>
ㄖ落Θ余辉 2024-11-05 08:39:56

在 2022 年,不添加窗口orientationchange监听器(不推荐监听器,因为已弃用),您应该侦听 screen.orientation 更改事件:

if (screen.orientation) { // Property doesn't exist on screen in IE11   
    screen.orientation.addEventListener("change", callback);
}

除 IE 和 Safari 之外的所有浏览器现在都支持它。 (这是 IE11 的 screen 屏幕截图:

在此处输入图像描述

...请注意,orientation 不是 screen 在 IE11 中)

屏幕方向 API 已完整记录。主要焦点是 ScreenOrientation 接口,它扩展了 Screen。以下是 Screenorientation 属性的 2 个屏幕截图,其中显示了 angle 在屏幕上如何从 0(纵向)到 90(横向)变化。 Android 设备:

在此处输入图像描述

在此处输入图像描述

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:

enter image description here

... 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:

enter image description here

enter image description here

雨落□心尘 2024-11-05 08:39:56

您可以使用 mediaMatch 来评估 CSS 媒体查询,例如

window
    .matchMedia('(orientation: portrait)')
    .addListener(function (m) {
        if (m.matches) {
            // portrait
        } else {
            // landscape
        }
    });

CSS 媒体查询在 orientationchange 之前触发。如果您希望捕获事件的结束(旋转完成时),请参阅 方向更改后的移动视口高度

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.

深白境迁sunset 2024-11-05 08:39:56

您可以像这样使用orientationchange事件:

window.addEventListener('orientationchange', function(event) {
     /* update layout per new orientation */
});

You can use the orientationchange event like so:

window.addEventListener('orientationchange', function(event) {
     /* update layout per new orientation */
});
兮子 2024-11-05 08:39:56

由于某种原因,没有人提到当该设备在该线程中倒置时会发生什么。
window.orientation 在水平放置时返回 -90 或 90。垂直放置时返回 0 或 180。有些设备支持,有些不支持倒置。因此,推荐的逻辑类似于,

window.addEventListener("orientationchange", function() {
  
  if ( window.orientation == 0 || window.orientation == 180) {
    // WHEN IN PORTRAIT MODE
    
  } else {
    // WHEN IN LANDSCAPE MODE
    
  }
}, false);

另请注意,window.orientation 在桌面上返回 undefined

For some reason, 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 support and some do not support being held upside-down. Therefore, the recommended logic is like,

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.

¢好甜 2024-11-05 08:39:56

来自“跨设备、跨浏览器纵向横向检测

这是关于确定移动设备是处于纵向模式还是横向模式;你不需要关心它的方向。众所周知,如果您将 iPad 倒置,它就会处于纵向模式。

$(window).bind("resize", function(){
    screenOrientation = ($(window).width() > $(window).height())? 90 : 0;
});

90表示横向,0表示纵向,跨浏览器、跨设备。

window.onresize 事件随处可用,并且总是在正确的时间触发;永远不会太早,永远不会太晚。事实上,屏幕的尺寸也总是准确的。

JavaScript 版本是这样的,如果我错了,请纠正我。

  function getScreenOrientation() {
    screenOrientation = window.outerWidth > window.outerHeight ? 90 : 0;
    console.log("screenOrientation = " + screenOrientation);
  }
  window.addEventListener("resize", function(event) {
    getScreenOrientation();
  });
  getScreenOrientation();

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();
笑梦风尘 2024-11-05 08:39:56

orientationChange 已被弃用,并且在某些浏览器中也不支持,
insideHeight 和outerHeight 有时在ios 中给出不一致的结果
所以我们可以使用 document.documentElement 来检查方向以及调整大小事件

const { clientWidth, clientHeight } = document.documentElement;
 
if (clientHeight > clientWidth) {
      setOrientation("portrait-secondary");
    } else {
      setOrientation("landscape-primary");
    }

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");
    }
翻身的咸鱼 2024-11-05 08:39:56

window.orientation 就是您要寻找的。还有一个 onOrientationChange 事件
适用于 Android、iPhone,我确信也适用于 iPad

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

梦回梦里 2024-11-05 08:39:56

添加到@mplungjan答案中,我发现使用webkit“本机”(我真的不知道如何称呼它)事件“deviceorientation”有更好的结果。

Mozilla 开发者网络中,他们对如何在 webkit 和 Gecko 之间进行标准化有很好的解释帮助我解决了这个问题。

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.

情痴 2024-11-05 08:39:56

一个易于使用的片段:

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();

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();
刘备忘录 2024-11-05 08:39:56

创建一个服务来使用 observable 检测方向的变化。

import { Injectable } from '@angular/core';
import { Observable, fromEvent } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Injectable({
 providedIn: 'root'
})
export class OrientationService {
 orientation$: Observable<string>;

 constructor() {
  this.orientation$ = fromEvent(window, 'resize').pipe(
   map(() => this.getOrientation()),
   startWith(this.getOrientation())
 );}

private getOrientation(): string {
 return window.innerWidth > window.innerHeight ? 'Landscape' : 'Portrait';}
}

现在在您的组件中使用此服务来订阅正在检测到的更改

import { Component, OnInit } from '@angular/core';
import { OrientationService } from './orientation.service';

@Component({
 selector: 'app-my-component',
 templateUrl: './my-component.component.html',
 styleUrls: ['./my-component.component.css']
 })
export class MyComponent implements OnInit {
 orientation: string;

 constructor(private orientationService: OrientationService) {}

ngOnInit() {
  this.updateOnOrientationChange();
  }

 updateOnOrientationChange() {
  this.orientationService.orientation$.subscribe(orientation => {
  this.orientation = orientation;
   });

}
}

Create a service to detect the change in orientation using observable.

import { Injectable } from '@angular/core';
import { Observable, fromEvent } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

@Injectable({
 providedIn: 'root'
})
export class OrientationService {
 orientation$: Observable<string>;

 constructor() {
  this.orientation$ = fromEvent(window, 'resize').pipe(
   map(() => this.getOrientation()),
   startWith(this.getOrientation())
 );}

private getOrientation(): string {
 return window.innerWidth > window.innerHeight ? 'Landscape' : 'Portrait';}
}

Now Use this service inside your component to subscribe to the changes being detected

import { Component, OnInit } from '@angular/core';
import { OrientationService } from './orientation.service';

@Component({
 selector: 'app-my-component',
 templateUrl: './my-component.component.html',
 styleUrls: ['./my-component.component.css']
 })
export class MyComponent implements OnInit {
 orientation: string;

 constructor(private orientationService: OrientationService) {}

ngOnInit() {
  this.updateOnOrientationChange();
  }

 updateOnOrientationChange() {
  this.orientationService.orientation$.subscribe(orientation => {
  this.orientation = orientation;
   });

}
}

℉服软 2024-11-05 08:39:56

从 2022 年开始,

一旦您像这样做好准备,

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

您可以

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
}
但请注意,

直接从 90 切换到 270 时,RESIZE 不会触发(不触发中间是肖像视图)

因此我们不能依赖
window.addEventListener("resize",screenOrientationHasChanged);

并且存在完全相同的问题
window.screen.orientation.addEventListener('change',screenOrientationHasChanged);

还带有
window.addEventListener("orientationchange",screenOrientationHasChanged);

这不幸地意味着,截至 2022 年,即使使用 setInterval 也没有可靠的方法来检测屏幕方向变化
因为当您从 90 转到 270 时,screen.orientation.anglescreen.orientation.type 都不会更新之间不会触发纵向视图。

因此,以下内容并不比移动设备上的 resize 更好。

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
}

您可以尝试锁定屏幕方向以避免错误,但这在 2022 年起不适用于 iOS,并且仅适用于 Android 上的全屏模式。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文