Erkennen Sie die Rotation des Android-Telefons im Browser mit JavaScript

187

Ich weiß, dass Sie in Safari auf einem iPhone die Ausrichtung des Bildschirms und die Änderung der Ausrichtung erkennen können, indem Sie auf das onorientationchangeEreignis warten window.orientationund den Winkel abfragen .

Ist dies im Browser auf Android-Handys möglich?

Um klar zu sein, frage ich, ob die Rotation eines Android-Geräts durch JavaScript erkannt werden kann, das auf einer Standardwebseite ausgeführt wird. Es ist auf einem iPhone möglich, und ich habe mich gefragt, ob dies für Android-Telefone möglich ist.

Philnash
quelle

Antworten:

214

Um eine Orientierungsänderung in einem Android-Browser zu erkennen, hängen Sie einen Listener an das Ereignis orientationchangeoder resizean 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);

Überprüfen Sie die window.orientationEigenschaft, um herauszufinden, in welche Richtung das Gerät ausgerichtet ist. Mit Android-Handys screen.widthoder screen.heightauch Updates, wenn das Gerät gedreht wird. (Dies ist beim iPhone nicht der Fall).

jb.
quelle
funktioniert das wirklich Ich habe versucht, jquery $ (Fenster) .bind ("Orientierungswechsel", fn); aber es hat nicht funktioniert, muss ich das obige Formular verwenden? Ich habe versucht, "onorientationchange" im Fenster, es wiederholt falsch
Ayyash
Es funktioniert gut. Ayyash - der ganze Punkt hier, dass, wenn "Orientierungsänderung" nicht unterstützt wird, es auf "Größe ändern" zurückgreifen wird
Dror
9
Auf dem Droiden ist das völlig verrückt. Es warnt die Bildschirmbreite von 320, wenn das Telefon im Querformat gedreht wird, und erkennt die Bildschirmbreite 569, wenn das Telefon im Hochformat gedreht wird! Woher??
IgorGanapolsky
1
Nur zur Klarstellung: Wer nach einer Lösung sucht, die auch unter iOS funktioniert, sollte sich die Zwei-Bit-Narren oder meine Antwort ansehen.
mklement0
3
Für iOS ist kein Zwei-Bit-Narren-Hack erforderlich. Verwenden Sie einfach screen.width und screen.height unter Android und iOS. Verwenden Sie window.innerWidth und window.innerHeight.
Justin
224

Das tatsächliche Verhalten zwischen verschiedenen Geräten ist inkonsistent . Die Ereignisse "Größe ändern" und "Ausrichtung ändern" können in einer anderen Reihenfolge mit unterschiedlicher Häufigkeit ausgelöst werden. Außerdem ändern sich einige Werte (z. B. screen.width und window.orientation) nicht immer, wenn Sie dies erwarten. Vermeiden Sie screen.width - es ändert sich nicht, wenn Sie in iOS drehen.

Der zuverlässige Ansatz besteht darin, sowohl Größenänderungs- als auch Orientierungsänderungsereignisse abzuhören (mit einigen Abfragen als Sicherheitsmaßnahme), und Sie erhalten schließlich einen gültigen Wert für die Ausrichtung. Bei meinen Tests können Android-Geräte gelegentlich keine Ereignisse auslösen, wenn sie um volle 180 Grad gedreht werden. Daher habe ich auch ein setInterval eingefügt, um die Ausrichtung abzufragen.

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

Hier sind die Ergebnisse der vier Geräte, die ich getestet habe (Entschuldigung für die ASCII-Tabelle, aber es schien der einfachste Weg zu sein, die Ergebnisse zu präsentieren). Abgesehen von der Konsistenz zwischen den iOS-Geräten gibt es eine große Vielfalt zwischen den Geräten. HINWEIS: Die Ereignisse werden in der Reihenfolge aufgelistet, in der sie ausgelöst wurden.

