I can't believe that I've been unable to dig out a solution to this problem. It looked to me like a very "regular" problem whose solution would litter the web!
I have these arrays returned from a database query:
var ids = ['12', '15', '40'];
var actions = ['hide', 'show', 'fadeIn'];
I want to loop through the arrays and carry out the appropriate action on the DOM, like so:
for(var i=0; i < ids.length; i++){
$('#row_'+ids[i]).actions[i]();
}
Now you get the idea. Actually I didn't expect the $('#row_'+ids[i]).actions[i](); to work as is. I have tried things like
$('#row_'+ids[i]).effect(actions[i]);
To no avail. I believe eval() should work and (in desperation) even tried that but couldn't get the right string for it to work.
Elsewhere on Stack Overflow, I have come across similar issues solved using the window global, like:
var fn = 'hideSomething';
window.fn();//where hideSomething was a defined function.
But this one is defined on jQuery, not on window.
So here we are!
You need to use [varhere] to access a property/method by variable name. Since your property name is in actions[i], then you would do this:
$('#row_'+ids[i])[actions[i]]();
Or, in a slightly easier scheme to follow exactly what is happening:
var method = actions[i];
$('#row_'+ids[i])[method]();
You can use the dot syntax obj.prop when the property name is known ahead of time. When it's in a variable and not known ahead of time, you use the obj[prop] syntax. Since a method is just a property, the same applies to jQuery methods too.
for(var i=0; i < ids.length; i++){
$('#row_'+ids[i])[actions[i]]();
}
Use square bracket notation in order to access the property:
for (var i = 0; i < ids.length; i++) {
$('#row_' + ids[i])[actions[i]]();
}
Example Here
See: Property accessors in JS (MDN)
Related
I know only one way of setting localstorage in HTML5
localStorage.name = "Peter Martin";
But, in the following discussion I found that there are 2 other ways to set localstorage.
localStorage - use getItem/setItem functions or access object directly?
localStorage.setItem(city, "New York");
localStorage[country] = "USA";
However, when I tried all 3 in the example below, seems the first works fine but issues with the other 2 methods. Can someone explain me out if all 3 methods are valid?
<html>
<head></head>
<body>
<button onclick="alpha()">Click Me</button>
<script>
function alpha(){
localStorage.name = "Peter Martin";
localStorage.setItem(city, "New York");
localStorage[country] = "USA";
}
</script>
</body>
</html>
As, there is some sandbox issue with StackOverflow, I am posting error image, as below:
This comes down to basic JavaScript syntax.
When you call localStorage.setItem(city, "New York");, you are referring to an identifier, city, which is not defined in the current scope. You should either define a variable named city, or just use the string "city" directly.
The same goes with localStorage[country] = "USA";. country is not defined in this scope, so the JavaScript engine throws an error.
Can someone explain me out if all 3 methods are valid?
Yes they are (ish). localstorage like pretty much everything in Javascript is an object. You can access properties in an object in two ways:
object.property
object['property']
See Property accessors in Javascript MDN. So there is no reason why you can't access properties of the localstorage object using property accessors as the above.
localStorage.setItem("city", "New York");
Is a method on the localstorage object that:
The setItem() method of the Storage interface, when passed a key name
and value, will add that key to the storage, or update that key's
value if it already exists.
MDN
So this is a valid way to "add that key to the storage, or update that key's
value if it already exists". Your having problems with this method because your passing an incorrect parameter city that doesn't exist. I believe you meant "city". As covered in this answer
You can break it down into
1> properties or values
localStorage.name = "Peter Martin";
localStorage["name"] = "Peter Martin";
The 2nd version allows you to use a JavaScript variable. But is harder to read because one needs to determine what value is in the variable.
IE
var tag= "name";
localStorage[tag] = "Peter Martin";
and
2> methods or functions that get / set value; etc.
localStorage.setItem("name", "Peter Martin");
vars allowed,
var obj = "name";
var value = "Peter Martin";
localStorage.setItem(obj, value);
With methods there are the .prototype goodies, which include things like .bind() that allows you to say do something when you call setItem. But generally when I want to do something after setting a property I do it on the very next line; I Keep it simple and readable.
I'm not sure why I would ever need to use the methods. But, on a modern system there should be no measurable difference in speed.
Maybe using methods would allow two tabs open at the same time to synchronize data between tabs?
There are situations in loops that change values of properties and either methods or properties works, I don't recall the details; but unlikely to need that with a localStorage string.
Now I recall, why a method or function is sometimes needed.
This fails using a property. (always returns 10 the last value of i)
var elements = document.getElementsByTagName('input');
var n = elements.length; // assume we have 10 elements for this example
for (var i = 0; i < n; i++) {
elements[i].onclick = function() {
console.log("This is element #" + i);
};
}
This works using a function
var elements = document.getElementsByTagName('input');
var n = elements.length; // assume we have 10 elements for this example
var makeHandler = function(num) { // outer function
return function() { // inner function
console.log("This is element #" + num);
};
};
for (var i = 0; i < n; i++) {
elements[i].onclick = makeHandler(i+1);
}
So if you are going through a long list and want to cancel then return to it using localStorage use the method.
Even though the localStorage may not require a method. Our subconscious brain recognizes patterns. And the loop with a property value pattern triggers a warning, anxiety because of how long it takes to find it, even though the details are not recalled. Though it would work since it does not store a reference to the variable it only stores static strings.
To program at max speed, people need to follow the patterns that they know work. Methods resolve the value of the value at the time the method was called.
<html>
<head></head>
<body>
<button onclick="alpha()">Click Me</button>
<script>
function alpha(){
localStorage.name = "Peter Martin";
localStorage.setItem("city", "New York");
localStorage["country"] = "USA";
}
</script>
</body>
</html>
So I use Spring to pass a list of objects into the jsp, but I don't know how to access it's values and properties inside javascript.
So if I use something like:
var x = ${objectList};
there seems to be an error, when I use chrome to check it.
I would like to do something like this:
var x = ${objectList};
for(i=0; i<x.length; i++)
{
document.write(x[i].propertyName); // property for object i
}
I searched for an answer for a few days, but I didn't find one for my problem.
Try this to access spring object in javascript
<script>
var data=<c:out value="${objectList}"/>
</script>
I am trying to find a better solution for adding objects to an array. The box objects are from a separate file and are pushed to the array one line at a time in a different file, as such:
function loadCols(){
collisionPoints.push(box1);
collisionPoints.push(box2);
collisionPoints.push(box3);
collisionPoints.push(box4);
collisionPoints.push(box5);
collisionPoints.push(box6);
collisionPoints.push(box7);
collisionPoints.push(box8);
collisionPoints.push(box9);
collisionPoints.push(box10);
};
I have tried using a for loop and concatenating the string "box" + i but this didn't work.
I also tried adding them to an array in the file where the objects are created but I was not able to find a way of passing the array to the main file. Although this works I'm hoping there is a cleaner solution. Any help would be appreciated, cheers.
You can get a variable from it's string name, by using the window object.
function loadCols(){
for (var i=1; i<=numberOfBoxVars; i++) {
collisionPoints.push(window["box" + i]);
}
}
Alternatively, if your variable are defined within a closure and your loadCols function is defined within the same closure, you can use the "this" keyword in place of the window object.
(function() {
var box1 = "1";
var box2 = "2";
...
function loadCols(){
for (var i=1; i<=numberOfBoxVars; i++) {
collisionPoints.push(this["box" + i]);
}
}
});
If I understand you correctly you are looking for a way to use dynamic variables in a for-loop. If box1 and so on are global variables you can get them dynamically by accessing them as property of window:
window['box'+i]
See here: Use dynamic variable names in JavaScript
If you send all the objects in a JSON array you could just do this:
var array = JSON.parse(boxesarray);
for(var i = 0;i< array.length; i++) {
collisionPoints.push(array[i]);
}
But it would require you sending all the boxes in an array, if this is not possible please post code as to why it isn't and i will adapt my anwser.
Knowledge: First week Javascript
I am trying to learn real javascript and avoid jquery at all cost. Now I am I recently learned that id's can be style easily but not classes. In order to style a class I need to loop through the dom for the class. My original code works, however my new one does not. Best practices aside for a moment, I am trying to learn how this works regardless if it is a perfect solution or not.
Problem specifics: In my new code I stored the two get functions in keys within an associative array. So I have objects which I would like my for loop to understand. I am trying to make it work like my first code.
What I tried: Honestly, I read something about squared bracket notation and how it can be useful. I felt a bit overwhelmed to be honest. What I tried was:
source[_class][i]
Maybe _class is undefined even though I defined it. I specified what class contains. Honestly im lost and would appreciate some help and of course I welcome best practice advice as well.
I want to be a better programmer and I would appreciate some insight. I dont want to start with jquery.
My experiment:
setTimeout(function() {
var source = {_id: document.getElementById('box'),
_class: document.getElementsByClassName('hint')};
for (var i = 0; i < source[_class].length; i++) {
source[_class + i].style.opacity = '0';
console.log(i);
}
}, 1000);
My original working code:
// setTimeout(function() {
// var divs = document.getElementsByClassName('hint');
// for (var i = 0; i < divs.length; i++) {
// divs[i].style.opacity = '0';
// console.log(i);
// }
// }, 1000);
Use source._class.length instead of source[_class].length and source._class[i] instead of source[_class + i]:
for (var i = 0; i < source._class.length; i++) {
source._class[i].style.opacity = '0';
console.log(i);
}
source is an object and has a property _class. You can access properties either as source._class or as source['_class'].
The property source._class is an collection of DOM nodes itself so it can be accessed like an array. You can access array elements like this: array[index].
So you have both an object with properties and an array with elements. You need to access their contents appropriately.
Styling should be done with css, not loops, because using css is an order of magnitude faster.
Create css class definitions for your set of styles and then simply change the name of the class on your elements to change their style.
Also, look into using css selectors to query the DOM. This is done with querySelector for a single element, or querySelectorAll for a set of elements. Note that jQuery wraps this functionality and that is where the name is derived.
For your specific example, the problem was with accessing the array, instead of adding the i index, you need to reference the array, and you also need to make sure you are using a string index or a dot notation (such as source._class) in order to reference that object's property
for (var i = 0; i < source['_class'].length; i++) {
source['_class'][i].style.opacity = '0';
console.log(i);
}
You missed a square bracket and it's text not a variable:
source[_class + i].style.opacity = '0';
should be
source["_class"][i].style.opacity = '0';
In a situation where I have something like this code:
var variableNames=["thisMonth", "thisDay"];
var variableValues=["February", 17];
Is there any way I could go through the array and initiate variables with their corresponding values? I've tried something like
for(var i=0;i<variableNames.length;i++){
eval("var "+variableNames[i]+"="+variableValues[i]+";");
}
But I'm not getting any reults. Is eval not able to define variables, or are there other problems that exist? Any solution would be greatly appreciated.
You need to assign the variables on an object. If you want to create global variables the following code should work:
for (var i=0; i<variableNames.length; i++) {
window[variableNames[i]] = variableValues[i];
}
//test
console.log(thisMonth); //"February"
Here you go. You missed a couple of quotes at "='" + variableValues[i] + "';");:
var variableNames=["thisMonth", "thisDay"];
var variableValues=["February", 17];
for(var i=0;i<variableNames.length;i++){
eval("var "+variableNames[i]+"='"+variableValues[i]+"';");
}
With that correction however, I would warn you against using it cause it's a very wrong way of doing it.
Use Objects, as most here mention.