2011-05-23 3 views
5

Sto cercando di definire un setter personalizzato per la proprietà innerHTML. Purtroppo, non sono in grado di accedere alla proprietà sottostante dopo definisco la funzione setter:proprietà Accesso nascosti da __defineGetter __/__ defineSetter__ in JavaScript

$('body')[0].__defineSetter__("innerHTML", 
    function (val) { 
    alert("Setting to: " + val); 
    this.innerHTML = val; 
}); 

Questo frammento riempie lo stack di chiamate poiché la cessione chiama il setter ricorsivamente. Apparenly innerHTML è già una proprietà sovraccarico in IE8 e si può semplicemente salvare il get coppia di anziani/impostare e utilizzare all'interno del nuovo descrittore di proprietà. Tratto da MSDN:

var innerHTMLdescriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML'); 
Object.defineProperty(Element.prototype, 'innerHTML', 
    { set: function(htmlVal) { 
     var safeHTML = toStaticHTML(htmlVal); 
     innerHTMLdescriptor.set.call(this, safeHTML); 
    } 
}); 

Tuttavia, questo non sembra essere il caso per Chrome, dove getOwnPropertyDescriptor ritorna undefined per innerHTML. In questo caso, come posso accedere alla proprietà sottostante?

Domanda bonus: come faccio a garantire che tutti gli oggetti creati in futuro hanno questa speciale innerHTML comportamento? È possibile utilizzare i prototipi DOM per questo? Sembra che sovraccaricare una funzione non sia ciò di cui ho bisogno qui. Forse è possibile sovraccaricare il costruttore DOM e aggiungere una chiamata __defineGetter__/defineProperty ma sembra che il supporto per i costruttori non è comune, così mi piacerebbe sapere se c'è qualche alternativa.

+0

Non usare \ _ \ _ defineSetter \ _ \ _ nel codice di produzione vero e proprio - è non standard e può escludere gli utenti di molti browser. – Ryan

+1

l'equivalente standard è 'defineProperty' giusto? ancora, il problema di referenziare la proprietà nascosta esiste ... – BruceBerry

+1

No, non è ancora uno standard. Non dovresti usarlo perché esclude i browser più vecchi. Certo, se stai facendo qualcosa di non cruciale e si degrada con grazia, va bene. Ma non sembra che sarà nel tuo caso. – Ryan

risposta

1

Tutto ciò che serve è una proprietà datastore separata per memorizzare il valore reale, proprio come con altre lingue che usano getter e setter. Puoi usare chiusure per renderle nascoste.

var _innerHTML = ""; 

this.__defineSetter__("innerHTML", 
    function (val) { 
     alert("Setting to: " + val); 
     _innerHTML = val; 
    }); 

this.__defineGetter__("innerHTML", 
    function() { 
     return _innerHTML; 
    }); 

Tuttavia, ho trovato che l'uso di getter e setter sulle proprietà DOM esistenti spesso semplicemente non funzionerà, a causa della gestione speciale di queste proprietà internamente. Ad esempio, non funzionerà con la proprietà value di un testo input. Mi aspetto che lo innerHTML sia nella stessa barca.

Problemi correlati