twb: Arrays in Mac-kompatiblen Webseiten

Liebe Cracks: Ich habe eine DHTML-Version des chinesischen Brettspiels Mahjongg im Netz stehen (http://www.thomasweibel.ch), das unter Windows-Browsern wie MSIE 5.x, 6.x, und Mozilla 0.6x und 1.0 gut läuft. Für alle komplexeren Funktionen (unlimitierte Zugrücknahme, Zugzähler, Zuganzeige, Spiel wiederholen) benötige ich Arrays, die ich auf- und wieder abbaue. Dabei stosse ich auf ein Problem bei der Kompatibilität mit Macintosh-Browsern: Offensichtlich unterstützt MSIE 5.x für Mac die Befehle

MeinArray.push();
MeinArray.shift();
MeinArray.pop();

nicht, was ich einigermassen skandalös finde. Um Mac-Fans nicht allzu sehr zu brüskieren, habe ich mittels brutaler Browserweiche die Macs auf die unmittelbarsten Spielfunktionen setzen müssen (nur der Button "Neues Spiel"); die genannten Funktionen erscheinen nur auf Nicht-Mac-Systemen - eine mehr als nur unelegante Lösung. Meine Frage: Gibt's taugliche und, da ich auf knappen Code achte, kurze Alternativen für push, shift, pop? Ein Riesendank für entscheidende Tipps! twb

  1. Liebe Cracks: Ich habe eine DHTML-Version des chinesischen Brettspiels Mahjongg im Netz stehen (http://www.thomasweibel.ch), das unter Windows-Browsern wie MSIE 5.x, 6.x, und Mozilla 0.6x und 1.0 gut läuft. Für alle komplexeren Funktionen (unlimitierte Zugrücknahme, Zugzähler, Zuganzeige, Spiel wiederholen) benötige ich Arrays, die ich auf- und wieder abbaue. Dabei stosse ich auf ein Problem bei der Kompatibilität mit Macintosh-Browsern: Offensichtlich unterstützt MSIE 5.x für Mac die Befehle

    MeinArray.push();
    MeinArray.shift();
    MeinArray.pop();

    nicht, was ich einigermassen skandalös finde. Um Mac-Fans nicht allzu sehr zu brüskieren, habe ich mittels brutaler Browserweiche die Macs auf die unmittelbarsten Spielfunktionen setzen müssen (nur der Button "Neues Spiel"); die genannten Funktionen erscheinen nur auf Nicht-Mac-Systemen - eine mehr als nur unelegante Lösung. Meine Frage: Gibt's taugliche und, da ich auf knappen Code achte, kurze Alternativen für push, shift, pop? Ein Riesendank für entscheidende Tipps! twb

    Hallo Crack,

    hier mein Vorschlag:
    Rufe beim Macintosh jedesmal, wenn Du mit MeinArray=new Array() ein neues Array erzeugst, die folgende Funktion MacArray(MeinArray) auf, dann sollte es gehen.

    function MacArray(obj)
    { obj.push=mac_push;
      obj.shift=mac_shift;
      obj.pop=mac_pop;
    }
    function mac_push(vv)
    { var ll=this.length;
      this[ll]=vv;
      return(ll+1);
    }
    function mac_shift()
    { var ii, vv=this[0];
      for (ii=1; ii<this.length; ii++)
      this[ii-1]=this[ii];
      return(vv);
    }
    function mac_pop()
    { var vv, ll=this.length;
      if (ll>0)
      { vv=this[ll-1];
        this.length=ll-1;
      }
    }

    Ich weiß leider nicht, wie man in JS den Constructor new Array() überschreiben kann, oder wie man beispielsweise ein Objekt array definieren kann, welches alle Eigenschaften vom (vordefinierten) Objekt Array erbt, deshalb ist hier der (unästhetische) Funktionsaufruf MacArray() notwendig. Vieleicht weiß ja jemand, wie man das besser machen könnte, das würde mich echt intessieren.

    MfG. Lutz T.

  2. Hi!

    Dabei stosse ich auf ein Problem bei der Kompatibilität mit Macintosh-Browsern: Offensichtlich unterstützt MSIE 5.x für Mac die Befehle
    MeinArray.push();
    MeinArray.shift();
    MeinArray.pop();
    nicht, was ich einigermassen skandalös finde.

    Nicht nur der. Auch gar nicht so alte IE fuer Windows koennen das nicht.

    Meine Frage: Gibt's taugliche und, da ich auf knappen Code achte, kurze Alternativen für push, shift, pop? Ein Riesendank für entscheidende Tipps! twb

    Yupp. Du kannst auch eingebauten Objekten weitere Eigenschaften und Funktionen hinzufuegen. Dazu musst Du z.B. an
      Array.prototype.push
    eine neue Funktion zuweisen, die genau das macht, was push() eben so macht. Du willst das natuerlich nur auf den Mac-Browsern machen. Das sagt man aber besser allgemeiner als: Du willst das nur bei solchen Browsern machen, die push() nicht schon von selber koennen. Dann kannst Du Dir naemlich auch irgendwelche durchgeknallten Browserweichen sparen, die sowieso nicht funktionieren.
    Das ganze sieht dann ungefaehr so aus (ungetestet):

    if (!Array.prototype.push) Array.prototype.push = function () {
          var i;
          for (i=0; i<arguments.length; i++)
              this[this.length] = arguments[i];
          return this.length;
      }

    Jetzt hat garantiert jeder Browser eine Array.push()-Funktion, die Du ganz normal ohne weitere Umstaende benutzen kannst. Das gleiche machst Du jetzt noch fuer die anderen beiden Methoden, und das war's.

    So long

    --
    Wenn alles was Du hast, ein Hammer ist, sieht jedes Problem wie ein Nagel aus!

    [calokey: js javascript object prototype add method Array push pop shift slice splice]

    1. Hallo,

      wofür ist das "prototype" gedacht / notwendig / gut ?

      Grüße
      Michael

      1. Hi!

        wofür ist das "prototype" gedacht / notwendig / gut ?

        Das ist das Kernstueck des ziemlich konfusen Vererbungsmechanismus in JavaScript. Die Erklaerung versteckt sich irgendwo in http://docserv.calocybe.dyndns.org/specs/NetscapeCommunications/JavaScript13ClientGuide/obj2.htm.

        So long

        --
        When a man and a woman marry they become one.
        The trouble starts when they try to decide which one.

    2. Danke, Calocybe und Lutz T.! Diese Antworten haben mir echt weitergeholfen. Allerdings habe ich noch eine dritte Möglichkeit entdeckt, auf die ich ohne Euch nicht gekommen wäre:

      MeinArray[MeinArray.length]="MeinWert"; //statt MeinArray.push();

      for (i=0;i<MeinArray.length-1;i++) //statt MeinArray.shift();
      {MeinArray[i]=MeinArray[i+1];}
      MeinArray.length=MeinArray.length-1;

      MeinArray.length=MeinArray.length-1; //statt MeinArray.pop();

      Das scheint ebenfalls zu funktionieren, und in meinem Game (http://www.thomasweibel.ch/mahjongg.htm) kann ich auf Browserweichen hoffentlich getrost verzichten. Nochmals: Dank! ;-)