jQuery - Working with arrays - javascript

OK so I fixed my last error with the DIV and all..
OK so at the very top of my javascript file... I have
$(function() {
var games = new Array(); // games array
});
and then in a new function I have: var gamesLgth = games.length;
but when I run it, I get this: Uncaught ReferenceError: games is not defined
When I weird because I initalized it at the very beginning...

games is out of scope. You need to store it somewhere such that your other function can access it.
For example, this will make your variable global.
var games;
$(function() {
games = new Array(); // games array
});
$(function() {
var gamesLgth = games.length;
console.log(gamesLgth);
});

By declaring that variable within a function you have scoped the variable to that function, which means that that variable games is only available within that function.
$(function() {
var games = new Array(); // games array
...
var gamesLength = games.length; // works fine
});
But this following example will not:
$(function() {
var games = new Array(); // games array
});
$(function() {
var gamesLength = games.length; // won't work - im in a different scope
});

You initialized it as a local variable of a separate function. You need to make it global, or to pass it from function to function as argument to be able to access it.

try this;
var games = [];
instead of
var games = new Array();
and also be sure about the games scope.

I'll go ahead and write the code out for you:
var games;
$(function(){
games = new Array();
...
});
$(function(){
games.length; // Which would be zero
});

You initialized "games" in a function scope, it's not available outside the borders of $(function() { ... });

Related

Trouble with my javascript function, I think with document.getElementById('vodObj').innerHTML

