Joe: iOS-Bugfix

Hallo Leute

Leider bin ich absoluter Anfänger in Sachen Javascript...
Eine Versuchswebseite soll für möglichst viele Geräte optimiert werden...
Leider gibt es bei iOS einen Bug, wenn eine zoombare Webseite vom Hoch- ins Querformat gedreht wird wird ein falscher Zoomfaktor verwendet...
Auf Github habe ich folgendes Script gefunden, dass den Zoom beim Drehen ausschaltet und dann wieder einschaltet...

Jedoch verstehe ich das Script nicht ganz...

Kann evtl. jemand Kommentare ergänzen oder mir die folgenden Fragen beantworten...

1. Weshalb steht vor function(w) eine geöffnete Klammer?
2. Ich sehe hier nur Funktionen, aber nirgends einen Aufruf der Funktionen, bzw. eine Übergabe eines Parameters w...
3. Braucht es die Variable ori überhaupt, diese wird nirgends mehr aufgerufen...
4. Was bedeuten Methoden die mit dem Funktionsparameter beginnen wie zum Beispiel " var doc = w.document;"

  
/*! A fix for the iOS orientationchange zoom bug.  
 Script by @scottjehl, rebound by @wilto, modified by Peter Wooster.  
 MIT / GPLv2 License.  
*/  
  
  
(function(w){  
  
        // This fix addresses an Mobile Safari iOS bug, so return early if the UA claims it's something else.  
        var ua = navigator.userAgent;  
        if( !( /iPhone|iPad|iPod/.test( navigator.platform )  
            && /OS [1-5]_[0-9_]* like Mac OS X/i.test(ua)  
            && ua.indexOf( "AppleWebKit" ) > -1  
            && ua.indexOf( "CriOS") == -1  // chrome for iOS doesn't have the bug  
            )){  
                return;  
        }  
  
  
    var doc = w.document;  
  
  
    if( !doc.querySelector ){ return; }  
    var meta = doc.querySelector( "meta[name=viewport]" );  
    if( !meta ){ return; }  
    var initialContent = meta && meta.getAttribute( "content" );  
    var disabledZoom = initialContent + ",maximum-scale=1";  
    var enabledZoom = initialContent + ",maximum-scale=10";  
    var enabled = true;  
    var        x, y, z, aig;  
    function restoreZoom(){  
        meta.setAttribute( "content", enabledZoom );  
        enabled = true;  
    }  
  
  
    function disableZoom(){  
        meta.setAttribute( "content", disabledZoom );  
        enabled = false;  
    }  
  
    function checkTilt( e ){  
        var ori = w.orientation;  
        // if it's landscape we're out of here  
        if(90 == Math.abs(w.orientation)) {  
            if(enabled)restoreZoom();  
            return;  
        }  
  
        aig = e.accelerationIncludingGravity;  
        x = Math.abs( aig.x );  
        y = Math.abs( aig.y );  
  
        // If in the danger zone where x is much greater than y turn off zoom  
        if(y == 0 || (x/y) > 1.2){  
            if(enabled)disableZoom();  
        }else if( !enabled )restoreZoom();  
    }  
  
    w.addEventListener( "orientationchange", restoreZoom, false );  
    w.addEventListener( "devicemotion", checkTilt, false );  
  
  
})( this );  
  

