Markus: JS Browserweiche analog zu CSS Browserweiche

Hallo,

zur Darstellung von Menüs habe ich einen Workaround ähnlich wie in

http://de.selfhtml.org/css/layouts/fixbereiche.htm#fixiert_ie

beschrieben benutzt, d.h. ein bestimmter Stylesheetbereich mit Sonderregeln ist mit <!--[if lt IE 7]><![endif]--> eingebunden worden.

Aufgrund von ein paar individuellen Anpassungen an dem Verfahren hat sich ergeben, daß ich etwas in Javascript speziell für die Browser mit diesem Workaround anpassen muß. Nun grübele ich, wie ich dafür die Abfrage geregelt kriege. Ich habe ein bißchen im Forum gesucht und werde nicht recht schlau draus.

  1. Ist die Abfrage der Javascript-Eigenschaften "navigator.appName" und "navigator.appVersion" in jedem Falle zuverlässig genug? In dem Fall, wie würde die beste Abfrage aussehen: navigator.appName = "Microsoft Internet Explorer" und navigator.appVersion < "7" bzw. noch irgendwie mit dem "appVersion"-String zeichenkettenverarbeitend zurechtgemurkst?

  2. Ich könnte die Conditional Comments einsetzen, um einen spezielle Javascript-Funktion einzubinden. Leider kann man offenbar nicht abfragen, ob eine (selbstdefinierte) Funktion existiert - in anderen Browsern würde es dann also zu einem Fehler kommen. Um das zu vermeiden - müsste ich die Funktion innerhalb eines Objektes packen, da man die Existenz eines Objektes offenbar abfragen kann?
    Die andere Möglichkeit wäre, die Funktion erst für alle Browser zu definieren und die Funktionsdefinition dann durch die Funktion für den Explorer überschreiben. Ich vermute mal, das geht nicht, oder?

