Self Beispiel funktioniert im FF nicht? contains() ??
WernerK
- javascript
Hallo,
wegen eines Problems und zum JS lernen bin ich auf den Self Beispielcode gestoßen.
http://de.selfhtml.org/javascript/objekte/all.htm#contains
Ich arbeite mit Firefox2. Mir wurde hier im Forum gesagt man soll nicht mehr "document.all" verwenden. Daher habe ich versucht das Beispiel so abzuändern damit es im FF funktioniert.
<html><head><title>Test</title>
<script type="text/javascript">
function Test () {
if (document.getElementById("dieseDatei").contains(document.getElementById("Absatz")))
alert(document.getElementById("Absatz").innerText);
}
</script>
</head><body id="dieseDatei">
<p id="Absatz">Ein Text</p>
<a href="javascript:Test()">Test</a>
</body></html>
ich habe das also mit "getElementsByID" ersetzt.
Jetzt kommt aber immer eine Fehlermeldung wie:
"document.getElementById("dieseDatei").contains is not a function"
Kann mir jemand sagen warum das kommt und wie man das Beispiel im FF zum laufen bekommt?
contains() ist doch eigentlich kaut Beschreibung eine Methode?
Gruss
Werner
Hi,
Kann mir jemand sagen warum das kommt
Du verwendest Methodiken des IE-proprietären document.all-Objektes. Dies sagt schon aus, dass Du abgesehen vom IE nirgendwo mit einer Unterstützung rechnen kannst - auch dann nicht, wenn Du Teile, die mit der Methodik nichts zu tun haben, durch DOM ersetzt. An der von Dir genannten Stelle suchst Du zudem vergeblich nach einem Hinweis, dass ein Firefox element.contains() unterstützt.
und wie man das Beispiel im FF zum laufen bekommt?
Indem Du eine entsprechende Funktionalität selbst implementierst.
contains() ist doch eigentlich kaut Beschreibung eine Methode?
Falls Du auf das "function" in der Fehlermeldung anspielst: In JavaScript sind Methoden Funktionen eines Objekts.
Cheatah
Hallo Cheatah
danke für deine Hilfe,
ich bin leider noch nicht so tief drin in JS.
Verstehe ich es dann richtig, dass "contains()" nur zum "all" Objekt gehört und das wiederum nur vom IE verstanden wird?
Im Self Beispiel steht halt nur der Hinweis für den Safari Browser, daher hatte ich das event. übersehen.
"Beachten Sie:
Das Beispiel kann im Safari nicht nachvollzogen werden, da dieser das Objekt document.all nicht kennt. Safari unterstützt jedoch die Methode contains()."
Was für einen Ersatz oder Möglichkeit gibt es dann für "contains()" in Verbindung mit dem Firefox?
Gruss
Werner
Hi,
Verstehe ich es dann richtig, dass "contains()" nur zum "all" Objekt gehört und das wiederum nur vom IE verstanden wird?
ja, genau.
Im Self Beispiel steht halt nur der Hinweis für den Safari Browser, daher hatte ich das event. übersehen.
Bei der Überschrift eines Themas findest Du eine Reihe Icons, aus denen Du die Kompatibilität grob ablesen kannst. Dort ist Firefox nicht dabei.
Was für einen Ersatz oder Möglichkeit gibt es dann für "contains()" in Verbindung mit dem Firefox?
Die Funktionalität selbst programmieren. Mir ist keine existierende Alternative bekannt.
Cheatah
Hallo Cheatah,
danke nochmals.
Die Funktionalität selbst programmieren. Mir ist keine existierende Alternative bekannt.
Darf ich nochmals nachhaken. Ich habe nämlich bei der Suche nach meinen Problemen folgend Code gefunden.
if (window.Node && Node.prototype && !Node.prototype.contains) {
Node.prototype.contains = function (arg) {
return !!(this.compareDocumentPosition(arg) & 16);
};
}
Wenn man diesen mit einbaut, dann funktioniert das auch im Firefox.
Nur verstehe ich da nur Banhof.
Ok, "node" habe ich gelesen das ist ein Knoten,
Was aber macht "prototype" und "compareDocumentPosition"?
Vielleicht kannst du oder jemand anderes mir (oder auch anderen) das Codebeispiel ein wenig erklären?
Ich weiss, für einen Anfänger in JS ist dies vermutlich ein wenig zu hoch :-)
Hi,
Was aber macht "prototype"
Bestehende Objekte um eigene Methoden erweitern.
und "compareDocumentPosition"?
Vergleicht die Knotenposition innerhalb des Dokuments.
Ich weiss, für einen Anfänger in JS ist dies vermutlich ein wenig zu hoch :-)
Ich habe mir eine kleines Formular-Script gemacht, in der ich eine JS-Eigenschaft/Methode eingebe, und daraus bastelt mir das Script dann Google-Suchanfragen mit den relevantesten JS-Quellen. Nutze ich immer, wenn ich mal eben etwas nachschlagen möchte. Die Such-URLs zu beispielsweise "innerHTML" lauten:
innerHTML site:de.selfhtml.org intitle:"SELFHTML: JavaScript / Objektreferenz /" (SELFHTML: unvollständig, aber schöne, meistens zutreffende Auflistung der unterstützenden Browser)
intitle:innerHTML site:developer.mozilla.org (Mozilla Developer Center (englisch, wichtig, standardkonform + Moz-Erweiterungen)
intitle:innerHTML msdn (Doku für IEs JScript)
Wenn Du so also nach den dir unbekannten Begriffen im Mozilla Developer Center suchst, wirst Du die Dokumentation finden, und, daß prototype zum Kern von JS gehört, und compareDocumentPosition zu DOM 3,
Gruß, Cybaer
Nachtrag:
prototype zum Kern von JS gehört
Wobei zu berücksichtigen ist, daß der IE nicht JavaScript nutzt, sondern JScript. JScript unterstützt prototype nur unzureichend. Es empfiehlt sich prinzipiell sowohl nach Standard-JS zu suchen (im MDC), als auch nach JScript (bei MSDN), wenn man Scripts schreiben möchte, die sowohl auf dem IE, als auch auf allen restlichen Browsern laufen sollen1
Gruß, Cybaer
Hallo Cybaer,
auch dir herzlichen Dank für deine Mühe und Erklärung.
Nur noch kurz ne Frage:
Ich hatte beim googlen zu "prototype" diesen Link gefunden.
http://www.teialehrbuch.de/Kostenlose-Kurse/AJAX/31959-Prototype-Eine-AJAX-Bibliothek-in-JavaScript.html
Ist diese erwähnte AJAX Bibliothek das gleiche oder nur zufällig der gleich Name?
Gruss
Werner
Hi,
Ist diese erwähnte AJAX Bibliothek das gleiche oder nur zufällig der gleich Name?
Das ist was ganz anderes. Zufällig ist dieser IMHO ärgerliche Name aber nicht.
Gruß, Cybaer
Hi,
Ist diese erwähnte AJAX Bibliothek das gleiche oder nur zufällig der gleich Name?
der Name ist zufällig gewollt ;-) Es gibt eine Vielzahl Bibliotheken, die den prototype-Ansatz in JavaScript exzessiv nutzen; für einige der Autoren lag es offenbar nahe, sich bei der Namensgebung von diesem Ansatz inspirieren zu lassen.
Übrigens kannst Du Dir einen prototype wie eine Blaupause vorstellen, welche eine gewisse Magie besitzt: Ändert man die Blaupause, ist gleichzeitig alles, was aus ihr gebaut wurde, mit verändert.
Cheatah
Hallo,
Wobei zu berücksichtigen ist, daß der IE nicht JavaScript nutzt, sondern JScript. JScript unterstützt prototype nur unzureichend.
Alle zugänglichen Konstruktoren in JScript sind m.W. auch prototypisch erweiterbar, der Witz ist eher, dass die DOM-Interfaces nicht als globale Konstruktoren angeboten werden.
Das ist übrigens keine Erfordernis irgendeines Standards. Dass man in "allen" anderen Browsern ein gleiches Verhalten hat, ist Resultat eines informellen Anpassungsprozesses. Es gab Zeiten, da lief das völlig unterschiedlich im Gecko, Opera, Webkit und KHTML.
Mathias
Lieber WernerK,
ich glaube, Du hast gerade die Antwort auf meine Frage gegeben...
if (window.Node && Node.prototype && !Node.prototype.contains) {
Node.prototype.contains = function (arg) {
return !!(this.compareDocumentPosition(arg) & 16);
};
}
>
> Wenn man diesen mit einbaut, dann funktioniert das auch im Firefox.
> Nur verstehe ich da nur Banhof.
Bei "prototype" kann ich Dir weiterhelfen, bei "compareDocumentPosition" (noch) nicht.
> Ich weiss, für einen Anfänger in JS ist dies vermutlich ein wenig zu hoch :-)
Also spätestens bei "prototype" muss ein Anfänger zwangsläufig überfordert sein.
Die Idee hinter prototype ist folgende: In JavaScript existieren verschiedene Baupläne für Objekttypen. Du hast sicherlich schon Anweisungen gesehen, die in etwa so aussehen:
`var a = new Array();`{:.language-javascript}
Hier wird mittels der Konstruktor-Funktion "Array" eine neue Instant eines Objektes geschaffen, dessen Aufbau in der Konstruktor-Funktion geregelt wird. "a" ist nun ein neues Array. Soweit klar?
Die Konstruktor-Funktion "Array" ist ein nativer Bestandteil von JavaScript. Die kann man so nicht einsehen (probiere doch einmal in der Adresszeile Deines Browsers "javascript:alert(Array)" einzugeben), jedoch kann man den Bauplan eines Arrays grundsätzlich erweitern. Und dazu braucht man "prototype".
~~~javascript
Array.prototype.meineErweiterung = function (param) {
alert(
"Anzahl Elemente im Array: "
+ this.length
+ "\n\nAn dieses Array übergebener Parameter: '"
+ param
+ "'"
);
}
Obige Funktionsdefinition definiert eine Funktion, die einen Parameter in der Variablen "param" entgegennimmt. Im Funktionskörper (oder wie man das zwischen den geschweiften Klammern nennt) steht eine alert-Anweisung, die eine Zeichenkette ausgibt. Diese Zeichenkette wird aus Einzelteilen zusammengesetzt, unter denen auch "this.length" steht. "this" innerhalb einer Funktion verweist grundsätzlich auf das Objekt, dem diese Funktion als Methode angehört. Bei einfachen selbstdefinierten Funktionen ist das das window-Objekt, in diesem Falle das Array-Objekt, dem wir diese Funktion über "prototype" als Methode verliehen haben.
Auch bei selbstdefinierten Objekten kann man den existierenden Bauplan mittels prototype erweitern.
function Auto (farbe) {
this.farbe = farbe;
this.start = function () {
alert("brumm, brumm, brrrrrrrummmmmmmmmmmmm!"
+ " ("
+ this.farbe
+ "er Rauch steigt auf)"
);
};
return this;
}
Auto.prototype.preis = "100000 Euro";
Auto.prototype.motor = "Ottomotor";
var meinAuto = new Auto("grün");
alert(
"Mein Auto ist "
+ meinAuto.farbe // im Konstruktor definierte Eigenschaft
+ " und hat "
+ meinAuto.preis // über prototype hinzugefügte Eigenschaft
+ " gekostet. In ihm läuft ein "
+ meinAuto.motor // im Konstruktor definierte Methode
+ "."
);
meinAuto.start(); // meldet "brumm, brumm, brrrrrrrummmmmmmmmmmmm! (grüner Rauch steigt auf)"
Liebe Grüße,
Felix Riesterer.
Hallo Felix,
recht herzlichen Dank für deine Erklärung und deine Mühe.
Ich finde es schön das es noch Menschen gibt die sich so Zeit nehmen und so toll erklären.
Jetzt ist es mir schon ein wenig klarer.
Ich werde aber mal noch zum vertiefen ein wenig herumspielen mit den Codebeispielen.
liebe Grüsse an alle Helfe
werner
Hallo,
return !!(this.compareDocumentPosition(arg) & 16);
Was aber macht "prototype" und "compareDocumentPosition"?
compareDocumentPosition ist eine Methode aus DOM 3 Core und macht das besagte: Die Position zweier Knoten im Knotenbaum des Dokuments miteinander vergleichen.
knoten1.compareDocumentPosition(knoten2);
Zurückgegeben wird eine Bit-Maske. Die Bits haben folgende Bedeutung (Auszug aus dem Standard mit Hexadezimalzahlen und von mir ergänzt mit Binärzahlen):
DOCUMENT_POSITION_DISCONNECTED = 0x01; // 000001
DOCUMENT_POSITION_PRECEDING = 0x02; // 000010
DOCUMENT_POSITION_FOLLOWING = 0x04; // 000100
DOCUMENT_POSITION_CONTAINS = 0x08; // 001000
DOCUMENT_POSITION_CONTAINED_BY = 0x10; // 010000
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; // 100000
Siehe
http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1950641247
<[link:http://www.w3.org/TR/DOM-Level-3-Core/core.html#DocumentPosition>]
In dem Fall, dass der knoten1 den knoten2 enthält, wird dezimal 20 (binär 10100) zurückgegeben, d.h. die Bits für CONTAINED_BY und FOLLOWING sind gesetzt.
Will ich nun wissen, ob in der Bitmaske das Bit für CONTAINED_BY (dezimal 16, dual 010000) gesetzt ist, mache ich eine Bitweise Maskierung, rechne also das Ergebnis & 16. Im positiven Falle bekomme ich wieder 16 zurück, andernfalls 0.
Das ist eigentlich alles. Mit !! wird das Ergebnis noch in Boolean umgewandelt, damit die Funktion entweder true oder false zurückgibt. Man könnte auch einfach Boolean(...) schreiben.
Mathias
Lieber Cheatah,
Mir ist keine existierende Alternative bekannt.
ist Dir eine Methode bekannt, wie man über Prototypisierung _jedem_ HTML-Element eine Methode verleihen kann? Dann wäre es durchaus möglich, sich diese Funktion selbst zu schreiben und an alle HTML-Elemente per prototype zu vergeben... In etwa so:
HTMLElement.prototype.contains = function (elm) {
for (var p in this) {
if (this[p] === elm)
return true;
}
return false;
}
Liebe Grüße,
Felix Riesterer.
Hi,
Mir ist keine existierende Alternative bekannt.
ist Dir eine Methode bekannt, wie man über Prototypisierung _jedem_ HTML-Element eine Methode verleihen kann?
ja, nämlich etwa so wie Du sie nanntest - aber das ist noch immer keine existierende Alternative, sondern eine Selbst-Implementierung ;-)
Wichtig ist darauf zu achten, dass der IE das (mal wieder) nicht kann. Der Code muss ihm also vorenthalten werden.
In etwa so:
Abgesehen davon, dass "var p in this" zugunsten einer Schleife über "this.getElementsByTagName('*')" weggelassen werden sollte, ist das schon der richtige Weg.
Cheatah
Hallo,
HTMLElement.prototype.contains = function (elm) {
for (var p in this) {
if (this[p] === elm)
return true;
}return false;
}
??? Was soll dieser Code tun? Sieht für mich sehr sinnfrei aus.
Ist hier vielleicht sowas gesucht:
</archiv/2008/7/t173611/#m1140229>
<http://www.quirksmode.org/blog/archives/2006/01/contains_for_mo.html>
Mathias
--
[SELFHTML aktuell Weblog](http://aktuell.de.selfhtml.org/weblog/)
Lieber WernerK,
anscheinend wollte Dir unter dem anderen Threadtitel navi.contains() is not a function???? niemand antworten...
Schön, dass Du doch noch Hilfe findest.
Liebe Grüße,
Felix Riesterer.
Lieber Felix,
ja herzlichen Dank auch für dein Bemühen.
Ich hatte nämlich in dem Zusammenhang diesen Code gefunden der irgendwie das "contains()" auch im Firefox ermöglicht.
Ich wusste nur nicht ob ich meine Frage falsch gestellt hatte.
Aber was solls.
Kannst du event. einem Wissenshungrigen JS Anfänger dies ein wenig erklären?
Was macht denn "prototype" ?
if (window.Node && Node.prototype && !Node.prototype.contains) {
Node.prototype.contains = function (arg) {
return !!(this.compareDocumentPosition(arg) & 16);
};
}
nochmals besten Dank
viele Grüße
Werner