I am getting a TYPE: Mismatch error in IE8 with the following code.
function showTabs() {
for (var i = 0; i < tabs.length; i++) {
tabs[i].style.display = "inline-block";
if (tabs[i]) {
console.log(tabs[i] + " " + i);
}
}
}
function showThumbBoxes() {
for (var i = 0; i < thumbsContainers.length; i++) {
thumbsContainers[i].style.display = "block";
if (thumbsContainers[i]) {
console.log(thumbsContainers[i] + " " + i);
}
}
}
function loadImages() {
for (var i = 0; i < lazyImages.length; i++) {
if (lazyImages[i].getAttribute("data-src")) {
lazyImages[i].src = lazyImages[i].getAttribute("data-src");
if (lazyImages[i]) {
console.log(lazyImages[i] + " " + i);
}
}
}
}
function hideContainers() {
for (var i = 0; i < hiddenContainers.length; i++) {
hiddenContainers[i].style.display = "none";
if (hiddenContainers[i]) {
console.log(hiddenContainers[i] + " " + i);
}
}
}
function setUpPage() {
showTabs();
showThumbBoxes();
loadImages();
hideContainers();
}
if (window.addEventListener) {
window.addEventListener("load", setUpPage())
} else {
window.attachEvent("load", setUpPage()); <<< Here seems to be causing issues.
}
I have steppped through the code and it goes through everything correctly and everything gets loaded to the page. After I step through the last curly brace of setUpPage function, it is back on the attachEvent("load", setUpPage()); When I click step through again, I get the mismatch error. Not sure what is going on but because of the error the rest of my script will not load.
Anyone have an idea?
With attachEvent you need to add on + name of the event, so the event will be called onload
UPDATE
Also the second parameter of both of the event listeners, are callbacks, so they get executed when the event is triggered.
To be able to achieve that, you need to remove the parenthesis of the function call.
Related
function updateScreen() {
var textOutput = "";
setScreen("yellowScreen");
for (var i=0; i < finalColor.length; i++){
var newIndex = i+1;
textOutput = (((textOutput + newIndex +". NAME: " +finalName[i] + ", "
+ "scientific name is") + finalScientificName[i] + ", " + "this bird is
")+ finalConservationStatues[i] + "and they eat ")+ finalDiet[i]+"\n\n";
}
setText("yellowOutput", textOutput);
console.log(textOutput);
}
onEvent("yellowButton", "click", function( ) {
yellowFilter();
upDateScreen();
});
the function yellowFilter prevents anything else to run
function yellowFilter() {
for (var i = 0; color.length; i++) {
if (color[i] == 'Yellow' ) {
appendItem(finalColor, color[i]);
appendItem(finalDiet, diet[i]);
appendItem(finalConservationStatues, conservationStatus[i]);
appendItem(finalScientificName, scientificName[i]);
appendItem(finalName, Name[i]);
console.log(finalColor);
}
}
}
is there anything wrong with these functions the update screen function doesn't run if the yellowFilter runs but yellowFilter needs to run so that upDateScreen can run properly
Without actually going through anything I see one error immediately:
for (var i = 0; color.length; i++)
The second statement in a for loop needs to be a conditional
I actually want to update my previous question Javascript understanding return because the code below is quite similar to the previous one but since that question was answered already I decided to post this. The code of my previous questions works fine already but I want to satisfy some of my curiosities so I experimented the code and moved the return namePosition,
function positionIdentifier(name, nameArray) {
var namePosition;
for (i = 0; i < nameArray.length; i++) {
if (nameArray[i] == name) {
namePosition = function() {
alert("Your name is in position number " + (i + 1));
}
}
}
return namePosition;
}
name1Array = ["look", "sky", "walk", "kier"];
positionIdentifier("walk", name1Array)();
Why does it alert the wrong position (i+1)? Instead it alerts the final position which is the length of the array.
You forgot to use break statement here is correct code:
<script>
function positionIdentifier(name, nameArray) {
var namePosition;
for (i = 0; i < nameArray.length; i++) {
if (nameArray[i] == name) {
namePosition = function () {
alert("Your name is in position number " + (i + 1));
};
break;
}
}
return namePosition;
}
name1Array = ["look", "sky", "walk", "kier"];
positionIdentifier("walk", name1Array)();
</script>
That my friend is what is called a closure in javascript.
function() {
alert("Your name is in position number " + (i + 1));
}
When positionIdentifier function is invoked, i has the last value from the for loop.
To fix this you need to do this
function positionIdentifier(name, nameArray) {
var namePosition;
for (i = 0; i < nameArray.length; i++) {
if (nameArray[i] == name) {
/* now this will keep the correct value of i */
namePosition = (function(i) {
return function(){
alert("Your name is in position number " + (i + 1));
}
})(i)
/* now this will keep the correct value of i */
}
}
return namePosition;
}
Here is a working fiddle https://jsfiddle.net/uxyot51b/
I have a for-loop that is terminating without finishing the loop. It seems to be related to whether or not a call to another function is made within the loop.
this.cycle = function() {
var list = this.getBreaches("Uncontained");
if (list.length > 0) {
for (i=0; i < list.length; i++) {
this.saveVsRupture(DC=11, i); //calls this.rupture() if save failed
}}
return 1;
};
this.saveVsRupture() calls a function that rolls a d20 and checks the result. If the save fails, it calls a method called this.rupture() that does some adjusting to this.
Problem
If the saving throw is successful, the loop continues, but if the saving throw fails, it runs the this.rupture() function and then breaks the for-loop. It should keep running the for-loop.
Why is this happening?
Additional Details
Here are the other functions...
savingThrow = function(DC=11) {
// DC = Difficulty Check on a d20
try {
if (0 <= DC) {
var roll = Math.floor((Math.random() * 20))+1; //roll d20
var msg = "(Rolled "+roll+" vs DC "+DC+")";
console.log(msg);
if (roll >= DC) { //Saved
return true;
}
else { //Failed save
return false;
}
}
}
catch(e) {
console.log("Exception in savingThrow: "+e);
};
};
this.saveVsRupture = function(DC=1, i=null) {
try {
if (!savingThrow(DC)) {
this.rupture(i);
return false;
}
return true;
}
catch(e) {
console.log(e);
}
};
this.rupture = function(i=null) {
if (i == null) {
i = range(1,this.damageList.length).sample();
}
var hole = this.damageList[i];
var dmg = range(1,this.harmonics()).sample();
hole.rupture(dmg);
msg = "*ALERT* " + hole + " expanded by " + dmg + "% Hull Integrity #"+this.hullIntegrity();
this.log(msg);
if (hole.size % 10 == 0) {
this.health -= 25;
msg = "The ship creaks ominously.";
this.log(msg);
}
return 1;
};
The correct syntax for the for-loop declares the counter variable.
for (var i=0; i < list.length; i++) {etc..
/// Causes the For-Loop to exit prematurely...
for (i=0; i < list.length; i++) {etc..
Once the "var i=0" is used, the for-loop operates as expected.
consider implementing a try-catch in your for loop, with your saveVsRupture function within the try. This implementation will catch errors in your function but allow the program to keep running.
Change the saveVsRupture function like this:
function saveVsRupture(a,b) {
try{
//your saveVsRupture code here...
}
catch(e){}
}
Your should catch problems that occurred in your code with try,catch block to prevent throw them to top level of your code (the browser in this example) .
Don't use return in for loop!
Change your code as following:
this.cycle = function() {
var list = this.getBreaches("Uncontained");
if (list.length > 0) {
for (i=0; i < list.length; i++) {
var temp = this.saveVsRupture(DC=11, i); //calls this.rupture() if save failed
console.log(temp);
}}
return 1;
};
I would like to do the something along the following:
for (var i = 0; i < 10; ++i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
The problem with this is that I always get the final value of i because Javascript's closure is not by-value.
So how can I do this with javascript?
One solution, if you're coding for a browser that uses JavaScript 1.7 or higher, is to use the let keyword:
for(var i = 0; i < 10; ++i) {
let index = i;
createButton(x, y, function() { alert("button " + index + " pressed"); }
}
From the MDC Doc Center:
The let keyword causes the item
variable to be created with block
level scope, causing a new reference
to be created for each iteration of
the for loop. This means that a
separate variable is captured for each
closure, solving the problem caused by
the shared environment.
Check out the MDC Doc Center for the traditional approach (creating another closure).
for(var i = 0; i < 10; i++) {
(function(i) {
createButton(function() { alert("button " + i + " pressed"); });
})(i);
}
Note that JSLint doesn't like this pattern. It throws "Don't make functions within a loop.".
Live demo: http://jsfiddle.net/simevidas/ZKeXX/
Create a new scope for the closure by executing another function:
for(var i = 0; i < 10; ++i) {
createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}
http://www.mennovanslooten.nl/blog/post/62
You need to put the closure into a separate function.
for(var dontUse = 0; dontUse < 10; ++dontUse) {
(function(i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
})(dontUse);
}
Thise code creates an anonymous function that takes i as a parameter for each iteration of the loop.
Since this anonymous function has a separate i parameter for each iteration, it fixes the problem.
This is equivalent to
function createIndexedButton(i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
for(var i = 0; i < 10; ++i) {
createIndexedButton(i);
}
for(var i = 0; i < 10; ++i) {
createButton(x, y, (function(n) {
return function() {
alert("button " + n + " pressed");
}
}(i));
}
The anonymous function on the outside is automatically invoked and creates a new closure with n in its scope, where that takes the then current value of i each time it's invoked.
I would like to do the something along the following:
for (var i = 0; i < 10; ++i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
The problem with this is that I always get the final value of i because Javascript's closure is not by-value.
So how can I do this with javascript?
One solution, if you're coding for a browser that uses JavaScript 1.7 or higher, is to use the let keyword:
for(var i = 0; i < 10; ++i) {
let index = i;
createButton(x, y, function() { alert("button " + index + " pressed"); }
}
From the MDC Doc Center:
The let keyword causes the item
variable to be created with block
level scope, causing a new reference
to be created for each iteration of
the for loop. This means that a
separate variable is captured for each
closure, solving the problem caused by
the shared environment.
Check out the MDC Doc Center for the traditional approach (creating another closure).
for(var i = 0; i < 10; i++) {
(function(i) {
createButton(function() { alert("button " + i + " pressed"); });
})(i);
}
Note that JSLint doesn't like this pattern. It throws "Don't make functions within a loop.".
Live demo: http://jsfiddle.net/simevidas/ZKeXX/
Create a new scope for the closure by executing another function:
for(var i = 0; i < 10; ++i) {
createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}
http://www.mennovanslooten.nl/blog/post/62
You need to put the closure into a separate function.
for(var dontUse = 0; dontUse < 10; ++dontUse) {
(function(i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
})(dontUse);
}
Thise code creates an anonymous function that takes i as a parameter for each iteration of the loop.
Since this anonymous function has a separate i parameter for each iteration, it fixes the problem.
This is equivalent to
function createIndexedButton(i) {
createButton(x, y, function() { alert("button " + i + " pressed"); }
}
for(var i = 0; i < 10; ++i) {
createIndexedButton(i);
}
for(var i = 0; i < 10; ++i) {
createButton(x, y, (function(n) {
return function() {
alert("button " + n + " pressed");
}
}(i));
}
The anonymous function on the outside is automatically invoked and creates a new closure with n in its scope, where that takes the then current value of i each time it's invoked.