Eigene Eigenschaften bei HTML-Elementen anlegen
JürgenB
- javascript
Hallo,
ich möchte die Eventhandler aus dem HTML entfernen, also statt
<div onclick="tuwas()">
möchte ich
document.getElement....onclick=tuwas ;
nehmen. Allerdings habe ich dann ein Problem, wenn die Funktion tuwas mit Parametern aufgerufen wird, also
<div onclick="tuwas(p1)">
<div onclick="tuwas(p2)">
...
Ich habe das Problem jetzt so gelöst, das ich den Parameter an das DIV als neue Eigenschaft hänge, also
var p=new Array(p1,p2,...);
var d=document.getElementsByTagName("div") ;
for(var i=0;i<d.lenght;i++) {
d[i].par=p[i]; // <---- !
d[i].onclick=function() { tuwas(this.par); }
}
Das funktioniert in IE, FF, Opera und Konqueror. Safari konnte ich nicht testen.
Jetzt meine Frage: darf ich an die HTML-Elemente beliebige selbstdefinierte Eigenschaften und Methoden hinzufügen, oder ist das Funktionieren nur ein Zufall? Sollten (müssten) das alle Standardkonformen Browser können?
Gruß, Jürgen
hi,
Ich habe das Problem jetzt so gelöst, das ich den Parameter an das DIV als neue Eigenschaft hänge
Ja, übliche und einfache Methode.
Eine andere wären wohl Closures.
Jetzt meine Frage: darf ich an die HTML-Elemente beliebige selbstdefinierte Eigenschaften und Methoden hinzufügen, oder ist das Funktionieren nur ein Zufall?
Du hast die Eigenschaft nicht an ein HTML-Element gehängt - sondern an ein Javascript-Objekt, welches dieses HTML-Element aus Sicht von Javascript repräsentiert.
Sollten (müssten) das alle Standardkonformen Browser können?
Ich denke ja.
gruß,
wahsaga
Hallo wahsaga,
danke für Deine Antwort.
Eine andere wären wohl Closures.
ich habe den Artikel von moliliy schon gelesen. Wie man aus Methoden von Objekten heraus Eventhandler auf andere Methoden des gleichen Objekts setzt habe ich auch verstanden. Aber wie ich hier auch noch die Parameter übergeben kann, und das nicht bei einem Element und einem Handler, sondern wie im Beispiel im Ausgangsposting bei vielen DIVs mit gleichem Handler aber verschiedenen Parametern, da habe ich noch eine Blockade.
Im Moment habe ich:
for(var i=0;i<this.titel.length;i++) { // this.title wurde mit getElementsByTagName gewonnen
var t=this.titel[i];
t.nr=i;
t.thisObj = this;
t.onclick = function() { this.thisObj.sort(this.nr); }
}
Gruß, Jürgen
hi,
Eine andere wären wohl Closures.
Wenn ich's genauer überlege, war das wohl der falsche Begriff, sorry.
Anonyme Funktion wäre hier angebrachter.
Im Moment habe ich:
t.onclick = function() { this.thisObj.sort(this.nr); }
Ja, genau sowas.
gruß,
wahsaga
Hallo,
Ich habe das Problem jetzt so gelöst, das ich den Parameter an das DIV als neue Eigenschaft hänge
Ja, übliche und einfache Methode.
Eine andere wären wohl Closures.
Zur Erklärung für Mitlesende: Closures gehen bei Schleifen nicht.
for (var i = 0, element; element = liste[i]; i++) {
element.onclick = function () {
// Closure-Funktion, schließt i, element und liste ein
alert("Element-Nummer: " + i);
};
}
Das würde bei allen Elementen dieselbe Element-Nummer ergeben, nämlich den letzten Wert, den i in der Funktionsausführung hatte.
Allgemein: Eine Closure konserviert nicht den Wert, den eine Variable zu dem Zeitpunkt hat, an dem sie notiert wird. Sie konserviert lediglich den Namen zum Zugriff auf eine bestimmte Speicherstelle.
function func () {
var i;
i = 1;
element1.onclick = function () {
alert(i);
};
i = 2;
element2.onclick = function () {
alert(i);
};
}
Man denkt intuitiv, der Klick auf element1 ergäbe 1, der Klick auf element2 hingegen 2. Ist aber nicht so. Die Funktionsscopes der drei Funktionen sind miteinander verbunden, die Variablen werden nicht zum Zeitpunkt des Notierens der Closure kopiert, sondern es werden Referenzen angelegt. func wird ausgeführt und endet mit der lokalen Variable i mit dem Wert 2. Diese wird im Speicher bewahrt, da noch zwei Funktionen mit diesem Scope verknüpft sind. Wenn diese Funktionen ausgeführt werden, ist in beiden i == 2.
Mathias
Hallo molily,
danke für Deine Erklärungen. An dieser Stelle bin ich auch hängengeblieben. Ich glaube, eine mögliche Lösung wäre, für jedes Element eine eigene Handlerfunktion anzulegen. Aber da es ja "erlaubt" ist, an die Elemente, bzw. an ihre Repräsentanten im DOM-Baum eigene Methoden und Eigenschaften zu hängen, ist dieses wohl die einfachere Lösung. Es bleibt natürlich die Gefahr, das sich unabhängige Scripte in die Quere kommen.
Gruß, Jürgen
Hallo,
Jetzt meine Frage: darf ich an die HTML-Elemente beliebige selbstdefinierte Eigenschaften und Methoden hinzufügen, oder ist das Funktionieren nur ein Zufall? Sollten (müssten) das alle Standardkonformen Browser können?
Im Prinzip lässt sich jedes ECMAScript-Objekt durch neue Member erweitern (ich wüsst nicht, welches Objekt nicht bzw. was im Sinne von ECMAScript dagegen sprechen könnte). Ein ECMAScript-konformer Browser sollte das also erlauben. Einen JavaScript-Fehler sollte es zumindest keinesfalls ergeben, und falls ein Browser das Setzen der Eigenschaft ignoriert, kannst du diesen Fall einfach mit if (this.member) ... abfangen.
elementobjekt.neue_eigenschaft = "wert"; sollte also keine Probleme machen. Etwas anderes ist möglicherweise elementobjekt.setAttribute("neues_attribut", "wert");. Das wird ebenso oft benutzt und eignet sich natürlich nur für Strings. Ich weiß nicht, ob das im DOM erlaubt ist, jedenfalls sind da alle wichtigen Browser tolerant und setzen das Attribut, auch wenn es nicht Teil von HTML ist.
Mathias
nehmen. Allerdings habe ich dann ein Problem, wenn die Funktion tuwas mit Parametern aufgerufen wird, also
<div onclick="tuwas(p1)">
<div onclick="tuwas(p2)">
> ...
Was sind das für Parameter? Woher kommen diese? Und wie hängen die mit dem Element zusammen?
Struppi.
--
[Javascript ist toll](http://javascript.jstruebig.de/) (Perl auch!)
Hallo Struppi,
im einfachsten Fall eine Nummer, wie im anderen Posting. Aber es können auch beliebige Werte sein. Aber im Moment denke ich an Konstanten oder vieleicht Variablen, die sich in Objekten befinden.
Gruß, Jürgen
im einfachsten Fall eine Nummer, wie im anderen Posting. Aber es können auch beliebige Werte sein. Aber im Moment denke ich an Konstanten oder vieleicht Variablen, die sich in Objekten befinden.
Aber was für eine Nummer? Wo kommt die her und in welchem Kontext steht sie zum Element?
Irgendwie kommt mir dein Ansinnen seltsam vor. Entweder du willst eine Eigenschaft des Objektes, auf das kannst du innerhalb der Funktion mit this zugreifen, oder du hast ein Parameter, der in einem zusammenhang mit dem Element steht, z.b. mit der id, aber diese bekommst ja ebenfalls über this.id. Deshalb kann ich mir nicht vorstellen, was du machen willst.
Struppi.
Hallo Struppi,
vieleicht gehe ich da etwas zu abstrakt heran. Im konkreten Fall habe ich eine Tabelle und muss nur wissen, auf die wievielte Spaltenüberschrift gedrückt wurde. Natürlich kann ich mit this, parent etc. die Nummer des Elementes im Handler herausbekommen, einfacher ist es aber, wie im Beispiel, jedem Element zu sagen, welche Nummer es hat.
Gruß, Jürgen
vieleicht gehe ich da etwas zu abstrakt heran. Im konkreten Fall habe ich eine Tabelle und muss nur wissen, auf die wievielte Spaltenüberschrift gedrückt wurde. Natürlich kann ich mit this, parent etc. die Nummer des Elementes im Handler herausbekommen, einfacher ist es aber, wie im Beispiel, jedem Element zu sagen, welche Nummer es hat.
Du generierst den Code also in etwa so:
for(0...6)
{
print '<th onclick="tu_Was(' + $_ + ');">...</th>';
}
Aber was machst du mit dieser Nummer?
Was auch gehen würde:
for(0...6)
{
print '<th nummer="' + $_ + '" onclick="tu_Was(this);">...</th>';
}
und dann:
function tu_was(th)
{
var nr = th.getattribute('nummer');
alert(nr);
}
Struppi.
Hallo Struppi,
Du generierst den Code also in etwa so:
for(0...6)
{
print '<th onclick="tu_Was(' + $_ + ');">...</th>';
}
>
> Aber was machst du mit dieser Nummer?
der Handler benötigt die Nummer für seine Arbeit, hier Zugriff auf die darunterliegende Spalte.
Ich möchte aber vom onclick= im Tag weg und lieber den onclick per JS anlegen. (Siehe Ausgangsposting).
Das konkrete Problem, mit dem ich gerade beschäftigt bin:
<http://www.j-berkemeier.de/TableSort.html> / <http://www.j-berkemeier.de/TableSort_so_geht_es.html>
hier wird der Text in den THs durch einen Link mit href=jacascript:... ersetzt. Die Spaltennummer wird als Parameter übergeben. Einfach Maus über die Überschrift schieben.
Meine jetzige Version, die im HTML nur noch Klassennamen erwartet, ist noch im Test:
<http://www.j-berkemeier.de/test/TableSort.html> / <http://www.j-berkemeier.de/test/TableSort_so_geht_es.html>
Hier wird den THs per Javascript ein onlick spendiert und der Parameter und der Objektname werden als zusätzliche Eigenschaft im jeweiligen TH gespeichert.
Gruß, Jürgen
Meine jetzige Version, die im HTML nur noch Klassennamen erwartet, ist noch im Test:
http://www.j-berkemeier.de/test/TableSort.html / http://www.j-berkemeier.de/test/TableSort_so_geht_es.html
Sowas hab ich hab auch grad gemacht http://jstruebig.de/web/javascript/test/test tabelle sortieren.html
Hier wird den THs per Javascript ein onlick spendiert und der Parameter und der Objektname werden als zusätzliche Eigenschaft im jeweiligen TH gespeichert.
hmm, ich geb zu ich tu mich schwer andere Skripte zu erfassen. Aber ich werd das Gefühl nicht los, dass du hier wirklich mehrhmals um die Ecke gedacht hast.
Struppi.
Hallo Struppi,
Sowas hab ich hab auch grad gemacht
interessant!
Beim schnellem überblicken glaube ich, dass du die onclicks der Überschrift genauso machst, wie ich:
th[i].table = t;
th[i].spalte = i;
th[i].desc = false;
th[i].onclick = sort_tabelle;
th[i].style.cursor = 'pointer';
th[i].pointer = th[i].appendChild(pointer)
und
var t=this.titel[i];
t.nr=i;
t.style.cursor="pointer";
t.thisObj = this;
t.onclick = function() { this.thisObj.sort(this.nr); }
Nur ich übergebe die Spaltennummer mit this.nr und Du scheinst sie in sort_tabelle auszulesen.
Meine Sorge ist jetzt nur, dass irgendein anderes Script, das mit meinem nichts zu tun hat, auch auf die Tabelle zugreift und dort auch etwas unter z.B. element.nr abspeichert. Die Gefahr ist nicht so groß, wie bei globalen Variablen, aber richtig gekapselt sind meine Variablen nicht. Daher hätte ich die Parameter lieber im Tabellen-Objekt gespeichert, als sie an die THs anzuhängen. Vieleicht fällt mir ja noch was dazu ein.
Gruß, Jürgen
hi,
der Handler benötigt die Nummer für seine Arbeit, hier Zugriff auf die darunterliegende Spalte.
Das sollte doch auch anders gehen, als über eine Indexnummer.
Wie wär's beispielsweise mit nextSibling?
(Gut, da müsste man ggf. noch mit Textnode zwischen den Tabellenzellen aufpassen - aber da könnte man ja nodeName oder nodeType noch überprüfen, und ggf. einfach noch einen weiter gehen.
gruß,
wahsaga
Hallo wahsaga,
Wie wär's beispielsweise mit nextSibling?
nie und nimmer.
(Gut, da müsste man ggf. noch mit Textnode zwischen den Tabellenzellen aufpassen - aber da könnte man ja nodeName oder nodeType noch überprüfen, und ggf. einfach noch einen weiter gehen.
genau deswegen. Und irgendwie ist es auch eine Frage des Aufwands, sowohl bei der Programmierung, als auch bei der Scriptgröße und bei der Ausführung: hangel ich mich durch den DOM-Baum und prüfe, ob ich das gewünschte Element gefunden habe, oder greife ich einfach direkt darauf zu. Außerdem ist das Problem mit der Spaltennumer als Parameter ja noch einfach zu umgehen. Aber prinzipiell kann ein Eventhandler ja auch einen "beliebigen" Übergabeparameter enthalten.
Gruß, Jürgen