Objektname eines Objekts?
Karl
- javascript
Hallo,
kennt Jemand eine Möglichkeit, den JavaScript-Namen eines Objekts herauszukriegen?
Beispiel:
objekt1 = new obj();
alert(objekt1.name);
Mich würde folgende Ausgabe erfreuen: "objekt1"
Hintergrund ist ein Framework, das HTML-Tags erzeugt, deren ID idealerweise dem Namen des Objekts entspricht.
Mir ist schon klar, dass man sich einfach selbst ein Feld erzeugen kann, welches den Namen des Objekts als String enthält. Aber vielleicht geht das ja auch einfacher?
Vielen Dank im Voraus!
lg
Karl
Hallo,
Mir ist schon klar, dass man sich einfach selbst ein Feld erzeugen kann, welches den Namen des Objekts als String enthält. Aber vielleicht geht das ja auch einfacher?
Nein.
Hintergrund ist ein Framework, das HTML-Tags erzeugt, deren ID idealerweise dem Namen des Objekts entspricht.
Es scheint mir immer unverständlich, wenn jemand Code-interne Organisation und Benennung mit einer bestimmten »Ausgabe« koppeln will. Variablennamen müssen verständlich sein, sind darüber hinaus aber Schall und Rauch. Wenn man eine ID z.B. zur Adressierung außerhalb des JavaScript-Codes via CSS braucht (wozu brauchst du sie?), sollte man eine wählen, die vornehmlich diesem Zweck angemessen ist. Ich persönlich fand es bisher nicht erstrebenswert, ein bestimmtes Ergebnis fest an einen bestimmten Variablennamen zu koppeln.
Mathias
Hallo Mathias,
Hintergrund ist folgender: ich schreibe eine Art GUI-Framework. Es soll Elemente wie Forms, Edits, Labels, Scrollbars etc. enthalten.
Beispiel in JavaScript:
form1 = new TForm();
form1.setBounds(30,30,300,200);
button1 = new TButton(form1);
button1.setBounds(50,50,70,20);
button1.setCaption("Hallo Welt");
form1.show();
Dieser Code soll ein (mit der Maus verschiebbares) Dialogfeld mit einem Button erzeugen. Das ist natürlich nur ein sehr einfaches Beispiel.
Nehmen wir zum Beispiel die Methode "setCaption" eines GUI-Objekts, in diesem Falle eines TButton. Die Implementierung der Methode könnte so einfach sein:
function setCaption(fText)
{
el = document.getElementById(this.OBJEKTNAME);
el.style.value = fText;
}
Doch genau da liegt das Problem: OBJEKTNAME steht stellvertretend für ein Feld des Objekts - was es aber scheinbar nicht gibt.
Ich habe es jetzt anders gelöst. Aber es ist natürlich nicht so elegant.
In diesem Fall wäre es eben sehr praktisch, wenn die IDs von INPUT-Elementen oder DIVs die Namen der JavaScript-Objekte, die sie repräsentieren, tragen würden.
lg
Kalle
Nehmen wir zum Beispiel die Methode "setCaption" eines GUI-Objekts, in diesem Falle eines TButton. Die Implementierung der Methode könnte so einfach sein:
function setCaption(fText)
{
el = document.getElementById(this.OBJEKTNAME);
el.style.value = fText;
}
wozu brauchst du getElement?
Wenn du das Element mit createElement() erzeugst ist der rückgabewert doch bereits die Referenz.
Ich habe es jetzt anders gelöst. Aber es ist natürlich nicht so elegant.
Wenn du es mit dem Rückgabewert von createElement gelöst hast, ist es eleganter.
Struppi.
wozu brauchst du getElement?
Wenn du das Element mit createElement() erzeugst ist der rückgabewert doch bereits die Referenz.
Oops, sowas gibt es? *schäm*
Gut zu wissen, das könnte die Lösung sein.
Vielen Dank!
gruss Karl,
... ich schreibe eine Art GUI-Framework. Es soll Elemente wie
Forms, Edits, Labels, Scrollbars etc. enthalten.Beispiel in JavaScript:
form1 = new TForm();
...Dieser Code soll ein (mit der Maus verschiebbares) Dialogfeld
mit einem Button erzeugen. Das ist natürlich nur ein sehr
einfaches Beispiel. ... Die Implementierung der Methode könnte
so einfach sein:function setCaption(fText)
{
el = document.getElementById(this.OBJEKTNAME);
el.style.value = fText;
}... OBJEKTNAME steht stellvertretend für ein Feld des Objekts -
was es aber scheinbar nicht gibt.
so wie es aussieht, kapselst Du die Logik eines oder einer gruppe
von DOM-knoten in einem JavaScript-objekt. die initialisierung des
von Dir beispielhaft angegebenen objekts vom typ "tform" erledigt
Deine konstruktorfunktion "TForm". Du musst nur sicherstellen, dass
genau dort, oder meinetwegen auch in einer initialisierungsmethode
das "tform"-objekt mindestens einen der betroffenen DOM-knoten
als referenz an sich binden kann - z.b.:
~~~javascript var TForm = function (nodeObj) {
this.domNode = nodeObj;
//your code;
};
die beispielhafte methode "setCaption" liesse sich dann
so umsetzen:
~~~javascript
TForm.prototype.setCaption = function (fText) {
this.nodeObj.style.value = fText;
};
Ich habe es jetzt anders gelöst.
und wie?
In diesem Fall wäre es eben sehr praktisch, wenn die IDs von
INPUT-Elementen oder DIVs die Namen der JavaScript-Objekte,
die sie repräsentieren, tragen würden.
referenzen auf die von meinem JavaScript-objekt zu beeinflussenden
dom-knoten sind in meinen augen naheliegender, da ich diese bei der
objektinitialisierung sowiso "kennen" muss.
by(t)e by(t)e - peterS. - pseliger@gmx.net
Ich habe es jetzt anders gelöst.
und wie?
An DOM-Knoten habe ich noch gar nicht gedacht. Stattdessen übergebe ich im Konstruktor den Namen des Objekts als String.
button1 = new TButton("button1");
function TButton(fName)
{
this.name = fName;
}
...und verwende diesen später bei der Erzeugung
s = '<input id='+this.name+'>';
...und suche in der Methode setCaption das entsprechende Element
element = document.getElementByID(this.name);
Ist wie gesagt ziemlich uncool, aber eine bessere Lösung habe ich noch nicht gefunden. Das mit den DOM-Knoten muss ich mir mal ansehen :-)
Danke auf jeden Fall schonmal.
lg
Karl
An DOM-Knoten habe ich noch gar nicht gedacht. Stattdessen übergebe ich im Konstruktor den Namen des Objekts als String.
button1 = new TButton("button1");
function TButton(fName)
{
this.name = fName;
}...und verwende diesen später bei der Erzeugung
s = '<input id='+this.name+'>';
Du arbeitest anscheinend mit innerHTML. Besser wäre createElement() zu nutzen, aber auch so kannst du dir den Namen sparen, bzw. den Parameter.
Wie Mathias schon andeutet:
function TButton()
{
this.name = 'TButton' + TButton.index++;
}
TButton.index = 0;
Ist wie gesagt ziemlich uncool, aber eine bessere Lösung habe ich noch nicht gefunden. Das mit den DOM-Knoten muss ich mir mal ansehen :-)
Wäre cooler ;-)
Struppi.
hallo again Karl,
... Das mit den DOM-Knoten muss ich mir mal ansehen :-)
unbedingt.
fuer faelle, wie in dem von Dir beschriebenen, recycle
ich immer noch folgendes grob skizzierte schema:
var DHTMLObject = function () {
this.constructor = arguments.callee;
/*
minimal initial code if necessary like:
- private properties,
- privileged public methods.
*/
this.compile.apply(this, arguments);
};
DHTMLObject.prototype.compile = function (obj) { // for reinitialization.
var regXClassName = (/\bdhtmlObject\b/);
if (obj && obj.nodeType && obj.nodeName && obj.className && (obj.nodeType == 1) && (regXClassName.test(obj.className))) {
this.node = obj;
/*
major part of constructor code that not necessarily
needs to be run by the constructor function itself.
*/
var self = this;
this.node.onmousedown = function (evt) {
DHTMLObject.onMouseDown(evt, self);
};
}
};
DHTMLObject.onMouseDown = function (evtObj, dhtmlObj) {
evtObj = (window.event || evtObj);
//some more code;
};
DHTMLObject.elements = [];
DHTMLObject.initialize = function () {
if (window.opera && (DHTMLObject.elements.length >= 1)) {return;} // in order to fix the beneath mentioned opera 9 "onload" bug.
if (typeof document.getElementsByClassNames == "function") {
var i, obj, arr = document.getElementsByClassNames("dhtmlObject");
for (i=0; i<arr.length; ++i) {
obj = arr[i];
if (obj && (obj.nodeType == 1)) {
DHTMLObject.elements[DHTMLObject.elements.length] = new DHTMLObject(obj);
}
}
}
//alert("DHTMLObject.elements[" + (DHTMLObject.elements.length - 1) + "] : " + DHTMLObject.elements[DHTMLObject.elements.length - 1]);
};
if (window.addEventListener) {
window.addEventListener("load", DHTMLObject.initialize, true); // opera 9 behaves buggy on this - workaround got implied.
} else if (window.attachEvent) {
window.attachEvent("onload", DHTMLObject.initialize);
}
dabei geht mein Dank wie immer an Dr. Thomas Meinike fuer seine
pioniertat zu einem "getElementsByClassName", das mir seit dieser
zeit als angepasstes "document.getElementsByClassNames" stets
treue dienste leistet.
letztgenanntes modul benoetigt wiederum die unterstuetzung der
Array-methode "contains", die fuer nicht-gecko-getriebene browser
immer noch nachgeruestet werden muss:
schon ziemlich alt - http://www.pseliger.de/jsExtendedApi/jsApi.Array.contains.dev.js,
nicht mehr so neu - http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozExtensions.js.
eine entwicklungsseite verlinkt dann nur noch diese javascript-dateien zusammen mit
ein paar stylesheet-angaben. im html-quelltext selber werden die zu initialisierenden
[DHTMLObject]-objekte ueber den klassennamen des entsprechenden DOM-Knotens aufgespuert.
in diesem fall muesste man einfach <[nodename] class="... dhtmlObject ..." />
schreiben.
dieses grundpaket versetzt zumindest mich in die lage, innerhalb von wenigen minuten
eine vernuenftige arbeitsgrundlage fuer selbstzustrickende GUI-elemente zu schaffen.
by(t)e by(t)e - peterS. - pseliger@gmx.net
Hallo,
Wie ich vermutet hatte, spielt der Variablenname keine besondere Rolle. Für deine Zwecke könnte sich das Objekt auch automatisch selbst eine ID geben (z.B. TForm plus eine fortlaufende Nummer). Muss es aber gar nicht. Du willst anscheinend in den Methoden einfach auf den im Konstruktor erzeugten Elementknoten zugreifen. Also speicherst du (siehe Peter) eine Referenz auf den Elementknoten am Objekt. Was auch oft nützlich ist: Eine Referenz auf die jeweilige Instanz am Elementobjekt speichern, sodass sie sich gegenseitig verlinken. (Was allerdings garantiert zu Speicherlecks im MSIE 6 führt.)
Mathias