caught exception: out of memory
mb
- javascript
anbend, der FireBug spuckt bei mir folgenden ErrorMessage aus: caught exception: out of memory bei diesem Code:
function Fade(elem, array, ms) {
// Variable
this.elem = elem; // Bild
this.array = array; // URLs
this.ms = ms; // Milisekunden
// Methods
this.fading = function() {
var count = 0;
alert(this.elem + "\n" + this.array + "\n" + this.ms);
var stepping = window.setTimeout(function() {
alert(this.elem + "\n" + this.array + "\n" + this.ms);
this.elem.style.backgroundImage = this.array[count];
if (count > array.length) window.clearTimeout();
count++;
}, this.ms);
}
}
beim ersten alert gibt er noch definierte werte an. erst beim zweiter alert gibt der 3 mal undfined aus. Ich hab n konstruktor gebaut mit Bildwechsel. den halben Tag hab ich gegoogel, bis ich herausgefunden hab, das sich die Werte verändern :/ und ich weis nicht wieso. schon mal dank im voraus Liebe Grüße mb
Guten Abend,
function Fade(elem, array, ms) { // Variable this.elem = elem; // Bild this.array = array; // URLs this.ms = ms; // Milisekunden // Methods this.fading = function() { var count = 0; alert(this.elem + "\n" + this.array + "\n" + this.ms); var stepping = window.setTimeout(function() { alert(this.elem + "\n" + this.array + "\n" + this.ms); this.elem.style.backgroundImage = this.array[count]; if (count > array.length) window.clearTimeout(); count++; }, this.ms); } }
beim ersten alert gibt er noch definierte werte an. erst beim zweiter alert gibt der 3 mal undfined aus. Ich hab n konstruktor gebaut mit Bildwechsel. den halben Tag hab ich gegoogel, bis ich herausgefunden hab, das sich die Werte verändern :/ und ich weis nicht wieso.
Bei deinem ersten Alert befindest du dich mit dem Scope bei deinem Fade Object, welches die Eigenschaften elem, array und ms besitzt.
Bei deinem zweiten Alert befindest du dich allerdings mit dem Scope beim window (setTimeout). window besitzt keine der Eigenschaften elem, array oder ms; somit bekommst du undefined zurück.
Du kannst setTimeout Parameter mitgeben: setTimeout(fn(elem, array){}, this.ms, this.elem, this.array);
Der erste Parameter ist für die Funktion, der Zweite gibt die Millisekunden an. Alle weiteren sind optional; falls anwesend werden sie der angegebenen Funktion übergeben.
Vielleicht schaffe ich es später dir noch ein wenig Lektüre dazu mit auf den Weg zu geben. (Vielleicht könnte sich auf jemand anderes darum kümmern - ich bin morgen erst spät wieder da)
Reinhard
Lieber mb,
das Schlüsselwort "this" hat je nach Kontext ganz andere Bedeutungen. Es bezieht sich innerhalb der Funktion, die Du dem setTimeout als ersten Parameter übermittelst, auf das window-Objekt. Die Variable "this" ist daher dort eine völlig andere, als noch zuvor im Scope der fading-Methode.
Hier ist eine übliche Lösung:
Function Fade (elem, array, ms) {
// Variable
this.elem = elem; // Bild
this.array = array; // URLs
this.ms = ms; // Milisekunden
// Methods
this.fading = function () {
var count = 0;
var that = this; // für den setTimeout-Kontext später
var stepping = window.setTimeout(function () {
// that != this!
that.elem.style.backgroundImage = that.array[count];
// [...]
}, this.ms);
};
}
Warum willst Du den Rückgabewert von setTimeout speichern? Die übermittelte Funktion wird eh nur einmal ausgeführt! Da lohnt es sich ja kaum, den timeout wieder zu löschen! Dazu verwendest Du clearTimeout() ohne irgendeine Angabe (das müsste clearTimeout(stepping) heißen!), was mich zu der Frage bringt, was Du da eigentlich tust.
Liebe Grüße,
Felix Riesterer.
Nachtrag:
dass die anonyme Funktion, die dem setTimeout-Aufruf als ersten Parameter übermittelt wird, die Variable "that" überhaupt kennt, liegt an einem sehr mächtigen Sprach-Feature von JavaScript, das man "Closure" nennt. Die Variable "that" wird in der anonymen Funktion sozusagen eingekapselt, sodass sie, wenn denn der Timeout eintritt, den Wert dieser Variablen noch weiß, auch wenn der fading()-Aufruf längst abgearbeitet wurde.
Liebe Grüße,
Felix Riesterer.
dass die anonyme Funktion, die dem setTimeout-Aufruf als ersten Parameter übermittelt wird, die Variable "that" überhaupt kennt, liegt an einem sehr mächtigen Sprach-Feature von JavaScript, das man "Closure" nennt.
stimmt Danke Dir. Ich hab mich mit den Begriffen Closures und that = this schon auseinander gesetzt. Ich komme ursprünglicxh aus der Java Ecke und Closures nehme ich an sind nichts weiter als Private Methoden oder Konstruktoren. Danke euch Reihard und Felix. Ich vermute ich werd SelfHTML noch mal nerven wofür ich mich jetzt schon entschuldige :/. Herzlichste Grüße mb
Hier ist eine übliche Lösung:
Function Fade (elem, array, ms) { // Variable this.elem = elem; // Bild this.array = array; // URLs this.ms = ms; // Milisekunden // Methods this.fading = function () { var count = 0; var that = this; // für den setTimeout-Kontext später var stepping = window.setTimeout(function () { // that != this! that.elem.style.backgroundImage = that.array[count]; // [...] }, this.ms); }; }
Alternativ kann man den this-Kontext von der Callbackfunktion auch an den this-Kontext der äußeren Funktion binden:
var stepping = window.setTimeout(function () {
this.elem.style.backgroundImage = this.array[count];
// [...]
}.bind(this), this.ms);
In der neusten JavaScript-Version gibt es sogar eine verkürzte Funktionsschreibweise, die diesen Schritt obsolet macht:
var stepping = window.setTimeout(() =>
this.elem.style.backgroundImage = this.array[count];
// [...]
}, this.ms);
Eine radikalere Lösung besteht darin, this vollständig zu vermeiden und mit Factories anstatt mit Konstruktoren zu arbeiten:
function createFade (elem, array, ms) {
function fading () {
var count = 0;
var stepping = window.setTimeout(function () {
elem.style.backgroundImage = array[count];
// [...]
}, ms);
}
return { fading }; //ES2015 Syntax, für ES5.1: return { fading : fading }
}
Und nur so zum Spaß noch eine funktionale Variante ohne veränderliche Zustandsvariablen, dafür mit Promises, um den Kontrollfluss zu modellieren:
function reduceWithDelay (fn, array, delay) {
return array.reduce((lastPromise,nextElement) =>
new Promise(resolve =>
lastPromise.then(()=>setTimeout(()=>{
fn(nextElement)
resolve();
}, delay))
), (new Promise(resolve=>resolve())));
}
const animation = reduceWithDelay(color=>document.body.style.backgroundColor=color, ['red','green'], 1000);
animation.then(()=>console.log('Animation fertig'));
http://jsfiddle.net/sftvptzv/ (getestet mit Chrome)
schöne Lösungen 1unitedpower :) und ich werds mir ansachauen, aber das hilft bei diesem Problem nicht weiter :/.
Erst einmal herzlichen Dank. Mir ist jetzt einiges im quellcode klar geworden. das mit dem setTimeout und mit der übergabe funzt jetzt.
function Fade(elem, array, ms) {
// Variable
this.elem = elem;
this.array = array;
this.ms = ms;
// Methods
this.fading = function() {
var that = this;
var count = 0;
var stepping = window.setInterval(function () {
if (count >= array.length -1) {
window.clearInterval(stepping);
that.elem.style.display = "none";
} else {
that.elem.style.backgroundImage = "" + that.array[count];
count++;
}
alert(that.elem.style.backgroundImage + "\n" + that.array[count] + "\n" + that.ms + "\n" + count);
}, this.ms);
}
}
aber ich habe immer noch das problem mit
uncaught exception: out of memory
beim alert gibt er mir seh schon alle paraqmeter zurück auch die URLs, aber that.elem.style.backgroundImage ist leer und bei der HTML-Ausgabe auche ich n leeren String bei Style obwohl er mir style im HTML als Attribut angelegt hat. nur leer eben :/. am ender des setTimeout() kommt display: none was ja korrekt war;
<div id="screen" style=""></div>
Meine leihenhafte vermutung das irgendwas mit der übergabe vom array net stimmt. alles andere habe ich überprüft.
ach ja für die lösung des problem sollte ich den externen Quellcode dazu schreiben
<script type="text/javascript" src="lib/js/fade.js"></script>
<script type="text/javascript">
window.onload = function() {
var fade_1000 = "../../media/images/fade_1000.png",
fade_875 = "../../media/images/fade_875.png",
fade_750 = "../../media/images/fade_750.png",
fade_625 = "../../media/images/fade_625.png",
fade_500 = "../../media/images/fade_500.png",
fade_375 = "../../media/images/fade_375.png",
fade_250 = "../../media/images/fade_250.png",
fade_125 = "../../media/images/fade_125.png",
fade_0 = "../../media/images/fade_0.png",
imageFade = new Array(fade_1000, fade_875, fade_750, fade_625, fade_500, fade_375, fade_250, fade_125, fade_0);
var elem = document.getElementById("Screen");
var sceenFade = new Fade(Screen, imageFade, 125);
ScreenFade.fading();
}
</script>
die Bilder sind n pixel groß und wiederholen sich immer wieder im <div>-Conainer wenns funzt :/
Hallo mb,
var elem = document.getElementById("Screen"); var sceenFade = new Fade(Screen, imageFade, 125); ScreenFade.fading();
ist hier evtl. ein Fehler drin? Vergleiche elem
und Screen
bzw. sceenFade
und ScreenFade
.
Gruß, Dennis
hallo dennis
ist hier evtl. ein Fehler drin? Vergleiche
elem
undScreen
bzw.sceenFade
undScreenFade
.
ich habs veränder zum besseren Verständnis. Alles ist richtig implementiert. das problem ist weinzig ud allein
that.elem.style.backgroundImage = "" + that.array[count];
Der Übergabe Array mit URLs funzt, Style in JavaScript auch aber die Übergabe der Style-Elemente net :(
Morgen,
this.fading = function() { if (count >= array.length -1)
Wenn ich das richtig sehe, dann liegt hier das Problem. Du hast in der Funktion keine Variable array definiert. Versuche es mal mit that.array.length
.
Reinhard
Morgen Reinhard, leider nicht. Gute idee das mit that.array -1. hab korrigiert aber ist der selbe Fehler
this.fading = function() { if (count >= array.length -1)
Wenn ich das richtig sehe, dann liegt hier das Problem. Du hast in der Funktion keine Variable array definiert. Versuche es mal mit
that.array.length
.
that.array[count];
is n Array mit den URL-Werten und ich kann drauf zugreifen
that.elem.style.backgroundImage = "" + that.array[count];
das <div>-Tag "elem" in JavaScript Variable erzeugt ein Style-Attribut aber leer :/ leer obwohl ich die URLs übergeben habe
alert(that.elem.style.backgroundImage);
gibt nix aus. Es ist leer in jedem URL-Sting vom Array :(
Morgen,
also, ich habe mir einen Augenblick genommen um deinen Fader zu testen.
Immer schön auf Groß- und Kleinschreibung achten, dann sollte es auch funktionieren.
<div id="screen"></div>
#screen {
width: 100%;
height: 60vh;
background-color: #06F;
border: 3px solid #F00;
}
function Fade(elem, array, ms) {
this.elem = elem;
this.array = array;
this.ms = ms;
this.fading = function() {
var that = this,
count = 0,
stepping = setInterval(function() {
if (count >= that.array.length)
{
clearInterval(stepping);
that.elem.style.display = 'none';
}
else
that.elem.style.backgroundImage = 'url(' + that.array[count++] + ')';
}, this.ms);
};
}
document.addEventListener('DOMContentLoaded', function() {
var elem = document.getElementById('screen'),
array = ['chrome://global/skin/media/imagedoc-darknoise.png', 'chrome://global/skin/media/imagedoc-lightnoise.png'];
array.push.apply(array, array.slice());
array.push.apply(array, array.slice());
var fader = new Fade(elem, array, 2000);
fader.fading();
});
Den Inhalt von array (chrome://global …) einfach mit deinen URL's austauschen.
array.push.apply(array, array.slice());
vervielfältigt lediglich den Inhalt von array. Habe ich zum testen verwendet. Kannst du weglassen.
Reinhard
Guten Mittag,
ich bin mit alert() und firebug intensiv auf fehlersuche gegangen. alles läuft alles ok nur die übergabe an das style-Element läuft was schief. wenn da nur ne referenz auftauche würde wäre ja alles ok, aber das ist noch nicht einmal der Fall. alles was ich sehe nachdem ich diesen Befehl
document.getElementById("htmlObjekt");
htmlObjekt.style.backgroundImage = "nBild.png";
ausgeführt habe ist
<div id="htmlObjekt" style=""></div>
und kann es auch so lauten wie du es geschrieben hast?
htmlObjekt.style.backgroundImage = url( + "nBild.png" + );
viele Grüße mb
Guten Abend,
htmlObjekt.style.backgroundImage = url( + "nBild.png" + );
Wenn du kein <img> benutzen möchtest, sondern background-image, so musst du es - wenn schon denn schon - so aufschreiben:
htmlObjekt.style.backgroundImage = "url(" + _bildpfad_ + ")";
Was stimmt denn nicht mit dem Beispiel, das ich dir gegeben habe?
Wenn du das ganze lokal ausprobierst musst du ggf. vor dem Pfad ein file:/// anführen.
Reinhard
htmlObjekt.style.backgroundImage = "url(" + _bildpfad_ + ")";
ja stimmt, mir fällts wieder ein. Das Problem besteht immernoch das JavaScript im Stye-Element die URLs nicht übergibt :/
Was stimmt denn nicht mit dem Beispiel, das ich dir gegeben habe?
Alles gut. ich hab mich nur etwas falsch ausgedrückt. tschuldige bitte. Ich vermute mal das ist n syntaxtischer fehler irgendwo in meinem Code-konstrukt. Ich melde mich wenn ichs gelöst habe. matrial und beispiele habe ich ja dank euch. Guten Abend, mb
Abend allerseits,
htmlObjekt.style.backgroundImage = "url(" + _bildpfad_ + ")";
komischerweise gehts jetzt wegen eines einzigen semikolons.
htmlObjekt.style.backgroundImage = "url(" + _bildpfad_ + ");";
Ich danke euch - dir Reinhard - sehr. Schönen Abend mb