Austin sees the Word, through his iPhone

We see the world. Many of us. Not so Austin Seraphin. He can’t, can’t normally enjoy those millions of colors I often take for granted, can’t enjoy the stunning sight of the rising sun painting the horizon red, can’t usually gaze at the light of the stars or the deep blue of the ocean. He’s description of how he can see the world with the help of he’s iPhone is very moving.

The other night, however, a very amazing thing happened. I downloaded an app called Color ID. It uses the iPhone’s camera, and speaks names of colors. It must use a table, because each color has an identifier made up of 6 hexadecimal digits. This puts the total at 16777216 colors, and I believe it. Some of them have very surreal names, such as Atomic Orange, Cosmic, Hippie Green, Opium, and Black-White. These names in combination with what feels like a rise in serotonin levels makes for a very psychedelic experience.

I have never experienced this before in my life. I can see some light and color, but just in blurs, and objects don’t really have a color, just light sources. When I first tried it at three o’clock in the morning, I couldn’t figure out why it just reported black. After realizing that the screen curtain also disables the camera, I turned it off, but it still have very dark colors. Then I remembered that you actually need light to see, and it probably couldn’t see much at night. I thought about light sources, and my interview I did for Get Lamp. First, I saw one of my beautiful salt lamps in its various shades of orange, another with its pink and rose colors, and the third kind in glowing pink and red.. I felt stunned.

The next day, I went outside. I looked at the sky. I heard colors such as “Horizon,” “Outer Space,” and many shades of blue and gray. I used color queues to find my pumpkin plants, by looking for the green among the brown and stone. I spent ten minutes looking at my pumpkin plants, with their leaves of green and lemon-ginger. I then roamed my yard, and saw a blue flower. I then found the brown shed, and returned to the gray house. My mind felt blown. I watched the sun set, listening to the colors change as the sky darkened. The next night, I had a conversation with Mom about how the sky looked bluer tonight. Since I can see some light and color, I think hearing the color names can help nudge my perception, and enhance my visual experience. Amazing!

Read the whole Articel: My First Week with the iPhone

Bind < Each < Trigger

Ich bin seit einiger Zeit ein grosser Fan von Custom Events. Heute musste ich eine Funktion erweitern, bei der nach allen Elementen mit der Klasse insertmsgafter ein eingefügt wird, in den später eine Nachricht eingeblendet wird. Bisher war der Code für diese Funktions sehr einfach:

$('.insertmsgafter', c).after('<span class="msg">&nbsp;</span>');

Nun aber gab es plötzlich eine neue Grösse der Nachricht und ausserdem musste der Text durch das CMS pflegbar gemacht werden – bisher kam der Text aus einem JavaScript File. Das bedeutet, es ist nicht nur einfach ein mit einer statischen Klasse, je nach dem braucht es eine zusätzliche Klasse für die neue Dimension und eine URL für den Ajax Aufruf.

Der normale Ansatz wäre, alle Elemente mit der $.each() Funktion zu durchlaufen und darin zu entscheiden, welche Klassen gesetzt werden müssen und wo HTML nachgeladen werden muss:

$('.insertmsgafter', c).each(function() {
    var $t = $(this);
    var size = $t.attr('data-msg-size');
    var src = $t.attr('data-msg-src');
    var $msg = $('<span class="msg' + (size ? ' msgSize' + size: '') + '">&nbsp;</span>');
    if (src) {
        $msg.load(src + ' #ajax');
    }
    $t.after($msg);
});

Nun hatte ich folgende Idee: Statt alle Elemente mit $.each() zu durchlaufen, binde ich auf allen einen Custom-Event, welcher prüft ob das data Attribut für die Grösse und eines für die den Ajax Aufruf vorhanden ist. Danach rufe ich die Funktion direkt auf und unbinde sie wieder:

$('.insertmsgafter', c)
.bind('setupMsg.sgc', function() {
    var $t = $(this);
    var size = $t.attr('data-msg-size');
    var src = $t.attr('data-msg-src');
    var $msg = $('<span class="msg' + (size ? ' msgSize' + size: '') + '">&nbsp;</span>');
    if (src) {
        $msg.load(src + ' #ajax');
    }
    $t.after($msg);
})
.trigger('setupMsg.sgc')
.unbind('setupMsg.sgc');

Ich habe vermutet, dass dieses Vorgehen schneller ist als jedes Element mit $.each() zu durchlaufen. Um das zu testen habe ich einen kleinen Test geschrieben welcher auf 1000 Div’s eine Funktion in verschiedenen Varianten ausführt:

Getestet wurde folgende Funktion:

var calc = function() {
    var $msg = $(' ');
    $(this).after($msg);
    $msg.remove();
};

Für den nativen Loop wurde folgende Funktion verwendet:

for (var i = times; i > 0; i--) {
    var $msg = $(' ');
    $divs.eq(i - 1).after($msg);
    $msg.remove();
}

Leider stimmt meine Vermutung nur teilweise. Das Binding ist zwar fast 3 mal schneller als alle Elemente zu durchlaufen, das Aufrufen der Funktion jedoch dauert fast 1.5 mal so lange – rechnet man das Unbinding dazu, dauert es doppelt so lange wie ein einfaches Loopen mit each.