I am trying to write a JavaScript function that will update the labels and attributes of my CSS menu. The CSS menu I create dynamically with PHP and a database, and I want to update the CSS menu so the top item is the currently selected one, and the currently selected one does not appear in the list below it. Now that you know what I am trying to accomplish, here is my code:
var vodName = Array();
var vodAddress = Array();
var vodDate = Array();
function switchVod(vodID) {
alert("switchVod ran");
var x = document.getElementById("vod1");
var y = x.getElementsByTagName("span");
y[0].innerHTML = vodName[vodID];
for (var i = 0; i < vodName.length; i++) {
if (i != vodID) {
var gameNum = i + 2;
var gameID = "vod" + gameNum;
var x = document.getElementByID(gameID);
var y = x.getElementsByTagName("span");
y[0].innerHTML = vodName[i]
x.onclick = function () {
switchVod(id);
}
}
}
alert("after for loop");
alert("1"); //works
document.getElementById('vodObj').innerHTML = 'some string';
alert("2"); //doesn't work
document.getElementById("vodDate").innerHTML = " some string ";
alert("finished"); //doesn't work
}
Deeper in the webpage, after getting my information from the database and storing the strings I need in the vodName, vodAddress, and vodDate arrays, and creating the CSS menu and <div id="vodObj"> and <div id="vodDate">, I initialize the page by calling
window.onload = switchVod(0);
It wasn't doing what I hoped, so I added some alert() calls to see how far into the function it was going before failing. alert("after for loop") worked, as did alert("1"). But, alert("2") does not pop up, and neither does alert("finished"), so I think the problem is with document.getElementById('vodObj').innerHTML = 'some string';.
Any ideas of what I could be doing wrong?
window.onload = switchVod(0);
executes switchVod and assigns the return value to window.onload. So it is very likely that the elements you are trying to access (#vodObj in particular) are not loaded yet.
You have to assign a function to window.onload:
window.onload = function() {
switchVod(0);
};
See also Why does jQuery or a DOM method such as getElementById not find the element?
There is an other problem which will encounter eventually:
x.onclick = function () {
switchVod(id);
}
You never defined id anywhere, and if you define it inside the loop, you will run into closure issues. See JavaScript closure inside loops – simple practical example for a solution.
y[0].innerHTML = vodName[vodID];
At this point vodName is an empty array. Actually throughout all of this, you never provide any values to vodName. Please provide complete document.

Passing references in javascript

This is my first SO post. I'm eternally grateful for the information this community has and shares. Thanks.
I'm coming from Flash and I'm not even sure what the right question to ask is. All I can do is lay out my code example and then explain what I am trying to do. I do not fully grasp the terms that I am trying to illustrate here so I feel it is best to omit them.
The code below is incomplete as it only includes the parts that I feel are relevant to my question. Please refer to the comments in my code to see my issue.
EDIT: Full source file here: [link removed] The console.log outputs the issue in question.
<script type="text/javascript">
var a_chests = [];
var chestID = 0;
//I'm creating a plugin to be able to make multiple instances
(function ($) {
$.fn.chestPlugin = function (option) {
//This function creates a master sprite object which many of my sprites will use
//I've simplified the features to get to the heart of my question
var DHTMLSprite = function (params) {
var ident = params.ident,
var that = {
getID: function(){
return ident;
}
};
return that;
};
//ChestSprite inherits DHTMLSprites properties and then adds a few of its own
var chestSprite = function(params) {
var ident = params.ident,
that = DHTMLSprite(params);
that.reveal=function(){
console.log(ident);
};
return that;
};
//Here I create multiple instances of the chests
var treasure = function ( $drawTarget,chests) {
for (i=0;i<chests;i++){
var cs = chestSprite({
ident: "chest"+chestID
})
console.log(cs.reveal())
//This logs "chest0", "chest1", "chest2" as the for loop executes
//This behavior is correct and/or expected!
a_chests[chestID]={id:i,ob:cs};
//I add a reference to the new chestSprite for later
chestID++;
//increment the chestID;
}
console.log(a_chests[1].ob.reveal());
//This always logs "chest2" (the last chest that is created), even though
//the logs in the for loop were correct. It seems it is referencing the
//DHTML object (since the DHTMLSprite function returns that;) and since
//there is no reference to which chest I need, it passes the last one.
//Is there any way I can pass a reference to DHTMLSprite in order to retain
//the reference to the three individual chests that are created?
//Is there another solution altogether? Thanks!!!
};
//The rest of the code.
return this.each(function () {
var $drawTarget = $(this);
treasure($drawTarget,3);
});
};
})(jQuery);
</script>
You forgot to declare `that' as a local variable, so it's being overwritten on each iteration.
var chestSprite = function(params) {
var that;
var animInterval;
...
When you write:
a_chests[chestID]={id:i,ob:cs};
You are assigning the cs object itself, not an instance of this object. If later you modify cs, this will also modify what you stored in the ob property.
I guess what you need is a closure:
for (i=0;i<chests;i++){
(function(){
var cs = chestSprite({ident: "chest"+chestID});
a_chests[chestID]={id:i,ob:cs};
})();
}
This way, each loop creates a different cs object.

How to define Global Arrays?

Code example:
<script>
var data = new Array();
data[0] = 'hi';
data[1] = 'bye';
</script>
<script>
alert(data[0]);
</script>
This gives the following error: data is not defined
How do you make something like this work? Especially if the first <script> block is being loaded on the page by ajax, and the second block is working from it. jQuery solution is acceptable.
New is not a keyword.
Use:
var data = new Array();
Or, more succinctly:
var data = [];
After your edit you mention that the first script block is loaded asynchronously. Your code will not work as written. data is a global variable, once it is loaded onto the page. You need to use a callback pattern to properly execute the code.
Since you haven't posted the asynchronous code I am not going to provide a callback sample. Though, a quick solution follows:
var interval = setInterval(function(){
if(data) {
/* ... use data ... */
clearInterval(interval);
}
}, 500);
To create a global variable, just omit 'var' from the statement. When you omit 'var', you're actually creating the variable in the window namespace.
So, zz = 1 is actually window.zz = 1
If you really wanted to, you could explicitly say
window.data = new Array(); //remember that new should be lowercase.
But you can write that faster anyway by saying
data = ['hi','bye'];
alert(data);
If you're using jQuery, perhaps you should try .getScript() rather than using .html();
// in separate file
data[0] = 'hi';
data[1] = 'bye';
// in main file
var data = [];
$.getScript(url).done(function() {
alert(data[0]);
}).fail(function() {
// handle error
});
<script>
data = [];
data[0] = 'hi';
data[1] = 'bye';
</script>
<script>
alert(data[0]);
</script>
use this, remove var makes variable global

JavaScript object is undefined

I need some help please with a javascript object. it goes like this:
I call this function addFilter(element) with a html DOM element.
The function looks like this:
function MyList() {
this.arr = new Array();
this.index = 0;
}
MyList.prototype.add = function(filter) {
this.arr[this.index++] = filter;
//alert(this.arr[0] + ' mylist arr');
}
function Filter(element) {
this.setElement(element);
}
Filter.prototype.setElement = function (element) {
this.element = element;
this.kinorid = $(element).attr('id');
}
function addFilter(element) {
filters.Add(new Filter(element));
}
var filters = new MyList();
Now with in another function that in my case the function creates the jquery UI Slider, and every time the slider changes i need to get the parent element of that element that was sent to addFilter like i said in the beginning. so then i try doing
var value = filters.arr[0];
but like i said it id undefined.
Can any one please help me by reviewing the code, and tell me whats wrong.
Thank you very much.
You still haven't said where or how you're using filters.arr[0], without which it's very difficult to help you.
Assuming your code using it looks something like this:
AddFilter($("#theElement"));
display(typeof filters.arr[0]);
filters.arr[0].element.css("color", "blue");
It should be working; live example.
My only thought is if AddFilter and filters are not defined within the same scope. You're using filters within AddFilter, so AddFilter must be defined in the same scope as filters (or in a sub-scope). So this would be fine:
var filters;
function AddFilter() { ... }
And this
function AddFilter() { ... }
var filters;
And this
var filters;
$(function() {
function AddFilter() { ... }
});
But not
function AddFilter() { ... }
$(function() {
var filters;
// ...
});
...because in that last case, AddFilter is defined outside the scope in which filters is defined.
Your code is very convoluted, I don't understand it at all. Anyway, you are looking for (I think):
var value = filters.arr[0].element;
since you assign the element reference to arr[this.index].
Incidentally, if you are passing an element, then:
$(this).attr('id');
is an awfully slow way to do:
this.id;
Edit
The code I used (where there was a div with id 'd0' in the DOM):
var filters = new MyList();
AddFilter(document.getElementById('d0'));
alert(filters.arr[0].element);

Can't get JavaScript Array to work in OOP style

Hi currently I'm trying to get following snippet of code to work:
function Entry() {
var pauses = new Array();
}
Entry.prototype = {
AddElement: function(aParameter) {
this.pauses.push(aParameter);
}
}
Unfortunately this code fails with following error in Safari if I try to call AddElement("Test");
TypeError: Result of expression 'this.pauses' [undefined] is not an object. Does anybody know why?
In your code, pauses is a local variable within the Entry() function, not a member on the object constructed by it.
You want to replace var pauses = ... with this.pauses = ....
change
var pauses = new Array();
to
this.pauses = new Array();
or, better
this.pauses = [];

Categories