mabue88
Goto Top

Firefox - getElementById() - Object wird als Function zurückgegeben

Hallo,

ich ändere in Javascript das 'data'-Attribute eines objects:

function SetObjectUrl(object_id, url){
	var my_object = document.getElementById(object_id);

	if(typeof my_object === "object"){  
		my_object.setAttribute("data", url);  
		console.log("Update für '" + object_id + "', URL = " + url);  
	}
	else{
		console.log("Falscher Typ von 'my_object': " + typeof my_object);  
	}
}

In Chrome und Internet Explorer wird die aktualisierte Seite korrekt geladen. Im Firefox (36.0) wird die Seite nicht geladen. Das Objekt bleibt einfach leer (weiß).

Hier die Ausgabe aus der Konsole:

Falscher Typ von 'my_object': function  

Also wird das 'object' mit der entsprechenden ID als Funktion eingelesen. Mit Chrome und Internet Explorer wird das 'object' korrekt als 'object' eingelesen.

Weiss jemand warum es im Firefox als 'function' eingelesen wird?

Content-Key: 264651

Url: https://administrator.de/contentid/264651

Printed on: April 25, 2024 at 19:04 o'clock

Member: eisbein
eisbein Feb 26, 2015 at 16:50:18 (UTC)
Goto Top
Hallo!

Nur mal zur Anregung. Wenn schon Javascript verwendet wird, warum dann nicht gleich JQuery oder dergleichen?

Gruß
Eisbein
Member: colinardo
colinardo Feb 26, 2015 updated at 17:11:24 (UTC)
Goto Top
Hallo mabue,
wie sieht das Objekt aus das du im DOM auswählst (welcher Tagtyp im DOM). Kann das Verhalten hier in Firefox testweise nicht nachvollziehen.

Deine Abfrage ist aber eher unzuverlässig. Ich würde eher so prüfen:
if (my_object != null) {
    //.....
}else{
    //....
}
Der Grund: Es wird auch ein (null)Objekt zurückgegeben wenn die ID nicht gefunden wurde. Kannst du überprüfen mit console.log(typeof null)

Grüße Uwe
Member: mabue88
mabue88 Feb 26, 2015 at 18:15:55 (UTC)
Goto Top
Bislang habe ich noch nicht mit JQuery gearbeitet. Wollte mal damit anfangen, aber ergab sich bisher noch nicht.
Vielleicht setzt mich mal dran.

@colinardo:
Mit der unzuverlässigen Abfrage gebe ich dir recht. Das ändere ich ab. Allerdings löst das mein Problem noch nicht.

Hier eine der Object-Zeilen im HTML-Dokument:
<object id="my_id" class="my_class" type="text/html" data="default_page.php"></object>  

Die hier definierte "default_page.php" soll eben dynamisch ersetzt werden.
In der HTML gibt es mehrere Objects, aber alle haben definitiv unterschiedliche IDs.

Getestet habe ich mit Firefox auf zwei unterschiedlichen Rechnern. Bei beiden der gleiche Sachverhalt.
Member: colinardo
colinardo Feb 26, 2015 updated at 18:26:52 (UTC)
Goto Top
Zitat von @mabue88:
In der HTML gibt es mehrere Objects, aber alle haben definitiv unterschiedliche IDs.
Ahh du willst bestimmt den Tagname des Nodes prüfen oder ? Das machst du mit der Eigenschaft nodeName und nicht mit typeof
document.getElementById(object_id).nodeName

Kannst du aber auch mit
var objects = document.getElementsByTagName('object');  
for(i=0;i<objects.length;i++){
  objects[i].setAttribute("data","http://domain.de");  
}
über alle Object-Nodes iterieren ...
Member: mabue88
mabue88 Feb 26, 2015 updated at 18:35:29 (UTC)
Goto Top
Die Abfrage ist nur dafür da, um sicherzustellen, dass auch wirklich ein Objekt mit der entsprechenden ID gefunden wurde.
Wenn das nicht der Fall ist, brauche ich der 'data'-Eigenschaft auch keine neue URL zuweisen.

Sprich: eigentlich nur Fehlervermeidung


