Cannot set property 'marginLeft' of undefined - javascript

Firstly, >>>FIDDLE HERE<<<
I put a series of divs in my webpage and used JavaScript to change their margins.
var inn = document.getElementsByClassName("line");
for (var i in inn) {
inn[i].style.marginLeft=40+"px";
}
Although it changed my margins already, an error reported in my console:
Uncaught TypeError: Cannot set property 'marginLeft' of undefined
So rest of my codes couldn't be executed.
Could you please help me to solve this problem? Thanks!

Take a look at the properties that your loop iterates over:
0
1
2
3
4
length
A for...in loop iterates over all the enumerable properties of an object. You shouldn't use it for array-like objects unless you really intend to do that.
0 through 4 work, but length doesn't have a style attribute, which is what your error says.
Use a regular for loop instead:
for (var i = 0; i < inn.length; i++) {
inn[i].style.marginLeft = 40 + "px";
}

Don't use for ... in ... it's slower and more error prone try this:
var inn = document.getElementsByClassName("line");
var i=0;
for (i=0;i<inn.length;i++) {
inn[i].style.marginLeft=40+"px";
}
next one shows the for ... in ... I think it may include some things that aren't Elements so the .style is undefined.
for(i in inn){
console.log(i);
}

Another possible solution which worked for me is instead of class name, try using by id. only when you explicitly don't need a class
change this line to
var inn = document.getElementsByClassName("line");
to
var inn = document.getElementById("line");
and definately make change in html file also.

Related

JavaScript For Loop Breaking Early

Why would a for loop terminate early in JavaScript? For some reason my outer for loop terminates after the first repetition. I am new to JavaScript but would expect something like this to work in Java.
function check(){
var elements = document.getElementById('fields').children;
var filteredMolecules = molecules;
console.log(elements.length);
for (i = 0; i < elements.length; i++) {
console.log(elements[i].id)
filterMolecules(filteredMolecules, elements[i].id, 0, 10);
}
}
function filterMolecules(molecules, parameter, lower, upper){
console.log('filtering');
var filteredMolecules = [];
for (i=0;i<molecules.length;i++){
var value = molecules[i].val()[parameter];
filteredMolecules.push(molecules[i]);
}
molecules=filteredMolecules;
}
In check(), I loop through elements which contains 22 items as shown by the first console.log(elements.length). If I remove the method filterMolecules(...) then all 22 IDs are logged. However, with the code as is, only the first id is logged.
I believe the filterMolecules method which should run elements.length number of times is causing the outer for loop to not work. Could someone please explain why this is happening. If relevant, in filterMolecules(...) the data is retrieved from Google Firebase with molecules[i].val()[parameter]. Additionally, both methods use the global variable molecules (line 3 and line 14)
When you don't declare variables in javascript you end up using globals (which can be a difficult to spot source of bugs). So here you are using the same global variable i for both loops. When you start looping thought molecules you are accidentally incrementing the counter loop of your first for. Use different variables or define them with :
for (let i=0;i<molecules.length;i++)
Which will give each loop its own version of i.
In this case, since the declarations are inside individual functions, you could use var too:
for (var i=0;i<molecules.length;i++) {
// etc.
}

javascript: cannot read property 'push' of undefined

I'm trying to fill up an Array with a number of elements given by the user. I'm doing this with a prompt window.
However, the code doesn't execute, and I get an error on line 9, telling me this:
Uncaught TypeError: Cannot read property 'push' of undefined at fillArrayWithNumberOfElements (line 9).
I searched for an answer online, but they are all pointing out that the array is not properly declared, while I'm pretty sure mine is.
Any help is appreciated, thanks in advance!
var emptyArray = [];
function askInput() {
return (prompt("Please enter a number: "));
}
function fillArrayWithANumberOfElements(array, numberOfElements){
for(var i = 0; i < numberOfElements; i++){
array[i].push(askInput());
}
return array;
}
fillArrayWithANumberOfElements(emptyArray, 5);
In fillArrayWithANumberOfElements, array is the array, not array[i]. So to push, just use
array.push(askInput());
not
// Not this
array[i].push(askInput());
Alternately if you like, use assignment:
array[i] = askInput();
push is a function attached to the prototype of the array type. You're accessing a specific element within the array.

