JavaScript - Funktion in/aus XML Datei ausführen
zipdrive
- xml
Hallo, ich lade mir mit Ajax eine Datei und erhalte über responseXML die Daten aus der XML. In dieser XML definiere ich mir einen Scriptbereich, via <script type="text/javascript">...</script> aus dem default NS, in dem eine Funktion, nennen wir sie test, definiert wurde. Wenn ich den Namen kenne, wie kann ich die Funktion im selben Dokument ausführen und die returnten Daten in einem anderen Javascriptbereich, aus einem anderen Dokument entgegennehmen?
Ich hoffe doch, dass das irgendwie crossbrowsertechnisch geht?
MfG
Hallo,
In dieser XML definiere ich mir einen Scriptbereich, via <script type="text/javascript">...</script> aus dem default NS, in dem eine Funktion, nennen wir sie test, definiert wurde. Wenn ich den Namen kenne, wie kann ich die Funktion im selben Dokument ausführen und die returnten Daten in einem anderen Javascriptbereich, aus einem anderen Dokument entgegennehmen?
Sehr obskure Sachen machst du da... ;) Könntest du das für mich noch einmal gedanklich ordnen?
»Wie kann ich die Funktion im selben Dokument ausführen«: Erst einmal gar nicht, du kannst den Browser nicht dazu bekommen, das script-Element wie ein script-Element im HTML-Dokument zu behandeln. Du kannst höchstens den Textinhalt des Elementes auslesen und diesen Code mit eval() ausführen. (Das ist ungefähr der allerübelste Stil, den man in JavaScript programmieren kann, aber anders gehts nicht.) Dann ist die Funktion im aktuellen globalen Geltungsbereich deklariert und du kannst sie regulär aufrufen.
Wenn du Script nachladen willst, dann tu dies, indem du ein script-Element dynamisch erzeugst, einbindest und damit eine externe JavaScript-Ressource lädst. Hilft dir vielleicht JSONP weiter, um ein besseres Konzept zu erarbeiten?
Mathias
Hallo molily.
»Wie kann ich die Funktion im selben Dokument ausführen«: Erst einmal gar nicht, du kannst den Browser nicht dazu bekommen, das script-Element wie ein script-Element im HTML-Dokument zu behandeln. Du kannst höchstens den Textinhalt des Elementes auslesen und diesen Code mit eval() ausführen. (Das ist ungefähr der allerübelste Stil, den man in JavaScript programmieren kann, aber anders gehts nicht.) Dann ist die Funktion im aktuellen globalen Geltungsbereich deklariert und du kannst sie regulär aufrufen.
Darüber habe ich mir gerade ein paar Gedanken gemacht und bin bei folgendem gelandet:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript">
window.onload = function() {
var c = document.getElementsByTagName('code')[0];
var h = document.getElementsByTagName('head')[0]
var s = document.createElement('script');
s.type = 'text/javascript';
s.appendChild(document.createTextNode(c.firstChild.nodeValue));
h.appendChild(s);
try {
foo()
} catch(e) {}
}
</script>
</head>
<body>
<pre><code>function foo() {
alert('Hallo Welt');
}</code></pre>
</body>
</html>
Was hältst du davon? Natürlich könnten die Zeichendaten, die hier aus dem code–Element stammen ebenso gut aus dem responseText bzw. responseXML geholt werden. Als funktionstüchtig hat sich die Methode in Opera, Firefox und Konqueror erwiesen. Nur der IE streikt und meldet „Unerwarteter Aufruf oder Zugriff“. Eine Idee?
Einen schönen Samstag noch.
Gruß, Mathias
Hallo,
Was hältst du davon?
Abstand ;-) Siehe http://forum.de.selfhtml.org/archiv/2006/6/t131082/#m847712
Natürlich könnten die Zeichendaten, die hier aus dem code–Element stammen ebenso gut aus dem responseText bzw. responseXML geholt werden. Als funktionstüchtig hat sich die Methode in Opera, Firefox und Konqueror erwiesen. Nur der IE streikt und meldet „Unerwarteter Aufruf oder Zugriff“. Eine Idee?
Ja
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript">
window.onload = function() {
var c = document.getElementsByTagName('code')[0];
var h = document.getElementsByTagName('head')[0]
var s = document.createElement('script');
s.type = 'text/javascript';
h.appendChild(s);
s.text = c.firstChild.nodeValue;
try {
foo()
} catch(e) {}
}
</script>
</head>
<body>
<pre><code>function foo() {
alert('Hallo Welt');
}</code></pre>
</body>
</html>
Siehe auch http://forum.de.selfhtml.org/archiv/2006/6/t131082/#m847831 und zu HTMLScriptElement.text siehe http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html#ID-81598695.
viele Grüße
Axel
Hallo Axel.
Was hältst du davon?
Abstand ;-) Siehe http://forum.de.selfhtml.org/archiv/2006/6/t131082/#m847712
Durchaus berechtigt, ja. Aber für den Fall, dass das Nachladen von Programmcode doch einmal erforderlich ist, ist es gut, eine funktionstüchtige Möglichkeit zu haben.
[…] Nur der IE streikt und meldet „Unerwarteter Aufruf oder Zugriff“. Eine Idee?
Ja
[…]Siehe auch http://forum.de.selfhtml.org/archiv/2006/6/t131082/#m847831 und zu HTMLScriptElement.text siehe http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/html.html#ID-81598695.
Sehr interessant. Damit funktioniert es in fast allen mir zur Verfügung stehenden JS–fähigen Browsern. Lediglich mac:ie und Safari wollen nicht. Ersterer kennt offenbar noch keine Form des XMLHttpRequest–Objektes und zweiterer gibt folgendes als Fehler aus:
error[name] = TypeError
error[message] = Object (result of expression foo) does not allow calls.
error[message] = Object (result of expression foo) does not allow calls.¹
error[line] = 94
error[sourceURL] = http://dev.noctus.net/ajax/simple.htm
Fügt man den Inhalt des Scriptelementes jedoch per appendChild ein, verrichtet auch er sein Werk. So wie ich das mitbekommen habe, kennt Safari ab Version 1.3 HTMLScriptElement.text nicht mehr. (Version 1.2 soll sie noch kennen.)
Es ergibt sich also folgendes:
Browser | appendChild(document.createTextNode()) | text
-----------------+----------------------------------------+-------
Opera 9 | JA | JA
-----------------+----------------------------------------+-------
Firefox 1.5.0.6 | JA | JA
-----------------+----------------------------------------+-------
Konqueror 3.5.4 | JA | JA
-----------------+----------------------------------------+-------
IE 5 | NEIN | JA
-----------------+----------------------------------------+-------
IE 5.5 | NEIN | JA
-----------------+----------------------------------------+-------
IE 6 | NEIN | JA
-----------------+----------------------------------------+-------
Safari 1.3 | JA | NEIN
-----------------+----------------------------------------+-------
Mehr steht mir momentan nicht zur Verfügung, sollte also irgendwer über einen einigermaßen gängigen Browser verfügen, welcher noch nicht hier aufgeführt ist, würde ich mich über Testresultate meines Testfalls freuen.
Einen schönen Samstag noch.
Gruß, Mathias
¹ Ja, wirklich zweimal.
Hallo Mathias.
Es ergibt sich also folgendes:
Browser | appendChild(document.createTextNode()) | text
-----------------+----------------------------------------+-------
Opera 9 | JA | JA
-----------------+----------------------------------------+-------
Firefox 1.5.0.6 | JA | JA
-----------------+----------------------------------------+-------
Konqueror 3.5.4 | JA | JA
-----------------+----------------------------------------+-------
IE 5 | NEIN | JA
-----------------+----------------------------------------+-------
IE 5.5 | NEIN | JA
-----------------+----------------------------------------+-------
IE 6 | NEIN | JA
-----------------+----------------------------------------+-------
Safari 1.3 | JA | NEIN
-----------------+----------------------------------------+-------
Ergänzung: Opera 8.54 verhält sich zu seinem Nachfolger und Mozilla 1.7.3 zu Firefox identisch. In Bezug auf Gecko sind somit also nur noch Versionen < 1.7 und > 1.8 relevant.
Einen schönen Sonntag noch.
Gruß, Mathias
Hallo Mathias,
In Bezug auf Gecko sind somit also nur noch Versionen < 1.7 und > 1.8 relevant.
Mozilla 1.6: ja / ja
Grüße
Roland
Hallo Orlando.
In Bezug auf Gecko sind somit also nur noch Versionen < 1.7 und > 1.8 relevant.
Mozilla 1.6: ja / ja
OK, damit ist Gecko 1.6 auch abgedeckt. Danke.
Einen schönen Sonntag noch.
Gruß, Mathias
Hallo nochmal.
In Bezug auf Gecko sind somit also nur noch Versionen < 1.7 und > 1.8 relevant.
Mozilla 1.6: ja / ja
OK, damit ist Gecko 1.6 auch abgedeckt. Danke.
So, ich habe jetzt auch bis zu Gecko 1.2b (enthalten im Phoenix 0.1) getestet und in allen funktionieren beide Methoden.
Einen schönen Sonntag noch.
Gruß, Mathias
Also was ich da möchte steht im Zusammenhang mit einer XML Datenbank, dessen Files einen Scriptbereich haben, die bestimmen, wie sie auszulesen sind.
Das geht bestimmt auch einfacher, wenn ich in einem "normalen" HTML Dokument eine Fkt. definieren kann man sie doch schließlich auch im DOMInspector sehen.
Naja mal schauen, was so die ECMA dazu meint.
Also was ich da möchte steht im Zusammenhang mit einer XML Datenbank, dessen Files einen Scriptbereich haben, die bestimmen, wie sie auszulesen sind.
Das geht bestimmt auch einfacher, wenn ich in einem "normalen" HTML Dokument eine Fkt. definieren kann man sie doch schließlich auch im DOMInspector sehen.
Naja mal schauen, was so die ECMA dazu meint.
Im DOMInspector unter defaultView. Kann man nicht einfach eine virtuelle defaultView Instanz der XML erstellen? Mensch jetzt wirds abenteurlich!
Hallo,
Im DOMInspector unter defaultView. Kann man nicht einfach eine virtuelle defaultView Instanz der XML erstellen? Mensch jetzt wirds abenteurlich!
Häh?
defaultView ist eine Referenz auf das window-Objekt.
Ja, globale Funktionen hängen am window-Objekt.
XML-Dokumente, die du mit XMLHttpRequest lädst, haben kein window-Objekt. Nur wirkliche Dokumente, die im Browsre dargestellt werden, haben window-Objekte.
Der JavaScript-Code in diesem XML-Dokumenten wird nicht automatisch ausgeführt. Das steht fest.
Mathias
Hallo,
Darüber habe ich mir gerade ein paar Gedanken gemacht und bin bei folgendem gelandet:
Oh, ich dachte, genau das ginge nicht, nur das Einbinden von externen Scripten. Danke für die Ergänzung.
Mathias