Wenn ich jetzt beide Vorschläge von dir zu dem hier kombiniere...
if(my_object != null && my_object.nodeName == "OBJECT"){  
    // Load new URL
}

dann sollte das für die Fehlervermeidung ausreichen, oder?

Habs gerade mal versucht, damit funktioniert es im Firefox...
Member: colinardo
colinardo Feb 26, 2015 updated at 18:36:43 (UTC)
Goto Top
Ja das ist OK bis auf den "case sense" von OBJECT, das kannst du z.B. mit match machen:
if(my_object != null && my_object.nodeName.match(/^object$/i)){
    // Load new URL
}
oder mit toLowerCase()... habe nämlich schon erlebt das die Eigenschaft nicht überall den Tag in Großbuchstaben zurückgegeben hat (komischerweise).
Member: mabue88
mabue88 Feb 26, 2015 at 18:36:35 (UTC)
Goto Top
Ja, "case sense" wird noch "entfernt".

Mit dieser Lösung ist es gerade auch schon vorgekommen, dass die neue URL der 'data'-Eigenschaft zugeweisen wurde, das Object aber die Seite nicht geladen hat!
Das Problem liegt also noch irgendwo anders...
Member: colinardo
Solution colinardo Feb 26, 2015, updated at Mar 04, 2015 at 11:05:55 (UTC)
Goto Top
Das Problem liegt also noch irgendwo anders...
Dazu kenne ich zu wenig von deiner Seite ... vermutlich musst du die Objects erst aus dem DOM entfernen und neu hinzufügen, damit sie Ihre Daten neu laden (gerade zu faul zu testen ;-P).
Member: mabue88
mabue88 Feb 26, 2015 at 18:57:17 (UTC)
Goto Top
Kann ich das wie folgt machen?

- Bestehendes Object mittels ID in Variable schreiben
- Dieses Object im DOM löschen
- Das Object in der Variable anpassen ('data' ändern)
- Das Object in der Variable wieder in das DOM einfügen
Member: colinardo
colinardo Feb 26, 2015, updated at Feb 27, 2015 at 07:59:02 (UTC)
Goto Top

Ich würde das neue Element vorher einfügen (insertBefore), dann hast du noch seine Position im DOM und dann das alte Element löschen.
Member: mabue88
mabue88 Mar 03, 2015 at 09:34:43 (UTC)
Goto Top
Hallo,

ich habe gerade noch etwas festgestellt.

Im Body der Informationsseite habe ich ein onclick-Event definiert: onclick="window.frameElement.click()"
Dadurch wird beim Anklicken der Seite das Click-Event an das (eventuell) darüber liegende Object weitergeleitet und dessen onclick-Event ausgelöst.

Nachdem ich die URL wie beschrieben aktualisiere, funktioniert das mit dem Event nicht mehr. Das Object, in welchem die Informationsseite geladen ist, empfängt das Event nicht mehr.

Ich vermute, dass ich um die von colinardo genannte Methode nicht herum komme...
Member: mabue88
mabue88 Mar 03, 2015 at 17:02:53 (UTC)
Goto Top
Ich hatte gerade noch eine andere Idee, um eine Aktualisierung des Objects im eigentlichen Sinn zu umgehen.

Ist es möglich, von der Seite, in welcher das Object (über das wir reden) enthalten ist, auf eine Javascript-Funktion der im Object geladenen Seite zuzugreifen?

Dann könnte ich die Aktualisierung nämlich durch einen entsprechenden Funktionsaufruf mit Parametern durchführen...
Member: colinardo
colinardo Mar 03, 2015 updated at 17:21:37 (UTC)
Goto Top
Zitat von @mabue88:
Ist es möglich, von der Seite, in welcher das Object (über das wir reden) enthalten ist, auf eine Javascript-Funktion
der im Object geladenen Seite zuzugreifen?
Ja, das geht. Hol dir eine Referenz zum Object, darin gibt es dann die Eigenschaft contentWindow von der aus du alle deine JavaScript-Funktionen aus der Subsite aufrufen kannst.
document.getElementById('myObject').contentWindow.deineFunctionImObject();
Grüße Uwe
Member: mabue88
mabue88 Mar 03, 2015 at 17:34:10 (UTC)
Goto Top
"document.getElementById('myObject').contentWindow" liefert mir ein 'undefined' zurück.