| ================================================ ============================= |
| Gerät | Ereignisse ausgelöst | Orientierung | innerWidth | screen.width |
| ================================================ ============================= |
| iPad 2 | Größe ändern | 0 | 1024 | 768 |
| (zur Landschaft) | Orientierungswechsel | 90 | 1024 | 768 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPad 2 | Größe ändern | 90 | 768 | 768 |
| (zum Porträt) | Orientierungswechsel | 0 | 768 | 768 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPhone 4 | Größe ändern | 0 | 480 | 320 |
| (zur Landschaft) | Orientierungswechsel | 90 | 480 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| iPhone 4 | Größe ändern | 90 | 320 | 320 |
| (zum Porträt) | Orientierungswechsel | 0 | 320 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Droid Telefon | Orientierungswechsel | 90 | 320 | 320 |
| (zur Landschaft) | Größe ändern | 90 | 569 | 569 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Droid Telefon | Orientierungswechsel | 0 | 569 | 569 |
| (zum Porträt) | Größe ändern | 0 | 320 | 320 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Samsung Galaxy | Orientierungswechsel | 0 | 400 | 400 |
| Tablette | Orientierungswechsel | 90 | 400 | 400 |
| (zur Landschaft) | Orientierungswechsel | 90 | 400 | 400 |
| | Größe ändern | 90 | 683 | 683 |
| | Orientierungswechsel | 90 | 683 | 683 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
| Samsung Galaxy | Orientierungswechsel | 90 | 683 | 683 |
| Tablette | Orientierungswechsel | 0 | 683 | 683 |
| (zum Porträt) | Orientierungswechsel | 0 | 683 | 683 |
| | Größe ändern | 0 | 400 | 400 |
| | Orientierungswechsel | 0 | 400 | 400 |
| ---------------- + ------------------- + ------------ - + ------------ + -------------- |
Zwei-Bit-Dummkopf
quelle
Wenn Sie im iOS5-Emulator im Querformat aktualisieren und dann drehen, wird dieser Code nicht ausgelöst.
arbeitete
1
Gute Antwort. previousOrientationsollte mit der dann aktuellen Ausrichtung initialisiert werden: var previousOrientation = window.orientation;Wenn Sie 180-Grad-Drehungen ignorieren möchten, dh nicht zwischen der Links- oder Rechtslandschaft und den auf dem Kopf stehenden oder nicht-Varianten unterscheiden müssen, fügen Sie Folgendes hinzu als erste Zeile zu checkOrientation(): if (0 === (previousOrientation + window.orientation) % 180) return;Ohne zusätzliche setTimeoutTricks profitieren Sie jedoch nur unter iOS, wo eine schnelle 180-Grad-Drehung nur ein einziges orientationchange Ereignis erzeugt.
mklement0
Dank @mklement habe ich den Code optimiert, um die vorherige Ausrichtung zu initialisieren.
Zwei-Bit-Narr
Prost auf die tollen Informationen. Dies hat mir den Kopf verdreht, weil Windows Phone 8.1 bei Verwendung von Cordova kein Ereignis zum Ändern der Größe oder zum Ändern der Ausrichtung enthält. Es wurde auf die Verwendung von setInterval sowie auf die Ausfallsicherheit zurückgegriffen.
Perfektion
@ mklement0 Bis heute ist window.orientation auf Windows Phone 8.1 immer undefiniert.
Perfektion
39

Die hervorragende Antwort von Two-Bit-Fool liefert den gesamten Hintergrund, aber lassen Sie mich eine kurze, pragmatische Zusammenfassung des Umgangs mit Orientierungsänderungen unter iOS und Android versuchen :

  • Wenn Sie sich nur für Fensterabmessungen interessieren (das typische Szenario) - und nicht für die spezifische Ausrichtung:
    • Behandle nur das resizeEreignis.
    • In Ihrem Handler, wirkt auf window.innerWidthund window.InnerHeightnur.
    • NICHT verwenden window.orientation- es ist unter iOS nicht aktuell.
  • Wenn Sie sich für die spezifische Ausrichtung interessieren :
    • Behandeln Sie nur das resizeEreignis unter Android und nur das orientationchangeEreignis unter iOS.
    • Handeln Sie in Ihrem Handler auf window.orientation(und window.innerWidthund window.InnerHeight)

Diese Ansätze bieten geringfügige Vorteile gegenüber dem Erinnern an die vorherige Ausrichtung und dem Vergleichen:

  • Der Nur-Dimensionen-Ansatz funktioniert auch bei der Entwicklung in Desktop-Browsern, die ansonsten mobile Geräte simulieren können, z. B. Chrome 23. ( window.orientationist in Desktop-Browsern nicht verfügbar).
  • Es ist keine globale / anonyme Variable auf Funktionsebene auf Dateiebene erforderlich.
mklement0
quelle
Das Problem ist, dass beim Ändern der Größe oder Orientierung Ereignis das window.innerWidth meldet falsche und Droid-Geräte
Albanx
@ Albanx, das ist immer noch ein Problem in Chrom auf iOS: / Safari ist in Ordnung tho
Oldboy
12

Sie können das Fenstergrößenänderungsereignis jederzeit anhören. Wenn in diesem Fall das Fenster größer als breit und breiter als hoch wurde (oder umgekehrt), können Sie ziemlich sicher sein, dass die Ausrichtung des Telefons gerade geändert wurde.

