Workaround per usare __defineGetter__ e __defineSetter__ su elementi HTML
defineGetter e defineSetter sono due metodi dannatamente utili supportati al momento da Firefox, Opera 9.5, Safari 3 e Konqueror. Essi permettono di manipolare le proprietà dichiarando un setter ( una funzione che viene eseguita opgni volta che settiamo una proprietà ) o un getter ( una funzione che viene usata ogni volta che prendiamo una proprietà in modo da manipolare il valore ritornato ).
Teoricamente potremmo usarlo per simulare innerText su Firefox:
Purtroppo in Firefox 2 ( con la versione 3 il problema non sussiste ) non è possibile definire ne getter ne setter sugli elementi HTML ![]()
Si tratta di uno strano bug che fortunatamente ha un workaround molto semplice, ovvero quello di applicare il getter/setter alla classe Node:
L’unico svantaggio è che così facendo stiamo applicando il setter a tutti i tipi di nodi, compresi nodi testo, commento e persino documento!
Ma anche in questo caso la soluzione è alquanto semplice:
if(this.nodeType == 1)
this.textContent = value;
else
this.innerText = value;
})
Semplicemente controlliamo che il nodo sia veramente un elemento HTML ( con nodeType uguale a 1 ): se è vero settiamo la proprietà textContent ( il rispettivo di innerText in IE ) altrimenti ci comportiamo come se il setter non esistesse, ovvero settando la proprietà innerText manualmente.
Volendo possiamo “standardizzare” questa operazione tramite una funzione ( Ah che belle le closures
):
Node.prototype.__defineSetter__(prop, function(value) {
this.nodeType == 1
? fn.call(this, value)
: this[prop] = value;
})
}
Con poche modifiche possiamo creare una funzione che crea un getter:
Node.prototype.__defineGetter__(prop, function() {
retun this.nodeType == 1)
? fn.call(this, value)
: this[prop];
})
}
Per altri snippet stay tuned!
Tags: classi, defineGetter, defineSetter, Javascript, prototype