web-dev-qa-db-fra.com

Détecter la rotation du téléphone Android dans le navigateur avec JavaScript

Je sais que dans Safari sur un iPhone, vous pouvez détecter l'orientation de l'écran et changer d'orientation en écoutant l'événement onorientationchange et en interrogeant window.orientation pour connaître l'angle.

Est-ce possible dans le navigateur sur Android téléphones?

Pour être clair, je demande si la rotation d'un appareil Android peut être détectée par JavaScript exécuté sur une page Web standard. C'est possible sur un iPhone et je me suis demandé si cela pouvait être fait pour les téléphones Android.

185
philnash

Pour détecter un changement d'orientation sur un navigateur Android, associez un écouteur à l'événement orientationchange ou resize sur 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);

Vérifiez la propriété window.orientation pour déterminer l'orientation du périphérique. Avec Android téléphones, screen.width ou screen.height se met également à jour au fur et à mesure de la rotation du périphérique. (ce n'est pas le cas avec l'iPhone).

212
jb.

Le réel le comportement entre différents périphériques est incohérent. Les événements resize et orientationChange peuvent être déclenchés dans une séquence différente avec une fréquence variable. De plus, certaines valeurs (par exemple, screen.width et window.orientation) ne changent pas toujours lorsque vous vous y attendez. Évitez screen.width - cela ne change pas lors de la rotation dans iOS.

L'approche fiable consiste à écouter à la fois les événements de redimensionnement et d'orientationChange (avec une certaine interrogation comme mesure de sécurité) et vous obtiendrez éventuellement une valeur valide pour l'orientation. Lors de mes tests, il est parfois arrivé que Android ne parvienne pas à déclencher des événements lors d'une rotation à 180 degrés. J'ai donc également inclus un setInterval pour interroger l'orientation.

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

Voici les résultats des quatre périphériques que j'ai testés (désolé pour la table ASCII, mais cela semblait être le moyen le plus simple de présenter les résultats). Outre la cohérence entre les périphériques iOS, il existe une grande variété de périphériques. REMARQUE: les événements sont répertoriés dans l'ordre de leur déclenchement.

 | ========================================== ================================= | 
 | Appareil | Événements tirés | orientation | largeur intérieure | screen.width | 
 | ======================================= ===================================== 
 | iPad 2 | redimensionner | 0 | 1024 | 768 | 
 | (au paysage) | orientationchange | 90 | 1024 | 768 | 
 | ---------------- + ------------------- + ----- -------- + ------------ + -------------- | 
 | iPad 2 | redimensionner | 90 | 768 | 768 | 
 | (au portrait) | orientationchange | 0 | 768 | 768 | 
 | ---------------- + ------------------- + ----- -------- + ------------ + -------------- | 
 | iPhone 4 | redimensionner | 0 | 480 | 320 | 
 | (au paysage) | orientationchange | 90 | 480 | 320 | 
 | ---------------- + ------------------- + ----- -------- + ------------ + -------------- | 
 | iPhone 4 | redimensionner | 90 | 320 | 320 | 
 | (au portrait) | orientationchange | 0 | 320 | 320 | 
 | ---------------- + ------------------- + ----- -------- + ------------ + -------------- | 
 | Téléphone Droid | orientationchange | 90 | 320 | 320 | 
 | (au paysage) | redimensionner | 90 | 569 | 569 | 
 | ---------------- + ------------------- + ----- -------- + ------------ + -------------- | 
 | Téléphone Droid | orientationchange | 0 | 569 | 569 | 
 | (au portrait) | redimensionner | 0 | 320 | 320 | 
 | ---------------- + ------------------- + ----- -------- + ------------ + -------------- | 
 | Samsung Galaxy | orientationchange | 0 | 400 | 400 | 
 | Tablette | orientationchange | 90 | 400 | 400 | 
 | (au paysage) | orientationchange | 90 | 400 | 400 | 
 | | redimensionner | 90 | 683 | 683 | 
 | | orientationchange | 90 | 683 | 683 | 
 | ---------------- + ------------------- + ----- -------- + ------------ + -------------- | 
 | Samsung Galaxy | orientationchange | 90 | 683 | 683 | 
 | Tablette | orientationchange | 0 | 683 | 683 | 
 | (au portrait) | orientationchange | 0 | 683 | 683 | 
 | | redimensionner | 0 | 400 | 400 | 
 | | orientationchange | 0 | 400 | 400 | 
 | ---------------- + ------------------- + ----- -------- + ------------ + -------------- | 