object with array type string causing a typeError

The best way to explain this is just to show you.
var condition = 70;
var formnames = new Array("wheelcheckbox1", "wheelcheckbox2","spokecheckbox","spokecheckbox2","tirecheckbox","tirecheckbox2","tirecheckbox3");
formnames.forEach(function(entry) {
console.log(obj.entry);
if(obj.entry == "") {
condition = condition - 10;
}
});
as you can see I used the console log to show how it needs to work
as that works perfect, however, using the array causes an error as
they're strings and not what the obj wants, it wants text without it being a string.
Any ideas?
for..in should not be used to iterate over an array. Consider using forEach instead.

Why the eval() is not working with array

What's wrong with this code? Can anyone help out?
var read=new Array("i=10","j=20","k=i*j");
for(var i=0;i<read.length;i++)
{
alert(eval(read[i]));
}
Expecting output:
alert three times with values 10,20,200.
But actual output:
But alert Once with value 10.
When the loop executes the first time, you are setting i = 10, with eval. So the loop breaks out immediately.
So, you might want to change the loop variable to something else, like this
var read = new Array("i=10","j=20","k=i*j");
for(var idx=0; idx < read.length; idx++)
{
console.log(eval(read[idx]));
}
Output
10
20
200
Note: Please make sure that you read this question and the answers to that question, before using eval in your code.
Try this code
var read=new Array("i=10","j=20","k=i*j");
for(var index=0;index<read.length;index++)
{
alert(eval(read[index]));
}
while the loop is executing, at the first execution of i=10 the i variable is set to 10; so loop will be terminated because of the condition i<read.length (here... 10<3) remains false.
see the eval() tutorial.

document.getElementsByTagName("a") misses a link

I was working on a script for Greasemonkey (FX7) trying to remove certain links and found out that for some reason one that was present in the source, not hidden or constructed by JS, didn't show up in the array that that function returns.
If that one would have been constructed via JS upon running that page it wouldn't wonder me but it's sitting right behind another link that gets found.
So has anyone an idea why this is happening and how I could work around it?
var links = document.getElementsByTagName("a");
for (var l in links){
if (links[l].href == "blah"){ ... }
}
Thats how I was trying to work with them, a bit cut down as I had some more checks to not run into nulls and such.
On a sidenote: I was wondering why that function also returns null entries at all.
Edit: I passed this problem long since I asked for help and found a nice way to do it:
for (var i = 0, l; l = links[i]; i++) { }
This keeps setting l to the current link until there aren't any left. Works nice.
The for...in statement loops through the properties of an object. In this particular case you are iterating over Array object properties. Try to use this script instead:
var links = document.getElementsByTagName("a");
for (var l = 0; l < links.length; l++){
if (links[l].href == "blah"){ ... }
}
var links = document.getElementsByTagName('a');
for (var i=0; i<links.length; i++){
if (links[i].href.match('blah')){...}
};
for … in statements loop through the properties of an object, not only its values, just like #Yuriy said. You'll need to learn some Javascript to understand this (sorry, couldn't find any direct pointer to this part after a few minutes of Googling).
Basically, you need to understand that objects in JS also include “methods”. When you're using a for … in loop, you find an object's values but also its “methods” and other properties.
So, either use #Yuriy's indexed loop… or better, use the hasOwnProperty() method (MDN doc), that allows to avoid the very important caveat #Kolink mentioned.
Your loop should look like:
var links = document.getElementsByTagName('a');
for (var l in links) {
if (! links.hasOwnProperty(l))
continue; // this goes straight to the next property
if (links[l].href == "blah") { ... }
}
getElementsByTagName ("area") [0] returns the value of its href attribute and not HTMLAnchorElement

Categories

Resources