Hauptseite:
<html>
	<head>
		<script type="text/javascript">  
			function CallChildFunction(){
				console.log(document.getElementById("my_object").contentWindow);  
				document.getElementById("my_object").contentwindow.load_func();  
			}
		</script>
	</head>
	<body>
		<object id="my_object" data="load.html"></object>  
		<input type="button" value="Klick" onclick="CallChildFunction()">  
	</body>
</html>

Seite im Object:
<html>
	<head>
		<script type="text/javascript">  
			function load_func(){
				alert("load_func");  
			}
		</script>
	</head>
	<body>
		Page to Load
	</body>
</html>
Member: colinardo
colinardo Mar 03, 2015 updated at 17:49:37 (UTC)
Goto Top
contentwindow
Du hast einen Schreibfehler... es muss contentWindow heißen.
Member: mabue88
mabue88 Mar 03, 2015 at 17:56:59 (UTC)
Goto Top
Da hab ich die "falsche Version" geposted. Dachte auch an einen Schreibfehler und habe verschiedene Schreibweisen von 'contentWindow' getestet. Alle, inkl. 'contentWindow' geben ein 'undefined' zurück...
Member: colinardo
colinardo Mar 03, 2015 updated at 18:01:04 (UTC)
Goto Top
Zitat von @mabue88:
Da hab ich die "falsche Version" geposted. Dachte auch an einen Schreibfehler und habe verschiedene Schreibweisen von
'contentWindow' getestet. Alle, inkl. 'contentWindow' geben ein 'undefined' zurück...
Geht hier einwandfrei ... bitte nicht die IE-Krücke benutzen ...
Im IE musst du es anders machen....
document.getElementById('my_object').contentDocument.parentWindow.deineFunctionImObject();
immer dieser IE grausam ...
Member: colinardo
colinardo Mar 03, 2015 updated at 18:06:15 (UTC)
Goto Top
Du kannst auch mal auf das Laden des Contents im Object warten und daran ein Event binden:
<html>
	<head>
	</head>
	<body>
		<object id="my_object" data="load.html"></object>  
		<script type="text/javascript">  
		document.getElementById('my_object').onload = function (){  
	              this.contentWindow.load_func();
                  };
		</script>
	</body>
</html>
Das geht hier ebenfalls problemlos ...
Member: mabue88
mabue88 Mar 03, 2015 at 18:07:14 (UTC)
Goto Top
Gleiches Ergebnis...
Member: colinardo
colinardo Mar 03, 2015 updated at 18:20:21 (UTC)
Goto Top
sorry hier läufts ... latest Firefox 36 & Chrome (IE ausgenommen s.o.)
Member: colinardo
colinardo Mar 03, 2015 updated at 18:11:53 (UTC)
Goto Top
Siehe dazu auch http://stackoverflow.com/questions/1600488/calling-javascript-function- ...
Hier ist zwar von einem iFrame die Rede, das spielt aber keine Rolle, ist das selbe ...
Member: mabue88
mabue88 Mar 04, 2015 updated at 10:49:36 (UTC)
Goto Top
Also bei mir will das irgendwie nicht funktionieren.

Deswegen bin ich jetzt doch den Weg gegangen, das alte Object aus der HTML zu entfernen und ein neues zu erstellen. Dazu übergebe ich dem neuen Object die Parameter des alten. Lediglich der 'data'-Parameter wird verändert.

Hier die entsprechende Javascript-Funktion:
function UpdateObjectData(object_id, new_data){
	var oo = document.getElementById(object_id);	// oo = old object
	if(oo == null)	return;
	
	document.body.removeChild(oo);
	
	var no = document.createElement("object");		// no = new object  
	no.setAttribute("id", oo.id);  
	no.setAttribute("data", new_data);  
	no.setAttribute("onclick", oo.getAttribute("onclick").toString());  
	no.setAttribute("class", oo.className);  
	
	document.body.appendChild(no);
}
Ich danke euch allen für eure Unterstützung!


PS: Ich habe innerhalb dem Object noch eine andere Problematik, aber dafür werde ich dann wohl bei Bedarf einen neuen Thread erstellen...