Freundliche Grüsse

  1. @@Joe:

    nuqneH

    Leider gibt es bei iOS einen Bug, wenn eine zoombare Webseite vom Hoch- ins Querformat gedreht wird wird ein falscher Zoomfaktor verwendet...

    IIRC lässt sich der einfach mit CSS beheben:

    html { -webkit-text-size-adjust: 100% }

    Und weg mit dem Script.

    Qapla'

    --
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
    1. @@gunnar

      IIRC lässt sich der einfach mit CSS beheben:

      html { -webkit-text-size-adjust: 100% }

      Meines Wissens behebt dieser css Code nur die grössere Schrift, nicht jedoch denn Zoom der ganzen Site.

      Freundliche Grüsse

      Joe

  2. Hallo,

    1. Weshalb steht vor function(w) eine geöffnete Klammer?
    2. Ich sehe hier nur Funktionen, aber nirgends einen Aufruf der Funktionen, bzw. eine Übergabe eines Parameters w...
    (function() {})();
    

    Das ist der sogenannte sofort ausgeführte Funktionsausdruck (immediately-invoked function expression).

    Hier wird eine Funktion als Ausdruck erzeugt, die nicht unter einer Variable oder Objekteigenschaft gespeichert wird.

    function() {}

    Diese Funktion wird direkt aufgerufen, indem der Aufruf-Operator direkt dahinter gesetzt wird:

    function() {}()

    Beispiel:

    function() {  
      alert('Hallo Welt!');  
    }()
    

    Dieser Ausdruck kann so allerdings nicht alleine (als Statement) stehen, denn er sieht für den Parser nicht wie ein Ausdruck, sondern wie eine Funktionsdeklaration aus. Man verwendet üblicherweise Klammern, um den Parser umzustimmen.

    (function() {  
      alert('Hallo Welt!');  
    })();
    

    Das ist dann syntaktisch korrekts JavaScript-Programm. Es macht nichts anderes, als den Code in der Funktion auszuführen. Die Funktion wird dann weggeworfen und nirgends gespeichert.

    Den ganzen Zirkus veranstaltet man, damit man einen eigenen Variablen-Gültigkeitsbereich (Scope) hat, in dem man zwei schalten und walten kann. Dadurch vermeidet man globale Variablen.

    1. Braucht es die Variable ori überhaupt, diese wird nirgends mehr aufgerufen...

    Jo, sieht so aus.

    1. Was bedeuten Methoden die mit dem Funktionsparameter beginnen wie zum Beispiel " var doc = w.document;"

    Hier wird einfach eine Shortcut-Variable angelegt, um den Zugriff auf w.document zu vereinfachen. Anstatt fünfmal w.document zu notieren und die Objekteigenschaft immer wieder neu abzurufen, wird eine Variable mit dem Wert angelegt. Das verschlankt auch den Code, macht ihn besser lesbar und macht ihn besser komprimierbar.

    Mathias

    1. @@ mathias

      Vielen Dank für die ausführliche Antwort. Einiges ist jetzt klarer.

      Doch ich verstehe immer noch nicht was das w in der klammer der Funktion zu bedeuten hat... Es taucht ja zum beispiel hier wieder auf...

      w.document

      Oder hier...

      w.addeventlistener....

      Was hat w für ein Wert oder was bedeutet es?

      Freundliche Grüsse

      Joe

      1. Hallo,

        (function(w) {  
          alert(w);  
        })(this);
        

        Das Schlüsselwort »this« ist im globalen Kontext ein Verweis auf das globale Objekt window.

        Man hätte auch schreiben können:

        (function(w) {  
          alert(w); // Gibt das window-Objekt aus  
        })(window);
        

        Der sofort ausgeführten Funktion wird also window übergeben. Das ist auch nur ein Shortcut und eine sehr minimale Performance-Optimierung beim Zugriff auf window.

        Mathias

        1. Hallo

          Langsam verstehe ich wie das Skript aufgebaut ist... Vielen Dank an euch alle!
          Ich bin leider nicht ein Fan vom Einbau von Sachen, die ich selber nicht verstehe;-)

          Dann habe ich richtig verstanden, dass man einfach alle w durch window ersetzen könnte und this weglassen könnte?

          Sowie das e bei folgendem Skriptteil ebenfalls durch window ersetzen, da ja window übergeben wird, wenn die Methode aufgerufen wird?

            
          function checkTilt( e ){  
                  var ori = w.orientation;  
                  // if it's landscape we're out of here  
                  if(90 == Math.abs(w.orientation)) {  
                      if(enabled)restoreZoom();  
                      return;  
                  }  
            
                  aig = e.accelerationIncludingGravity;  
                  x = Math.abs( aig.x );  
                  y = Math.abs( aig.y );  
            
          
          

          Grüsse Joe

          1. Hallo!

            Dann habe ich richtig verstanden, dass man einfach alle w durch window ersetzen könnte und this weglassen könnte?

            Ja. Überall dort, wo w auf window zeigt.

            Sowie das e bei folgendem Skriptteil ebenfalls durch window ersetzen, da ja window übergeben wird, wenn die Methode aufgerufen wird?

            Nein, es wird nicht window übergeben.

            function checkTilt( e ){  
              // …  
              aig = e.accelerationIncludingGravity;  
              // …  
            }  
            w.addEventListener( "devicemotion", checkTilt, false );
            

            checkTilt ist also der Event-Handler für das Ereignis devicemotion beim window-Objekt.

            Ein Event-Handler erhält als ersten Parameter das Event-Objekt. Als Parameternamen verwendet man üblicherweise »e«, »ev« oder »event«. Das ist nicht window und du kannst die Verweise auf e nicht einfach durch window ersetzen.

            accelerationIncludingGravity ist also eine Eigenschaft des devicemotion-Event-Objekts.

            Grüße
            Mathias