TypeError: obj.style is undefined
Linuchs
- javascript
0 Christian Kruse0 Linuchs
0 Tabellenkalk0 dedlfix0 dedlfix
3 Orlok
Moin,
nach dem Laden eines Bildes möchte ich es ansprechen. Warum kann ich keinen style zuweisen?
<img id=utkiek class=webcam style="display:block" src="http://utkiek.vege.net/record/current.jpg">
window.addEventListener('load', function ( ) {
// Web-Bilder finden
obj = document.getElementsByClassName( "webcam" );
alert ( "[" +obj.length +"] Web-Bilder" ); // meldet 1 Bild
for ( i=0; i<obj.length; i++ ) {
obj.style.border = "1px solid #000";
obj.style.padding = "2px";
}
});
Fehlermeldung: TypeError: obj.style is undefined
Linuchs
Hallo Linuchs,
window.addEventListener('load', function ( ) { // Web-Bilder finden obj = document.getElementsByClassName( "webcam" ); alert ( "[" +obj.length +"] Web-Bilder" ); // meldet 1 Bild for ( i=0; i<obj.length; i++ ) { obj.style.border = "1px solid #000"; obj.style.padding = "2px"; } });
Fehlermeldung: TypeError: obj.style is undefined
Es fehlt der Index. obj.style
vs obj[i].style
.
LG,
CK
Es fehlt der Index.
obj.style
vsobj[i].style
.
Au weia ... Brett vorm Kopf. Danke.
Linuchs
Hallo,
Warum kann ich keinen style zuweisen?
Weil obj nicht dein Bild ist, sondern die Liste deiner Bilder.
Gruß
Kalk
Tach!
nach dem Laden eines Bildes möchte ich es ansprechen. Warum kann ich keinen style zuweisen?
Eine HTMLCollection hat keine Eigenschaft style.
obj = document.getElementsByClassName( "webcam" ); for ( i=0; i<obj.length; i++ ) { obj.style.border = "1px solid #000";
Anscheinend weißt du ja, dass getElementsByClassName() sowas ähnliches wie ein Array liefert, aber du sprichst die einzelnen Elemente nicht an.
dedlfix.
Tach!
Browser haben Entwicklertols eingebaut. Wenn man den Fehler nicht durch Code-Betrachten erkennt, kann man immerhin nachschauen, was wirklich in einer Variable enthalten ist.
dedlfix.
Hallo Linuchs
window.addEventListener('load', function ( ) { // Web-Bilder finden obj = document.getElementsByClassName( "webcam" ); alert ( "[" +obj.length +"] Web-Bilder" ); // meldet 1 Bild for ( i=0; i<obj.length; i++ ) { obj.style.border = "1px solid #000"; obj.style.padding = "2px"; } });
Abgesehen von dem, was die anderen bereits gesagt haben: Mir ist in deinem Code aufgefallen, sowohl in diesem Thread also auch im Letzten, dass du offenbar jede Menge globale Variablen produzierst, da du konsequent das Schlüsselwort var
auslässt.
// globale Variable obj obj = document.getElementsByClassName( "webcam" ); // globale Variable i for ( i=0; i<obj.length; i++)
Jede Zuweisung die du vornimmst ohne die Variable lokal zu deklarieren erzeugt eine globale Variable, also eine Eigenschaft des Objektes window
, womit du völlig unnötig das Risiko von Namenskonflikten schaffst. Das heißt, du solltest deine Variablen vor der Verwendung immer deklarieren, also bei der Erzeugung der Variable das Schlüsselwort var
notieren.
var obj = document.getElementsByClassName('webcam');
for (var i = 0; i < obj.length; i ++) // ...
Um dich dagegen zu schützen, versehentlich globale Variablen zu produzieren, kannst und solltest du dein Programm – oder zumindest einzelne Funktionen – im Strict Mode ausführen. Wenigstens in der Entwicklungsphase. Wenn du dann das Schlüsselwort var
vergisst wird eine Ausnahme geworfen und du kannst den Fehler sofort korrigieren.
function safe ( ) {
'use strict';
foo = 42;
}
safe( ); // Error - assignment to undeclared variable foo
Gruß,
Orlok
Hallo Orlok
Jede Zuweisung die du vornimmst ohne die Variable lokal zu deklarieren erzeugt eine globale Variable, also eine Eigenschaft des Objektes
window
, womit du völlig unnötig das Risiko von Namenskonflikten schaffst. Das heißt, du solltest deine Variablen vor der Verwendung immer deklarieren, also bei der Erzeugung der Variable das Schlüsselwortvar
notieren.
Danke für den Hinweis.
Da ich oft mehrere Javascript-Dateien einbinde, sollte ich wohl auch deren "globale" Variablen - die ja dann auch für die anderen Skripte gelten - mit einem Vornamen versehen, also web_imgUrl statt imgUrl in der Datei webcam.js.
function safe ( ) { 'use strict'; foo = 42; } safe( ); // Error - assignment to undeclared variable foo
Danke auch für den Tipp, habe ich schon ausprobiert.
Linuchs
Hallo Linuchs,
Da ich oft mehrere Javascript-Dateien einbinde, sollte ich wohl auch deren "globale" Variablen - […] - mit einem Vornamen versehen,
Nö. Auf globale Variablen verzichten.
- die ja dann auch für die anderen Skripte gelten -
Wenn verschiedene Skripte auf dieselbe Variable zugreifen sollen, müssen es tatsächlich globale Variablen sein, falls du sie nicht als Parameter übergeben kannst. Dann kannst du sie aber auch als window.linuchs_foo
anlegen, da sieht dann jeder, wies gemeint ist.
Bis demnächst
Matthias
Hallo Matthias,
Da ich oft mehrere Javascript-Dateien einbinde, sollte ich wohl auch deren "globale" Variablen - […] - mit einem Vornamen versehen,
Nö. Auf globale Variablen verzichten.
Wie soll das denn gehen, wenn mehrere Funktionen in einer .js Datei dieselben Variablen brauchen?
Soweit ich weiss, kann man z.B. setTimeout für die aufgerufene Funktion keine Variablen mitgeben, die müssen also schon mal global sein.
Oder gibt es "regionale" Variablen, die nur in einer .js Datei gelten?
Linuchs
Hallo
Da ich oft mehrere Javascript-Dateien einbinde, sollte ich wohl auch deren "globale" Variablen - […] - mit einem Vornamen versehen,
Nö. Auf globale Variablen verzichten.
Wie soll das denn gehen, wenn mehrere Funktionen in einer .js Datei dieselben Variablen brauchen?
Warum stellst du hier diese Frage, die Matthias im von dir nur teilweise zitierten Vorposting einen Absatz später beantwortet?
Zitat: „Wenn verschiedene Skripte auf dieselbe Variable zugreifen sollen, müssen es tatsächlich globale Variablen sein, falls du sie nicht als Parameter übergeben kannst.“
Das heißt im Umkehrschluss aber auch, dass Variablen, die nicht von verschiedenen Skripten geteilt werden sollen, nicht global sein müssen und sollen. Das trifft meist für den überwiegenden Teil der Variablen zu.
Tschö, Auge
Tach!
Soweit ich weiss, kann man z.B. setTimeout für die aufgerufene Funktion keine Variablen mitgeben, die müssen also schon mal global sein.
Da weißt du nicht ganz richtig: MDN zu setTimeout(). Allerdings ist die erste Form nicht in älteren IEs verfügbar. Aber auch dann gibt es keinen Zwang, globale Variablen zu verwenden.
Oder gibt es "regionale" Variablen, die nur in einer .js Datei gelten?
Scope, nicht Datei, ist das richtige Stichwort, beispielsweise IIFE. Aber auch jede "normale" Funktion bildet einen Scope. Und sich darin neben dem setTimeout() auch die Callback-Fuktion befindet, so hat man darin Zugriff auf alle Variablen in diesem Scope.
dedlfix.
Dafür musst Du nicht zur "Konkurrenz" verweisen ;-).
Das steht - naja, nicht ganz so ausführlich - auch bei uns: setTimeout. Ich habe den Eintrag gerade noch um einen IE Hinweis erweitert.
Ja, sowas wie regionale Variablen gibt es. Die Funktionen, die Du in der .js hast, sind dann allerdings auch regional. Wenn Du das nicht willst, brauchst Du EIN globales Objekt, an das Du die Funktionen als Eigenschaften anklebst.
Schau Dir im Wiki mal das Revealing Module Pattern an.
Gruß Rolf
Nö. Auf globale Variablen verzichten.
Wie soll das denn gehen, wenn mehrere Funktionen in einer .js Datei dieselben Variablen brauchen?
Neben der bereits von den anderen skizzierten "best practice" ein Kompromissvorschlag, wie Du bei Deinen globalen Variablen bleiben kannst und dabei weitgehend die Verschmutzung des globalen Namensraums vermeiden kannst: pack einfach alles in eine globale Variable:
window.linuchsGlobals = window.linuchsGlobals || {};
window.linuchsGlobals.ersteVar = 15;
window.linuchsGlobals.zweiVar = 'foo';
window.linuchsGlobals['foo'] = 'bar';
Dann hast Du weiterhin überall globalen Zugriff, aber den globalen Namensraum selber immerhin nur mit einer Variablen verschmutzt: "linuchsGlobals".