检测设备方向

这是一个实验中的功能
此功能某些浏览器尚在开发中,请参考浏览器兼容性表格以得到在不同浏览器中适合使用的前缀。由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。

有越来越多的基于web的设备能够确定它们的方向; 也就是说,它们可以报告数据以指示基于重力方向的方向改变。特别地,手持设备如手机可以利用这些信息以自动旋转屏幕,保持内容直立,当设备旋转至横屏时(宽度大于高度),提供网页内容的横屏视图。

有两种Javascript事件负责处理设备方向信息。第一种是DeviceOrientationEvent,它会在加速度传感器检测到设备在方向上产生变化时触发。通过处理该事件传来的数据信息,让交互式地响应用户移动设备旋转和仰角变化成为可能。

第二种是DeviceMotionEvent,它会在加速度发生改变时触发。跟DeviceOrientationEvent不同,DeviceMotionEvent监听的是相应方向上加速度的变化。传感器通常都具有监听DeviceMotionEvent的能力,包括笔记本中用于保护移动中的存储设备的传感器。DeviceOrientationEvent事件更多见于移动设备中。

处理方向(orientation)事件

要接收设备方向变化信息,只需要监听deviceorientation事件:

注意:gyronorm.js is a polyfill for normalizing the accelerometer and gyroscope data on mobile devices. This is useful for overcoming some of the differences in device support for device orientation.

window.addEventListener("deviceorientation", handleOrientation, true);

注册完事件监听处理函数后(对应这个例子中的handleOrientation),监听函数会定期地接收到最新的设备方向数据。

方向事件对象中包含四个值:

DeviceOrientationEvent.absolute

DeviceOrientationEvent.alpha

DeviceOrientationEvent.beta

DeviceOrientationEvent.gamma

下面是一个事件处理函数的例子:

function handleOrientation(orientData) {
  var absolute = orientData.absolute;
  var alpha = orientData.alpha;
  var beta = orientData.beta;
  var gamma = orientData.gamma;

  // Do stuff with the new orientation data
}

相关值解释

关于每一个轴的记录值表示的是相对于标准的坐标系,设备在某一个给定轴上的旋转量。Orientation and motion data explained 这篇文章有更详细的描述,下面是对这篇文章的总结。

例子

这个例子会成功运行在支持检测自己方向的设备中的支持deviceorientation 事件的浏览器中。

让我们想象一下有一个球在花园中:

<div class="garden">
  <div class="ball"></div>
</div>

<pre class="output"></pre>

花园只有200px宽(很小对吧),球在中央:

.garden {
  position: relative;
  width : 200px;
  height: 200px;
  border: 5px solid #CCC;
  border-radius: 10px;
}

.ball {
  position: absolute;
  top   : 90px;
  left  : 90px;
  width : 20px;
  height: 20px;
  background: green;
  border-radius: 100%;
}

现在,如果我们移动设备,球将随之移动:

var ball   = document.querySelector('.ball');
var garden = document.querySelector('.garden');
var output = document.querySelector('.output');

var maxX = garden.clientWidth  - ball.clientWidth;
var maxY = garden.clientHeight - ball.clientHeight;

function handleOrientation(event) {
  var x = event.beta;  // In degree in the range [-180,180]
  var y = event.gamma; // In degree in the range [-90,90]

  output.innerHTML  = "beta : " + x + "\n";
  output.innerHTML += "gamma: " + y + "\n";

  // Because we don't want to have the device upside down
  // We constrain the x value to the range [-90,90]
  if (x >  90) { x =  90};
  if (x < -90) { x = -90};

  // To make computation easier we shift the range of 
  // x and y to [0,180]
  x += 90;
  y += 90;

  // 10 is half the size of the ball
  // It center the positioning point to the center of the ball
  ball.style.top  = (maxX*x/180 - 10) + "px";
  ball.style.left = (maxY*y/180 - 10) + "px";
}

window.addEventListener('deviceorientation', handleOrientation);

输出结果:

这里以新窗口打开此示例;因为有些浏览器中的 deviceorientation 事件不支持跨域。

警告: Chrome 和 Firefox 处理角度的机制不同,所以某些轴上的方向是相反的。

处理移动(motion)事件

移动事件的处理跟方向事件是一样的,除了他们有自己的事件名:devicemotion

window.addEventListener("devicemotion", handleMotion, true);

真正不同的是做为参数传递给HandleMotion函数的DeviceMotionEvent对象所包含的信息。

这个对象包含四个属性:

相关值解释

DeviceMotionEvent对象提供给web开发者设备在位置和方向上的改变速度的相关信息。这些变化信息是通过三个轴来体现的。(Orientation and motion data explained有更详细的说明。)

acceleration 和 accelerationIncludingGravity,都包含下面三个轴:

  • x: 西向东
  • y: 南向北
  • z: 垂直地面

