Javascript: “Pull to refresh”

Pull-to-refresh in (mobilen!) Webseiten nachzubauen, ist jetzt keine Raketenwissenschaft, aber doch so viel Aufwand, dass sich ggf. eine Library lohnt. Viele (? einige? apeatling, ember-gestures, …) bauen aber auf hammer auf, und das hat einen Bug (Beispiel, es gibt weitere Tickets) im Zusammenspiel von Panning (also dem “Pull” in “Pull-to-refresh”) und Scrolling. Zusammengefasst: Es geht nur eines von beiden. Mit ein wenig Drumherumgehacke bekommt man das etwas näher zusammengeführt, aber entweder kommt PanEnd dann gar nicht (was das “refresh” schwierig macht), oder bspw. die PanMove-Events kommen nicht zuverlässig (wodurch man den “pull” nicht 1:1 an den Finger des Nutzers hängen kann).

Ein npm-Modul, das nicht auf hammer aufbaut, wäre pulltorefreshjs (getestet mit 0.1.11 und 0.1.13):

In Ember sieht das als Komponente so aus:

Auf dem Handy sollte das so schon funktionieren. Auf dem Desktop hatte ich das Phänomen, dass Hochcrollen immer erst beim zweiten mal funktioniert hat (und auch dann nur, wenn zwischen Versuch 1 und 2 nicht zu viel Zeit lag). Weil: Die Lib immer beim Hochscrollen den Loader anzeigt, wenn man die Funktion shouldPullToRefresh nicht vom default !window.scrollY ummapt, bspw. auf

Hochscrollen geht sonst nur, so lange der Loader angezeigt wird 🙃

Generische npm Module in Ember

Wer, wie ich, die verfilzte komplexe Javascript-Umgebung etwas… “unübersichtlich” findet, und sich fragt, wie zur Hölle man ein nicht-Ember-spezifisches npm-Modul in Ember importiert, dem kann geholfen werden:

Erst Browserify:

dann, voilà:

JS: navigator.language im Chrome

Chrome ist der neue Internet Explorer:

Stellt sich raus: navigator.language ist im Chrome die Sprache des UI, nichtAccept-Language” m(

navigator.languages funktioniert dafür auch im FF und liefert alle akzeptierten Sprachen.

EaselJS: Lift-off und OOP [UPDATE]

Also zuerst mal sollte diese EaselJS-Geschichte nun nicht mehr nur auf der Startseite funktionieren – mea culpa!

Was EaselJS für mich so richtig interessant macht, ist die Tatsache, dass jedes Objekt auf dem Canvas eigenständig bleibt – so wie ich das Canvas-Element verstehe (als eine Art Bitmap/BitmapData), ist das nicht immer so? Dadurch kann man diesem kleinen Ball aus meiner Demo zum Beispiel einen Click-Handler geben, wie soeben geschehen.

Dabei ist mir Folgendes aufgefallen: Wenn ich tatsächlich nach und nach mehrere (ausgefeiltere) Demos bauen will, dann würde es der Übersichtlichkeit dienen, wenn ich diese voneinander separieren könnte. Am Liebsten in ihrem jeweils eigenen Objekt, von denen ich dann jeweils eines instanziiere. Nur: Wie funktioniert objektorientiertes Programmieren in JS? Meine JS-Kenntnisse sind etwas eingerostet, aber hier gibt es eine nette Basic- (!) Einführung.

Das Ergebnis kann man sich im Quellcode ansehen: Alle Variablen, die nur zur (bisher einzigen) Demo gehören, sind in “Klasse” “A” ausgelagert… I like! Nun könnte es eigentlich/vielleicht losgehen.

UPDATE:

Hm, andererseits wäre es auch interessant, “richtiges” OOP zu sehen, z.B. das Beerben von EaselJS’ Klassen. Angenommen, ich möchte ein TicTacToe-Spiel bauen, dann hätte ich Kreuze und Kreise, die beide (mir fällt grad kein besserer Begriff ein) Spielsteine (engl. “Tile”)sind, der wieder meinetwegen ein Shape ist. Wenn ich diese etwas ausgefeiltere Einführung als Ausgangspunkt nehme, sieht das so aus:

Potential für Verbesserung sehe ich hier:

  • Kreis und Kreuz nur je einmal zeichnen und wiederverwenden (siehe Doku zu Shape), statt jedes mal im Konstruktor.
  • DisplayObject.cache() verwenden.

Meinungen?

EaselJS: Kickoff

So ein Blog ist ein tolles Spielzeug. Eigentlich wollte ich nur meine Tweets anzeigen. Dafür brauchte ich ein neues Theme (das alte hatte keine Sidebar^^). Das neue ist schick, aber hat da oben diesen grauen Header, für den ich eigentlich keine Verwendung habe… lange Rede, kurzer Sinn: Ich benutze es jetzt als Canvas für EaselJS, mit dem ich gerade rumspiele.

Mittelfristig möchte ich da random das anzeigen, was bei meinen Spielereien so abfällt. Bis auf weiteres muss es aber eine Abwandlung einer Demo von Mike Chambers tun.

[Firefox] ExternalInterface.call() von außerhalb “der Bühne”

firefox

Man liest von ExternalInterface-Problemen, die darauf basieren, dass von Javascript aus AS-Funktionen aufgerufen werden, bevor das SWF geladen ist – etwa bei onLoad. Als Lösung gilt: “Rufe aus dem SWF heraus eine JS-Funktion auf. Dann (und erst dann) weiß JS, dass das SWF bereit ist.”

So weit, so gut.

Was man dazu wissen muss, und was man deutlich weniger schnell findet im Netz: Ein SWF, das außerhalb des sichtbaren Bereiches liegt (etwa bei “position: absolute; top: -10px; left: -10px;”), ruft im Firefox 3/Windows keine ExternalInterface-Funktion auf. Gar keine, nie. Obwohl ExternalInterface.available true ist, und obwohl das SWF eigentlich angezeigt wird.

HTH.