Обнаружение вращения телефона Android в браузере с помощью JavaScript
Я знаю, что в Safari на iPhone вы можете обнаружить ориентацию экрана и изменение ориентации, прослушивая onorientationchange
событие и запрос window.orientation
для угла.
Возможно ли это в браузере на телефонах Android?
Чтобы было ясно, я спрашиваю, можно ли обнаружить вращение устройства Android с помощью JavaScript, работающего на стандартной веб-странице. Это возможно на iPhone, и мне было интересно, можно ли это сделать для телефонов Android.
12 ответов
Чтобы обнаружить изменение ориентации в браузере Android, подключите слушателя к orientationchange
или же resize
событие на window
:
// Detect whether device supports orientationchange event, otherwise fall back to
// the resize event.
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
alert('HOLY ROTATING SCREENS BATMAN:' + window.orientation + " " + screen.width);
}, false);
Проверить window.orientation
свойство выяснить, в какую сторону ориентировано устройство. С телефонами Android, screen.width
или же screen.height
также обновляется по мере вращения устройства. (это не относится к iPhone).
Фактическое поведение на разных устройствах противоречиво. События resize и directionChange могут запускаться в различной последовательности с различной частотой. Кроме того, некоторые значения (например, screen.width и window.orientation) не всегда меняются, когда вы ожидаете. Избегайте screen.width - он не меняется при повороте в iOS.
Надежный подход заключается в прослушивании как resize, так и directionChange событий (с некоторым опросом в качестве предохранителя), и вы в конечном итоге получите действительное значение для ориентации. В моем тестировании Android-устройства иногда не запускали события при повороте на 180 градусов, поэтому я также включил setInterval для опроса ориентации.
var previousOrientation = window.orientation;
var checkOrientation = function(){
if(window.orientation !== previousOrientation){
previousOrientation = window.orientation;
// orientation changed, do your magic here
}
};
window.addEventListener("resize", checkOrientation, false);
window.addEventListener("orientationchange", checkOrientation, false);
// (optional) Android doesn't always fire orientationChange on 180 degree turns
setInterval(checkOrientation, 2000);
Вот результаты четырех устройств, которые я тестировал (извините за таблицу ASCII, но, похоже, это самый простой способ представить результаты). Помимо согласованности между устройствами iOS, существует большое разнообразие между устройствами. ПРИМЕЧАНИЕ. События перечислены в порядке их возникновения.
| ================================================= ============================= | | Устройство | События Запущены | ориентация | innerWidth | screen.width | |==============================================================================| | iPad 2 | изменить размер | 0 | 1024 | 768 | | (в ландшафт) | Ориентация | 90 | 1024 | 768 | |----------------+-------------------+-------------+------------+--------------| | iPad 2 | изменить размер | 90 | 768 | 768 | | (к портрету) | Ориентация | 0 | 768 | 768 | |----------------+-------------------+-------------+------------+--------------| | iPhone 4 | изменить размер | 0 | 480 | 320 | | (в ландшафт) | Ориентация | 90 | 480 | 320 | |----------------+-------------------+-------------+------------+--------------| | iPhone 4 | изменить размер | 90 | 320 | 320 | | (к портрету) | Ориентация | 0 | 320 | 320 | |----------------+-------------------+-------------+------------+--------------| | Дроид телефон | Ориентация | 90 | 320 | 320 | | (в ландшафт) | изменить размер | 90 | 569 | 569 | |----------------+-------------------+-------------+------------+--------------| | Дроид телефон | Ориентация | 0 | 569 | 569 | | (к портрету) | изменить размер | 0 | 320 | 320 | |----------------+-------------------+-------------+------------+--------------| | Samsung Galaxy | Ориентация | 0 | 400 | 400 | | Планшет | Ориентация | 90 | 400 | 400 | | (в ландшафт) | Ориентация | 90 | 400 | 400 | | | изменить размер | 90 | 683 | 683 | | | Ориентация | 90 | 683 | 683 | |----------------+-------------------+-------------+------------+--------------| | Samsung Galaxy | Ориентация | 90 | 683 | 683 | | Планшет | Ориентация | 0 | 683 | 683 | | (к портрету) | Ориентация | 0 | 683 | 683 | | | изменить размер | 0 | 400 | 400 | | | Ориентация | 0 | 400 | 400 | |----------------+-------------------+-------------+------------+--------------|
Отличный ответ two-bit-fool обеспечивает весь фон, но позвольте мне попробовать краткое, прагматичное резюме того, как обрабатывать изменения ориентации в iOS и Android:
- Если вам важны только размеры окна (типичный сценарий), а не конкретная ориентация:
- Обрабатывать
resize
только событие - В вашем обработчике действуйте на
window.innerWidth
а такжеwindow.InnerHeight
только. - Не использовать
window.orientation
- это не будет актуальным на iOS.
- Обрабатывать
- Если вы действительно заботитесь о конкретной ориентации:
- Обрабатывать только
resize
событие на Android, и толькоorientationchange
событие на iOS. - В вашем обработчике действуйте на
window.orientation
(а такжеwindow.innerWidth
а такжеwindow.InnerHeight
)
- Обрабатывать только
Эти подходы предлагают небольшие преимущества по сравнению с запоминанием предыдущей ориентации и сравнением:
- Подход, основанный только на размерах, также работает при разработке браузеров для настольных компьютеров, которые могут имитировать мобильные устройства, например Chrome 23. (
window.orientation
недоступно в настольных браузерах). - нет необходимости в глобальной / анонимной переменной уровня файла-функции-оболочки-уровня.
Вы всегда можете прослушать событие изменения размера окна. Если в этом случае окно стало не выше, чем широко, то шире, чем высоко (или наоборот), вы можете быть уверены, что ориентация телефона была только что изменена.
Это возможно в HTML5.
Вы можете прочитать больше (и попробовать демо) здесь: http://slides.html5rocks.com/.
window.addEventListener('deviceorientation', function(event) {
var a = event.alpha;
var b = event.beta;
var g = event.gamma;
}, false);
Он также поддерживает десктопные браузеры, но всегда будет возвращать одно и то же значение.
У меня такая же проблема. Я использую PhoneGap и JQuery для мобильных устройств, для устройств Android. Чтобы правильно изменить размер, я должен был установить таймаут:
$(window).bind('orientationchange',function(e) {
fixOrientation();
});
$(window).bind('resize',function(e) {
fixOrientation();
});
function fixOrientation() {
setTimeout(function() {
var windowWidth = window.innerWidth;
$('div[data-role="page"]').width(windowWidth);
$('div[data-role="header"]').width(windowWidth);
$('div[data-role="content"]').width(windowWidth-30);
$('div[data-role="footer"]').width(windowWidth);
},500);
}
Вот решение:
var isMobile = {
Android: function() {
return /Android/i.test(navigator.userAgent);
},
iOS: function() {
return /iPhone|iPad|iPod/i.test(navigator.userAgent);
}
};
if(isMobile.Android())
{
var previousWidth=$(window).width();
$(window).on({
resize: function(e) {
var YourFunction=(function(){
var screenWidth=$(window).width();
if(previousWidth!=screenWidth)
{
previousWidth=screenWidth;
alert("oreientation changed");
}
})();
}
});
}
else//mainly for ios
{
$(window).on({
orientationchange: function(e) {
alert("orientation changed");
}
});
}
Вы можете попробовать решение, совместимое со всеми браузерами.
Следующий orientationchange
совместимость рис: поэтому я автор orientaionchange
polyfill, он основан на атрибуте @media для исправления библиотеки утилит ориентации—— directionchange -fix
window.addEventListener('orientationchange', function(){
if(window.neworientation.current === 'portrait|landscape'){
// do something……
} else {
// do something……
}
}, false);
Еще одно замечание - на некоторых планшетах Android (я полагаю, Motorola Xoom и бюджетный Elonex, на котором я провожу некоторые испытания, возможно, и на других) установлены акселерометры, так что window.orientation == 0 в режиме LANDSCAPE, а не портрет!
Стоит отметить, что на моем Epic 4G Touch мне пришлось настроить веб-видение для использования WebChromeClient до того, как сработают любые вызовы javascript для Android.
webView.setWebChromeClient(new WebChromeClient());
Кроссбраузерный путь
$(window).on('resize orientationchange webkitfullscreenchange mozfullscreenchange fullscreenchange', function(){
//code here
});
Небольшой вклад в ответ дурачка:
Как описано в таблице на телефонах Droid, событие "directionalchange" запускается раньше, чем событие "resize", таким образом блокируя следующий вызов resize (из-за оператора if). Свойство Width все еще не установлено.
Обходной путь, хотя, возможно, и не идеальный, может заключаться в том, чтобы не запускать событие "directionalchange". Это можно заархивировать, обернув привязку события "directionalchange" в операторе "if":
if (!navigator.userAgent.match(/android/i))
{
window.addEventListener("orientationchange", checkOrientation, false);
}
Надеюсь, поможет
(тесты проводились на Nexus S)