对于 rotationRate ,情况有点不同;三个轴的信息对应着以下三种情况:

  • alpha: 设备沿着垂直于屏幕(对于桌面设备则是垂直于键盘)的轴的旋转速率
  • beta: 设备沿着屏幕(对于桌面设备则是键盘)左至右方向的轴的旋转速率(桌面设备相对于键盘)
  • gamma: 设备沿着屏幕(对于桌面设备则是键盘)下至上方向的轴的旋转速率

最后,interval 表示的是从设备获取数据的间隔时间,单位是毫秒。

规范

规范 状态 注释
DeviceOrientation Event Specification Editor's Draft Initial specification.

浏览器兼容性

DeviceMotionEvent

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
DeviceMotionEvent
Experimental
Chrome Full support 11Edge Full support 12Firefox Full support 6IE No support NoOpera Full support 15Safari Full support 5WebView Android Full support ≤37Chrome Android Full support 18Firefox Android Full support 6Opera Android Full support 14Safari iOS Full support 4.2Samsung Internet Android Full support 1.0
DeviceMotionEvent() constructor
ExperimentalNon-standard
Chrome Full support 59Edge Full support ≤79Firefox ? IE No support NoOpera ? Safari ? WebView Android Full support 59Chrome Android Full support 59Firefox Android ? Opera Android ? Safari iOS ? Samsung Internet Android Full support 7.0
acceleration
Experimental
Chrome Full support YesEdge Full support 12Firefox Full support 6IE No support NoOpera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 6Opera Android ? Safari iOS Full support 4.2Samsung Internet Android Full support Yes
accelerationIncludingGravity
Experimental
Chrome Full support YesEdge Full support 12Firefox Full support 6IE No support NoOpera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 6Opera Android Full support YesSafari iOS Full support 4.2Samsung Internet Android Full support Yes
interval
Experimental
Chrome Full support YesEdge Full support 12Firefox Full support 6IE No support NoOpera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 6Opera Android Full support YesSafari iOS Full support 4.2Samsung Internet Android Full support Yes
rotationRate
Experimental
Chrome Full support YesEdge Full support 12Firefox Full support 6IE No support NoOpera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 6Opera Android Full support YesSafari iOS Full support 4.2Samsung Internet Android Full support Yes

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
Experimental. Expect behavior to change in the future.
Experimental. Expect behavior to change in the future.
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.

DeviceOrientationEvent

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
DeviceOrientationEvent
Experimental
Chrome Full support 7
Notes
Full support 7
Notes
Notes Before version 50, Chrome provided absolute values instead of relative values for this event. Developers still needing absolute values may use the ondeviceorientationabsolute event.
Edge Full support 12Firefox Full support 6
Notes
Full support 6
Notes
Notes Firefox 3.6, 4, and 5 supported mozOrientation instead of the standard DeviceOrientationEvent interface.
IE No support NoOpera Full support 15Safari Full support 5WebView Android Full support ≤37
Notes
Full support ≤37
Notes
Notes Before version 50, Chrome provided absolute values instead of relative values for this event. Developers still needing absolute values may use the ondeviceorientationabsolute event.
Chrome Android Full support 18
Notes
Full support 18
Notes
Notes Before version 50, Chrome provided absolute values instead of relative values for this event. Developers still needing absolute values may use the ondeviceorientationabsolute event.
Firefox Android Full support 6
Notes
Full support 6
Notes
Notes Firefox 3.6, 4, and 5 supported mozOrientation instead of the standard DeviceOrientationEvent interface.
Opera Android Full support 14Safari iOS Full support 4.2Samsung Internet Android Full support 1.0
Notes
Full support 1.0
Notes
Notes Before Samsung Internet 5.0, Samsung Internet provided absolute values instead of relative values for this event. Developers still needing absolute values may use the ondeviceorientationabsolute event.
DeviceOrientationEvent() constructor
ExperimentalNon-standard
Chrome Full support 59Edge Full support ≤79Firefox ? IE No support NoOpera ? Safari ? WebView Android Full support 59Chrome Android Full support 59Firefox Android ? Opera Android ? Safari iOS ? Samsung Internet Android Full support 7.0
absolute
Experimental
Chrome Full support 7Edge Full support 12Firefox Full support 6IE No support NoOpera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 6Opera Android Full support YesSafari iOS Full support 4.2Samsung Internet Android Full support Yes
alpha
Experimental
Chrome Full support 7Edge Full support 12Firefox Full support 6IE No support NoOpera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 6Opera Android Full support YesSafari iOS Full support 4.2Samsung Internet Android Full support Yes
beta
Experimental
Chrome Full support 7Edge Full support 12Firefox Full support 6IE No support NoOpera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 6Opera Android Full support YesSafari iOS Full support 4.2Samsung Internet Android Full support Yes
gamma
Experimental
Chrome Full support 7Edge Full support 12Firefox Full support 6IE No support NoOpera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 6Opera Android Full support YesSafari iOS Full support 4.2Samsung Internet Android Full support Yes

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
Experimental. Expect behavior to change in the future.
Experimental. Expect behavior to change in the future.
Non-standard. Expect poor cross-browser support.
Non-standard. Expect poor cross-browser support.
See implementation notes.
See implementation notes.

参见