24cze Szybkie iteracje czyli przyspieszanie pętli
We wpisie Wydajne tworzenie elementów DOM C.D. pisałem o szybkim sposobie tworzenia elementów DOM w pętli. Zainspirowany częścią prezentacji Nicholasa Zakasa Speed Up Your JavaScript dotyczącą pętli przedstawie sposoby wydajnego iterowania po elementach.
Specyfikacja ecma-262, 3. edycja z grudnia 1999 roku wprowadza cztery rodzaje pętli: for, do-while, while oraz for-in.
Trzy pierwsze pętle służą do iteracji po listach, których klucze są kolejnymi liczbami całkowitymi zaczynając od 0.
For-in natomiast jest stworzony do przebiegania po tablicach asocjacyjnych, których klucze są łańcuchami znakowymi. Konstrukcja:
for (var key in arr) {
arr[key];
}
w zmiennej key zwraca klucz i nie będę jej omawiać ze względu na niską wydajność.
Co jest ważne?
Dwa najważniejsze czynniki wpływające na prędkość pętli do ilość operacji w każdym przebiegu oraz liczba iteracji.
(więcej…)
10cze Ładowanie na żądanie i Google Maps API
Zdarza się, że funkcjonalność, którą udostępniam na stronie jest rozbudowanym modułem JS, ale jednocześnie może nie być w ogóle użyta po załadowaniu strony. Wtedy warto się zastanowić czy ładować kod od razu z całą stroną (co oczywiście wpływa na prędkość ładowania) czy dociągać go dopiero po akcji użytkownika.
Przykładem realizacji wzorca projektowego ładowanie na żądanie, może być dynamiczne ładowanie API Google Map, aby pokazać dany adres na mapie.
W tej chwili Google udostępnia już dynamiczne ładowanie różnych API przy pomocy AJAX API, ale udam, że tego nie ma, gdyż chce pokazać co się dzieje w tle.
Na początek zdefiniuje klasę z konstruktorem init i trzema metodami:
getMap – pobiera API map, loadMap – ładuję mapę i loadPoint – ładuję punkt na mapie.
Jeżeli nie znasz metody bind zapoznaj się z Tu Haczyk IStnieje – ‘this’ cz. I .
W linii 9. konstruktora rejestruję zdarzenie click na grupie linków zawartych w liście o id=”poi”.
var Gmap = {
init: function() {
this.apiKey = 'TWOJ-KLUCZ-G-API';
this.location = '';
this.mapObj = null;
this.mapDiv = $('map');
this.loadMap = this.loadMap.bind(this);
this.loadPoint = this.loadPoint.bind(this);
$$('#poi li > a')
.invoke('observe','click',this.getMap.bind(this));
},
getMap : function(e){
},
loadMap : function() {
},
loadPoint: function(point) {
}
};
document.observe('dom:loaded', Gmap.init.bind(Gmap));
01cze Tu Haczyk IStnieje – this cz. II
W pierwszej części Tu Haczyk IStnieje omówiłem sposób wykorzystania metody bind, tak aby panować nad zawartością this bez względu na kontekst wywołania funkcji.
W drugiej części przyjrzymy się wykorzystaniu this do obsługi zdarzeń oraz metodzie bindAsEventListener, która jest szczególnym przypadkiem bind.
Rozpatrzymy następującą listę trzech elementów oraz kawałek CSSa:
<style>
li {padding: 1em; width: 5em; background-color: darkblue; }
span {color: white; background-color: darkgreen;}
.active {color: red; background-color: yellow; }
</style>
<ul id="list"> <li><span><strong>Stan</strong></span></li> <li><span><em>Kyle</em></span></li> <li><span>Kenny</span></li> </ul>
Przypadek 1.
Standardowy przykład użycia this to zarejestrowanie zdarzenia click na wszystkich elementach listy. Warto zwrócić uwagę na to, że o ile obiekt zdarzenia e w metodzie element zwraca kliknięty element (strong,em, span, li) o tyle w this jest zawsze element listy li.
$$('#list > li').invoke('observe','click',list);
function list(e){
$$('#list > li').invoke('removeClassName','active');
this.addClassName('active');
console.info(this,e.element());
}
/*
<li class="active"> <strong>
<li class="active"> <em>
<li class="active"> <span>
<li class="active"> <li class="active">
*/
Przypadek 2.
W tym przypadku, użyjemy metody bind podobnie jak w poprzedniej części.
Do funkcji list dołączyliśmy nią samą, dlatego wewnątrz list – this wskazuje na list. Niedługo zaprezentuje przykład zastosowania bind na rzeczywistym przykładzie.
$$('#list > li')
.invoke('observe','click',list.bind(list))
function list(e){
console.info(this,e.element());
}
/*
list(e) <li>
list(e) <strong>
list(e) <em>
list(e) <span>
*/
Przypadek 3.
Metoda bindAsEventListener jest rozwinięciem bind i dba o to, żeby obiekt zdarzenia e był zwrócony na pierwszym miejscu, a później dopiero ewentualne parametry tak jak w tym przykładzie Parametr1.
$$('#list > li').invoke('observe','click',
list.bindAsEventListener(list,'Parametr1'))
function list(e,par){
console.info(this,par,e.element());
}
/*
list(e, par) Parametr1 <li>
list(e, par) Parametr1 <strong>
list(e, par) Parametr1 <em>
list(e, par) Parametr1 <span>
*/
Podsumowanie
W ostatnich dwóch wpisach omówiłem this oraz metody bind i bindAsEventListener. Teraz będę mógł przedstawić ich przykładowe zastosowanie w praktyce.
25maj Tu Haczyk IStnieje – ‘this’ cz. I
W językach programowania słowo kluczowe this wskazuje przeważnie w metodzie na obiekt, w którym jest metoda.
W związku z dynamicznym charakterem JS, fraza this przybiera wartości w zależności od kontekstu w jakim metoda jest wykonana i może być zarówno bardzo pomocne jak i przyprawić o nielichy ból głowy.
W pierwszej części “Tu Haczyk IStnieje” omówie jak zapanować nad this przy użyciu metody bind ulubionego frameworka.
Rozpatrzmy następujący obiekt Car1 z atrybutem color i metodą check zwracającą wartość color:
var Car1 = {
color: "Red",
check: function() {
//console.info(this) - wyświetla wartość w konsoli Firebuga w Firefoxie
alert( "Car color is " + this.color );
}
};
Przypadek 1.
Wywołanie metody check działa tak jak byśmy się spodziewali zwracając Red.
// console.info -> Object color=Red // alert -> Car color is Red Car1.check();
Przypadek 2.
W drugim przypadku możemy być już trochę zaskoczeni, ale w metodzie check – this będzie już wskazywać na Car2, a nie na Car1 i zwróci Blue.
var Car2 = {
color: "Blue",
check: Car1.check
};
//Object color=Blue
//Car color is Blue
Car2.check();