222
two-bit-fool

l'excellente réponse de two-bit-imb fournit tout le contexte, mais laissez-moi tenter un résumé concis et pragmatique sur la façon de gérer les changements d'orientation sur iOS et Android:

  • Si vous ne vous souciez que des dimensions de la fenêtre (scénario typique) - et non de l'orientation spécifique:
    • Traitez l'événement resize uniquement.
    • Dans votre gestionnaire, agissez uniquement sur window.innerWidth et window.InnerHeight.
    • N'utilisez PAS window.orientation - il ne sera pas à jour sur iOS.
  • Si vous vous souciez de l'orientation spécifique :
    • Traite uniquement l'événement resize sur Android et uniquement l'événement orientationchange sur iOS.
    • Dans votre gestionnaire, agissez sur window.orientation (et window.innerWidth et window.InnerHeight)

Ces approches offrent de légers avantages par rapport à l’orientation précédente et à la comparaison:

  • l'approche basée uniquement sur les dimensions fonctionne également lors du développement sur des navigateurs de bureau pouvant simuler des appareils mobiles, par exemple, Chrome 23. (window.orientation n'est pas disponible sur les navigateurs de bureau).
  • pas besoin d'une variable globale/anonyme-fichier-niveau-fonction-encapsuleur.
39
mklement0

Vous pouvez toujours écouter l'événement de redimensionnement de la fenêtre. Si, lors de cet événement, la fenêtre est passée de plus en plus large (ou inversement), vous pouvez être à peu près sûr que l'orientation du téléphone vient d'être modifiée.

12
Joel Mueller

J'ai eu le même problème. J'utilise Phonegap et Jquery mobile pour les appareils Android. Pour redimensionner correctement je devais définir un délai d'attente:

$(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);
}
3
tauanz

C'est possible en HTML5.
Vous pouvez en lire plus (et essayer une démonstration en direct) ici: http://slides.html5rocks.com/#slide-orientation .

window.addEventListener('deviceorientation', function(event) {
    var a = event.alpha;
    var b = event.beta;
    var g = event.gamma;
}, false);

Il prend également en charge les navigateurs de bureau, mais il retournera toujours la même valeur.

3
Derek 朕會功夫

Voici la solution:

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");
            }   
        });
    }
2
Shishir Arora

Un autre piège - certains Android tablettes (le Motorola Xoom, je crois, et le bas de gamme Elonex sur lequel je teste, probablement d'autres aussi) ont leurs accéléromètres configurés pour que window.orientation == 0 en mode PAYSAGE, pas en portrait!

1
james-geldart

vous pouvez essayer la solution, compatible avec tous les navigateurs.

Voici orientationchange image de compatibilité: compatibility je crée donc un orientaionchange polyfill, c’est un attribut basé sur @media qui corrige la bibliothèque d’utilitaires orientationchange —— orientationchange-fix

window.addEventListener('orientationchange', function(){
 if(window.neworientation.current === 'portrait|landscape'){
    // do something……
 } else {
    // do something……
 }
}, false);
1
Zhansingsong

chemin du navigateur

$(window).on('resize orientationchange webkitfullscreenchange mozfullscreenchange fullscreenchange',  function(){
//code here
});
0
comonitos

Il est à noter que sur mon Epic 4G Touch, j'ai dû configurer WebView pour utiliser WebChromeClient avant qu'aucun des appels javascript Android ne fonctionne.

webView.setWebChromeClient(new WebChromeClient());
0
calebisstupid