Conclusion:

Das Binden eines Custom-Events ist um einiges schneller als das Durchlaufen aller Elemente mit each – solange die Funktion dann zu einem späteren Zeitpunkt einzeln aufgerufen wird. Um Elemente einmaling aufzubereiten, lohnt sich der Einsatz von Custom-Events aus Performance-Sicht jedoch nicht. Den browser-nativen Loop zu verwenden lohnt sich ebenfalls nicht; Wenn man darin auf ein DOM-Element selektieren muss, dauert es sogar etwas länger.

Ausserdem ganz interessant; Die Ergebnisse in Safari und Firefox sind zwar praktisch identisch, Safari5 ist aber insgesammt etwa 6 mal schneller wie Firefox 3.6.6.

Was sind Eure Ergebnisse in anderen Browsern?

Testsystem:

  • Firefox 3.6.
  • Safari Version 5.0 (6533.16)
  • Mac OS X 10.6.4

Auch Bilder sind “in line”

Inline-Elemente sind für viele Frontend Entwickler mehr oder minder „unbekannte“ Elemente, welche ein Dasein im Schatten des nur allzu bekannten und dominanten Block-Elements führt. Dabei bringen Inline-Elemente eine Reihe von Eigenschaften mit, welche jeder Entwickler kennen sollte – denn ohne sind gewisse Effekte beim Erstellen eines Layouts nicht zu erklären. Das Inlin-Elemente keinen Umbruch erzeugen ist allgemein bekannt. Darüber hinaus, haben Inline-Elemente aber viele weitere Eigenarten. Alle Inline-Elemente folgen einander in einer Linie. Daher werden sie auch «in»line genannt. Genaugenommen sind auch einzelne Buchstaben nichts anderes als eine Aneinanderreihung von Inline-Elementen.

Eine solche „line“ hat eine Höhe – diese wird immer durch die Schriftgrösse bestimmt, ist aber um etwa 15% grösser als die Schriftgrösse. Die Elemente liegen jedoch nicht wie im ersten Moment vielleicht anzunehmen ganz „unten“ oder „oben“ in dieser Linie, sondern ruhen auf einer imaginären Linie dazwischen – ich nenne diese unsichtbare Linie «Basis-Linie»1. Diese Linie dient dazu, dass „überhängende“ Buchstaben wie etwa ein «g» nicht aus der „line“ fallen.

Der Abstand zur Oberkannte der nächsten Line entspricht der CSS Eigenschaft line-height – ebenso ist dies der Abstand zwischen zwei Basis-Linien. Inline-Elemente ruhen grundsätzlich auf dieser Basis-Linie und können den Abstand der Linen selber nicht verändern – selbst wenn das Element höher ist. Dies äussert sich darin, dass man einem solchen Element zwar einen vertikalen Innenabstand2 geben kann – und dieser auch angenommen wird3 – dadurch jedoch der Abstand zur nächsten Linie nicht verändert wird. Ein Rahmen um ein Inline-Element umschliesst jedoch nicht die Linien-Höhe sondern die Höhe der „line“ – also Schriftgrösse plus etwa 15%4.

Auch Bilder sind bekanntlich Inline-Elemente. Sonst könnten wir keine Icons in einer Textzeile platzieren, ohne dass dieses einen Umbruch erzeugt. Wie alle anderen Inline-Elemente folgen auch Bilder den Gesetzen der «Inline-Graviation» – das heisst, sie ruhen auf der imaginären «Basis Linie». In manchen Layouts werden jedoch Bilder verwendet, welche nicht direkt von Text umschlossen wird. Das führt dazu, dass besagte Inline-Eigenschaften schnell vergessen werden können. Ist das Bild von einem Block-Element umschlossen und gibt man diesem Element einen Rand, liegt diese erstaunlicherweise nicht bündig mit der Bild Unterkante. Dies ist natürlich nicht wirklich «erstaunlich» sondern kommt von der etwa 7.5% höherligenden Basis-Linie, auf welcher das Bild ruht.

Diesem Umstand sind wir jedoch nicht hilflos ausgeliefert. Mit der CSS Eigenschaft vertical-align können wir bestimmen, wo ein Element innerhalb der Linie zu liegen kommt. Ob es also auf der unsichtbaren Basis Linie liegt oder nicht, ist beeinflussbar. Der Standard dieser Eigenschaft ist «baseline». Wenn der Rahmen um das Bild also auf der Unterkante anliegend sein soll, darf das Bild nicht mehr auf der «baseline» liegen, sondern muss sich ganz unten in der Line befinden. Folgende Beispiele zeigen ein Bild mit dem Standard-Wert «baseline» und dem Wert «bottom» welcher das Problem löst:

Bild mit vertical-align baseline. Image © 2009 By Chris Gin: http://interfacelift.com/wallpaper_beta/details/1885/half_moon_bay_sunset.html
1 Die 15% welche die Line grösser ist als die Schrift, werden oben & unten um die Buchstaben verteilt.
2 Padding
3 Was durch einen Rahmen sichtbar gemacht werden kann
4 Plus allfälliges Padding