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 listthis 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.

Share

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 checkthis 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();

Continue reading

Share

Dynamiczne elementy DOM, które tworzą stronę i zmieniają się przy zastosowaniu AJAX’a można tworzyć na wiele sposób. Poniżej przedstawie trzy najczęściej przeze mnie używane i porównam je ze względu na wydajność. Testy zostały przeprowadzone na Firefox 3.0.3 na Ubuntu przy użyciu opcji Czas wykonania (ang. Profiler) z pluginu Firebug.

Przeczytaj także wpis Szybkie iteracje czyli przyspieszanie pętli oraz
Wydajne tworzenie elementów DOM C.D..

Na początek mamy link go, który będzie wywoływać każdą testowaną metodę. Metody wykonujemy jedna na raz i mierzymy czas wstawienia 1000 elementów listy li do ul od id list.


<a href="#" id="go">go</a>
<ul id="list"></ul>

1. Sposób

Wstawienie metodą insert elementów LI w pętli, które zostały stworzone przy pomocy silnika template z biblioteki Prototype.


$('go').observe('click',go1);
//Czas wykonania (2136.313ms, 84055 wywołań)
function go1(e){
	e.stop();
	$('list').update();
	var tpl = new Template ('<li class="#{class}" id="#{id}">#{id}</li>');
	$R(1, 1000).each(function(i){
		$('list').insert(tpl.evaluate({
			class: 'klasa',
			id: i
		}));
	})
}

Dom 1
Continue reading

Share