Joel Mueller
quelle
Das ist eine gute Idee, ich werde es versuchen (und meinen Freund mit dem Android-Handy bitten, zu testen!)
Philnash
Ich habe gerade festgestellt, dass diese Methode mir nicht die Ausrichtung des Telefons gibt. Ich werde wissen, ob es sich um ein Hoch- oder Querformat handelt, aber nicht, ob es auf dem Kopf steht oder nach links oder rechts gedreht wurde. Irgendwelche weiteren Ideen?
Philnash
Ich bin mir nicht sicher, wie es möglicherweise wichtig sein könnte ... Warum müssen Sie wissen, ob das Telefon auf dem Kopf steht? Der Browser des Telefons hat eine Oberseite, und die Webseite wird an der Oberseite des Browsers ausgerichtet. Jeder Benutzer mit zwei Gehirnzellen zum Aneinanderreiben, der eine Webseite verkehrt herum betrachtet, dreht sein Telefon nur um, wenn er sie richtig herum sehen möchte
Joel Mueller
1
Das ist ein bisschen hart. Ich bin daran interessiert zu wissen, dass ich je nach Ausrichtung des Bildschirms unterschiedliche Inhalte anzeigen kann. Dies können bis zu 4 verschiedene Seiten sein, wobei der Browser wissen muss, ob er um 0, 90, 180 und 270 Grad gedreht wurde. Dies ist alles in JavaScript auf dem iPhone möglich und deshalb frage ich.
Philnash
Es fällt mir immer noch schwer, mir vorzustellen, was eine Webseite sinnvoll anders machen könnte, wenn das Gerät, auf dem sie gerendert wird, um 270 Grad gedreht wird. Wenn Sie jedoch sagen, dass Sie einen gültigen Anwendungsfall haben, werde ich nicht streiten. In diesem Fall: Es tut mir leid, aber ich habe keine Ahnung, ob der Android-Browser diese Detailstufe bietet.
Joel Mueller
3

Es ist in HTML5 möglich.
Weitere Informationen (und eine Live-Demo) finden Sie hier: http://slides.html5rocks.com/#slide-orientation .

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

Es unterstützt auch Deskop-Browser, gibt jedoch immer den gleichen Wert zurück.

Derek 朕 會 功夫
quelle
4
Dieses Ereignis ist wirklich eher für den Zugriff auf die Bewegungssensoren gedacht, obwohl es vermutlich auch zum Erkennen von Orientierungsänderungen verwendet werden kann.
René
Auf meinem Android Galaxy S2 wird es weder im Aktienbrowser noch im Dolphin Browser unterstützt. Funktioniert aber gut mit mobilem Firefox.
Eduardo
3

Ich hatte das gleiche Problem. Ich verwende Phonegap und Jquery Mobile für Adroid-Geräte. Um die Größe richtig zu ändern, musste ich eine Zeitüberschreitung festlegen:

$(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);
}
Tauanz
quelle
2

Hier ist die Lösung:

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");
            }   
        });
    }
Shishir Arora
quelle
Dies ist die Lösung, die für mich am besten funktioniert hat. Ich weiß, dass sie nicht 100% genau ist, aber Sie können horizontal oder vertikal erkennen, indem Sie Folgendes verwenden: var screenWidth = $ (window) .width (); var screenHeight = $ (Fenster) .height (); if (screenWidth> screenHeight) {doSomething (); }
math0ne
Dieser war die Lösung für mich auf einem beschissenen Android-Tablet. window.onresize, attachevent und addeventlistener sind bei mehreren Ereignissen fehlgeschlagen (Größenänderung, Größenänderung, Orientierungsänderung, Geräteorientierung). Nur Jquery $ (Fenster) .on () hat funktioniert.
Lego
1

Ein weiteres Problem: Einige Android-Tablets (das Motorola Xoom, von dem ich glaube, und ein Low-End-Elonex-Tablet, an dem ich einige Tests durchführe, wahrscheinlich auch andere) haben ihre Beschleunigungsmesser so eingerichtet, dass window.orientation == 0 im LANDSCAPE-Modus und nicht im Hochformat !

James-Geldart
quelle
1

Sie können die Lösung ausprobieren, die mit allen Browsern kompatibel ist.

Das folgende orientationchangeBild zeigt die Kompatibilität: Kompatibilität Daher orientaionchangeverfasse ich eine Polyfüllung, die auf dem @ media-Attribut basiert, um die Dienstprogrammbibliothek für den Orientierungswechsel zu reparieren - Orientierungswechsel-Fix

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

Es ist erwähnenswert, dass ich auf meinem Epic 4G Touch die Webansicht für die Verwendung von WebChromeClient einrichten musste, bevor einer der JavaScript-Android-Aufrufe funktionierte.

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

Browserübergreifend

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

Ein kleiner Beitrag zur Antwort des Zwei-Bit-Narren:

Wie in der Tabelle auf Droidentelefonen beschrieben, wird das Ereignis "Orientierungsänderung" früher als das Ereignis "Größenänderung" ausgelöst, wodurch der nächste Größenänderungsaufruf blockiert wird (aufgrund der if-Anweisung). Die Width-Eigenschaft ist immer noch nicht festgelegt.

Eine Problemumgehung, die möglicherweise nicht perfekt ist, könnte darin bestehen, das Ereignis "Orientierungswechsel" nicht auszulösen. Dies kann archiviert werden, indem die Ereignisbindung "Orientierungsänderung" in die "if" -Anweisung eingeschlossen wird:

if (!navigator.userAgent.match(/android/i))
{
    window.addEventListener("orientationchange", checkOrientation, false);
}

Ich hoffe es hilft

(Tests wurden mit Nexus S durchgeführt)

Alex
quelle