Vielen Dank im voraus,
Markus

  1. Hallo Markus.

    Aufgrund von ein paar individuellen Anpassungen an dem Verfahren hat sich ergeben, daß ich etwas in Javascript speziell für die Browser mit diesem Workaround anpassen muß.

    Inwiefern?

    1. Ist die Abfrage der Javascript-Eigenschaften "navigator.appName" und "navigator.appVersion" in jedem Falle zuverlässig genug?

    Nein, in keinem Falle.

    1. Ich könnte die Conditional Comments einsetzen, um einen spezielle Javascript-Funktion einzubinden. Leider kann man offenbar nicht abfragen, ob eine (selbstdefinierte) Funktion existiert

    Warum sollte man das nicht können?

    function foobar() {  
      alert('Foo!');  
    }  
      
    alert(typeof(foobar));
    

    Anm.: allgemein (=im globalen Scope) deklarierte Funktionen werden als Funktions-Eigenschaft dem http://de.selfhtml.org/javascript/objekte/window.htm@title=window-Objekt zugeordnet. Dieses kann bei der Verwendung und Abfrage der deklarieren Funktion weggelassen werden.
    So ist z. B. folgendes deckungsgleich:

    window.alert('Bar.');  
    alert('Bar.');
    

    müsste ich die Funktion innerhalb eines Objektes packen, da man die Existenz eines Objektes offenbar abfragen kann?

    Du kannst in JS *jedes* Objekt und *jede* Eigenschaft abfragen.

    Allgemein: vergiss jegliche Browserweiche und konzentriere dich nur auf Fähigkeitenweichen.
    Dich interessiert nicht, welchen Browser ein Surfer nutzt, sondern was dieser kann.

    Einen schönen Samstag noch.

    Gruß, Ashura

    --
    sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
    mathbr:del.icio.us/ mathbr:w00t/
    1. Hallo,

      1. Ist die Abfrage der Javascript-Eigenschaften "navigator.appName" und "navigator.appVersion" in jedem Falle zuverlässig genug?

      Nein, in keinem Falle.

      Aha. In welchem Falle sind diese Eigenschaften im IE nicht so gesetzt, wie man gängigerweise erwartet?

      Mathias

      1. Hallo molily.

        1. Ist die Abfrage der Javascript-Eigenschaften "navigator.appName" und "navigator.appVersion" in jedem Falle zuverlässig genug?

        Nein, in keinem Falle.

        Aha. In welchem Falle sind diese Eigenschaften im IE nicht so gesetzt, wie man gängigerweise erwartet?

        In dem Falle, in dem jemand den UA-String in der Registry entsprechend modifziert hat.

        Einen schönen Samstag noch.

        Gruß, Ashura

        --
        sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
        mathbr:del.icio.us/ mathbr:w00t/
        1. Hallo,

          In dem Falle, in dem jemand den UA-String in der Registry entsprechend modifziert hat.

          Dann wäre er vermutlich kein IE Nutzer ;)

          Abgesehen davon empfinde ich dieses dogmatische "in keinem Falle" übertrieben. Offenbar geht es dem OP darum ein Darstellungsproblem mit Hilfe von JS zu beheben. Solange es nicht um Funktionalität geht, würde ich in diesem Falle meinen, dass es eine legitime Methode mit dem Browser-String wäre - wenn auch vielleicht nicht die geschickteste.
          Wenn jemand mutwillig Browser-Fehlverhalten erzwingen möchte, so kann er das immer tun. Ob ihm das nun durch die Veränderung des Browser-Strings gelingt oder durch eine Extension, die wirres Zeug tut ist letztlich egal.

          Ciao

          1. Hallo schneemann,

            In dem Falle, in dem jemand den UA-String in der Registry entsprechend modifziert hat.
            Dann wäre er vermutlich kein IE Nutzer ;)

            dann bin ich als bekennender IE-Nutzer kein IE-Nutzer nach deiner Definition. ;-)
            Tatsächlich: Ich selbst verwende diesen Browser am liebsten, sehe aber nicht ein, dass jeder Server gleich über meine Software Bescheid wissen muss. Der ausschlaggebende Faktor waren schließlich einige MSDN-Seiten, die mit einem IE bei abgeschaltetem ActiveX absolut unbenutzbar werden; wenn man sich aber mit einem geänderten UA als Fremdbrowser ausgibt, bekommt man sauber geschriebene Seiten ohne ActiveX serviert, die dann einwandfrei benutzbar sind.

            Abgesehen davon empfinde ich dieses dogmatische "in keinem Falle" übertrieben.

            ACK. Diese absolutistischen Formulierungen mag ich auch nicht.

            Offenbar geht es dem OP darum ein Darstellungsproblem mit Hilfe von JS zu beheben.

            Das wäre IMHO ein falscher Ansatz. Darstellungsprobleme sollte man nicht mit JS beheben, sondern mit CSS - falls unbedingt nötig, auch CSS-Hacks.

            Schönen Sonntag noch,
             Martin

            --
            You say, it cannot be love if it isn't for ever.
            But let me tell you: Sometimes, a single scene can be more to remember than the whole play.
            1. Hallo,

              In dem Falle, in dem jemand den UA-String in der Registry entsprechend modifziert hat.
              Dann wäre er vermutlich kein IE Nutzer ;)

              dann bin ich als bekennender IE-Nutzer kein IE-Nutzer nach deiner Definition. ;-)

              Ja, ich kann mich erinnern. Daher auch "vermutlich" ;) Ich sehe Dich mit diesen Einstellungen als nicht sehr repräsentativ an.

              Offenbar geht es dem OP darum ein Darstellungsproblem mit Hilfe von JS zu beheben.

              Das wäre IMHO ein falscher Ansatz. Darstellungsprobleme sollte man nicht mit JS beheben, sondern mit CSS - falls unbedingt nötig, auch CSS-Hacks.

              Daher schreibe ich auch in einem Post weiter oben folgenes:
              » Die vielleicht beste Lösung Deines Problems wär aber vermutlich eine Problembeschreibung incl. Code. Vielleicht gibt's ja eine weniger häßliche Lösung.

              Ciao

        2. Hallo Ashura,

          ["navigator.appName" und "navigator.appVersion"]
          Aha. In welchem Falle sind diese Eigenschaften im IE nicht so gesetzt, wie man gängigerweise erwartet?
          In dem Falle, in dem jemand den UA-String in der Registry entsprechend modifziert hat.

          nein, du irrst. Der UA-String lässt sich tatsächlich über Registry-Einträge konfigurieren. Aber die Informationen, die die Javascript-Engine des IE über das navigator-Objekt preisgibt, sind meines Wissens hartcodiert.

          Allerdings kann diese Information über ein Benutzer-Script, das vor der Abfrage aufgerufen wird, beliebig manipuliert werden. Ich habe eben das hier ausprobiert:

          <script type="text/javascript">  
          navigator.appname="I am a generic browser";  
          alert(navigator.appname);  
          </script>
          

          Und mein IE poppte brav ein alert-Fenster mit der Meldung "I am a generic browser" auf.

          So long,
           Martin

          --
          Es gibt Dinge, die sind sooo falsch, dass nicht einmal das Gegenteil stimmt.
          1. Hallo,

            <script type="text/javascript">

            navigator.appname="I am a generic browser";
            alert(navigator.appname);
            </script>

              
            navigator.appName müsste es heißen.  
            Und damit bekomme ich bei der ersten Zeile nur einen JavaScript-Fehler "Falsche Anzahl an Argumenten der ungültige Eigenschaftszuweisung". Die Eigenschaft ist also nicht überschreibbar.  
              
            Mathias
            
            1. Hallo,

              navigator.appName müsste es heißen.

              stimmt, da habe ich mich mit meinem Fehler bei der Groß/Kleinschreibung selbst ins Knie geschossen. ;-)

              Und damit bekomme ich bei der ersten Zeile nur einen JavaScript-Fehler "Falsche Anzahl an Argumenten der ungültige Eigenschaftszuweisung". Die Eigenschaft ist also nicht überschreibbar.

              Richtig. Das habe ich nun mit der korrekten Schreibweise auch gemerkt.

              So long,
               Martin

              --
              Die letzten Worte des Architekten:
              Mir fällt da gerade was ein...
  2. Hallo,

    1. Ist die Abfrage der Javascript-Eigenschaften "navigator.appName" und "navigator.appVersion" in jedem Falle zuverlässig genug? In dem Fall, wie würde die beste Abfrage aussehen: navigator.appName = "Microsoft Internet Explorer" und navigator.appVersion < "7" bzw. noch irgendwie mit dem "appVersion"-String zeichenkettenverarbeitend zurechtgemurkst?

    Nein, aber vielleicht findest du hier etwas Passendes:
    http://www.lipfert-malik.de/webdesign/tutorial/bsp/browser_js_test.html
    Ansonsten für den IE 7 etwas wie:
    if (window.XMLHttpRequest && window.ActiveXObject)

    1. Ich könnte die Conditional Comments einsetzen, um einen spezielle Javascript-Funktion einzubinden. Leider kann man offenbar nicht abfragen, ob eine (selbstdefinierte) Funktion existiert - in anderen Browsern würde es dann also zu einem Fehler kommen. Um das zu vermeiden - müsste ich die Funktion innerhalb eines Objektes packen, da man die Existenz eines Objektes offenbar abfragen kann?

    Das sollte m.E. nur ausnahmsweise passieren, hast du ein Beispiel?

    Die andere Möglichkeit wäre, die Funktion erst für alle Browser zu definieren und die Funktionsdefinition dann durch die Funktion für den Explorer überschreiben. Ich vermute mal, das geht nicht, oder?

    Das sollte prinzipiell doch gehen. So kann getElementById z.B. für die Browser
    Internet Explorer 4 und Netscape 4 erstellt werden.

    Grüsse

    Cyx23

    1. Hallo,

      Ansonsten für den IE 7 etwas wie:
      if (window.XMLHttpRequest && window.ActiveXObject)

      Und vielleicht sicherheitsweise Opera ausschließen (&& !window.opera), denn manche Versionen kennen diese beiden Objekte.

      Mathias

      1. Hallo Mathias,

        Ansonsten für den IE 7 etwas wie:
        if (window.XMLHttpRequest && window.ActiveXObject)

        Und vielleicht sicherheitsweise Opera ausschließen (&& !window.opera), denn manche Versionen kennen diese beiden Objekte.

        Sicher, ggf. der Opera 8, ist in "Browsererkennung durch JavaScript" auch entspr.
        aufgeführt. Dabei würde ich sowas (ActiveXObject) mittlerweile sogar auch
        Mozilla zutrauen, ob nun mit geeigneten Extensions oder sonstwie, und
        window.opera wiederum läßt sich wohl auch von Profis per Script abstellen...

        Vielleicht eignet sich window.navigator.systemLanguage noch als IE-Erkennung
        für den 7er, wird sich ja wohl bald zeigen.

        Und grundsätzlich bleibt es dabei, dass die meisten Browserweichen hinsichtlich
        zukünftiger Browser riskant sind.

        Grüsse

        Cyx23

  3. Hallo,

    das Wesentliche hat Ashura ja schon gesagt.

    Sollte es trotzdem einen Grund geben, den IE bis Version 6 separieren zu müssen, dann setze doch eine entsprechende Variable, bspw. stupidIE auf false und überschreibe den Wert in einem nachfolgenden Conditional Comment.

    Die vielleicht beste Lösung Deines Problems wär aber vermutlich eine Problembeschreibung incl. Code. Vielleicht gibt's ja eine weniger häßliche Lösung.

    Ciao

  4. Hallo,

    beschrieben benutzt, d.h. ein bestimmter Stylesheetbereich mit Sonderregeln ist mit <!--[if lt IE 7]><![endif]--> eingebunden worden.

    Eigentlich ist Ashuras einwurf dass dich die Fähigkeiten und nicht die Versionen des Browsers interessieren, aber es gibt auch Conditional Comments für JavaScript.

    Grüße
    Jeena Paradies

    --
    Zufallsheader Augen- und Serverschonend | Jlog | Gourmetica Mentiri
  5. Hi,

    zur Darstellung von Menüs habe ich einen Workaround ähnlich wie in

    http://de.selfhtml.org/css/layouts/fixbereiche.htm#fixiert_ie

    beschrieben benutzt [...]

    1. Ist die Abfrage der Javascript-Eigenschaften "navigator.appName" und "navigator.appVersion" in jedem Falle zuverlässig genug?

    Wenn Du schonmal in diesem Kapitel bist, dann solltest Du auch mal einen Blick in http://de.selfhtml.org/css/layouts/navigationsleisten.htm#javascript werfen - diese Browserweiche wurde hier zumindest getestet und ist auf jeden Fall sicherer als den UA abzufragen.

    Die von Jeena gefundene Möglichkeit hört sich auch interessant an, aber ich frage mich, ob der IE dies auch bei Deklaration als text/javascript akzeptiert - und andererseits kommt mir in diesem Zusammenhang gerade der Gedanke, ob IE-Workarounds (sprich Javascript ausschließlich für den IE) nicht grundsätzlich über text/JScript machbar wären...

    freundliche Grüße
    Ingo

    1. Hallo,

      Die von Jeena gefundene Möglichkeit hört sich auch interessant an, aber ich frage mich, ob der IE dies auch bei Deklaration als text/javascript akzeptiert

      Ja.

      und andererseits kommt mir in diesem Zusammenhang gerade der Gedanke, ob IE-Workarounds (sprich Javascript ausschließlich für den IE) nicht grundsätzlich über text/JScript machbar wären...

      Zum Beispiel Opera versucht auch, Scripte mit text/jscript zu interpretieren, daher eignet sich der MIME-Typ nicht für eine Browserabfrage.

      http://de.selfhtml.org/dhtml/modelle/anzeige/scriptsprachen.htm

      Mathias

      1. Hi,

        und andererseits kommt mir in diesem Zusammenhang gerade der Gedanke, ob IE-Workarounds (sprich Javascript ausschließlich für den IE) nicht grundsätzlich über text/JScript machbar wären...

        Zum Beispiel Opera versucht auch, Scripte mit text/jscript zu interpretieren, daher eignet sich der MIME-Typ nicht für eine Browserabfrage.

        schade, wäre eine saubere Lösung gewesen. Aber warum nur gibt Opera vor, jscript zu können? Oder unterstützt der das wirklich (zumindest rudimentär)?

        freundliche Grüße
        Ingo

        1. Hallo Ingo,

          Zum Beispiel Opera versucht auch, Scripte mit text/jscript zu interpretieren, daher eignet sich der MIME-Typ nicht für eine Browserabfrage.
          schade, wäre eine saubere Lösung gewesen. Aber warum nur gibt Opera vor, jscript zu können? Oder unterstützt der das wirklich (zumindest rudimentär)?

          Würde mich wundern; ob nun als Quick&Dirty-Fehlertoleranz oder zur
          Code-Ersparnis, Opera übersah und übersieht offenbar einige Attribute
          wie z.B. zu JSS "einfach so".

          Interessant sind hier aber vielleicht wirklich die ja schon von Jeena
          erwähnten Möglichkeiten der conditional compilations, mit denen (wie
          im u.g. Beispiel) die IEs auch unterschieden werden können.

          Grüsse

          Cyx23

          Multiple Internet Explorer / Conditional Compilation JScript Test

  6. Hallo,

    vielen Dank an alle, die beigetragen haben. Auch die erweiterte Diskussion über navigator.appName habe ich mit Interesse verfolgt.:)

    Ashura hat natürlich recht: man kann sowohl Funktionen überschreiben als auch auf Existenz prüfen. Mein Mangel an Erfahrung mit Javascript hat mich einen Fehler machen lassen, als ich dies testete. Nun habe ich es erstmal so realisiert. Den Browser abzufragen, wäre mir auch etwas unsicher.

    Der Satz "man braucht nie den Browser abzufragen, sondern nur die Funktionalität" habe ich vorher schon im Forum gelesen. Fand ich bei mir nicht ganz 100% zutreffend, da die Javascript-Unterscheidung nicht direkt an einer DOM oder Javascriptfunktionalität festgemacht werden konnte, sondern nur daran, ob eben dieses Conditional Command für den CSS-Bereich gegriffen hat. Ich habt natürlich recht, das ist auch eine Browserfunktionalität, aber eben keine in diesem klassischen Sinne, wie mir vorschwebte. Die Browserfunktionalität war eben genau das Conditional Command und ich war unsicher, ob es damit realisiert werden konnte.

    Okay, möglicherweise hätte man alles ganz anders lösen müssen. Ich skizzier kurz, wie es dazu kam: immer noch (wieder) das alte Problem, daß ich einen festen (nichtscrollbaren) Menübereich oben haben will, und darunter einen getrennt scrollbaren Contentbereich (insgesamt also quasi ein Frame-Ersatz). In Firefox klappt das wunderbar, aber der Explorer kanns nicht so richtig, wie wir wissen. Deswegen habe ich den erwähnten Hack angewendet. Aber ich habe das nicht so richtig hinbekommen, wie ich es wollte: der Contentbereich lag zum Teil unter dem Menübereich, was ja auch okay war, wenn man einen entsprechenden Abstand nach oben definiert hat. Aber das hatte auch zur Folge, daß der Scrollbalken des Contentbereiches unter dem Menü weiterging. Und auch einige andere Sachen hauten nicht hin: der Explorer hat zuviel oder zuwenig Scrollbalken gemalt oder der Contentbereich wurde abgeschnitten etc. Ich habe mit der "overflow"- bzw. "overflow-y"-Eigenschaft der einzelnen Bereiche zwischen "visible", "hidden" und "auto" rumprobiert, aber es einfach nicht vernünftig hinbekommen. Ich habe also aufgegeben, in dem Sinne, daß im Firefox etc der Contentbereich tatsächlich getrennt scrollbar bleibt, ich es aber für den Explorer so eingerichtet habe, daß alles zusammen (Menü und Content) scrollbar ist. Deshalb musste ich im Explorer die Koordinaten, die für das Aufklappen eines Untermenüs zuständig sind, um den gescrollten Betrag anpassen, im Firefox hingegen nicht. Die Untermenüs werden mit Javascript aufgeklappt, ja, sicher keine moderne Lösung, nunja.

    Also, wenn es hier Leute gibt, die sagen, daß man *alles* mit CSS so einrichten kann, wie man will, dann stelle ich die Seite mal irgendwo ins Web zum rumprobieren und ausdiskutieren.

    Ich glaube das läuft alles so ein bißchen auf diese Fragestellung hinaus, die ich an CSS immer noch nicht kapiert habe: wie kann ich einen Bereich festlegen, der z.B. an Position 100px, 100px anfängt und so breit und so hoch ist, wie eben nach unten und nach rechts noch Platz auf dem Bildschirm ist? Also ob es quasi einen Ersatz gibt für die hübsche Frame-Funktionalität, mit der man die Bereiche in "200px,*" aufteilt.
    So wie ich es verstanden habe, gibt es dafür keinen direkten Ersatz, da CSS nicht nach so einem bildschirmorientierten Prinzip arbeitet. Aber wie man das dann sonst macht, habe ich immer noch nicht kapiert.

    Vielen Dank soweit,
    Markus