Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I've made a nice little function to return a NodeList array containing all the inputs that have a specified name attribute:

function GiveElementsByName(name) {
var finalOutput = [], times = document.getElementsByTagName('input').length, inOutput = 0, inAll = 0; //For use later.
while(times--)
{
if (document.getElementsByTagName('input')[inAll].name == name) //Apply to all inputs with specified name.
	{
	finalOutput[inOutput] = document.getElementsByTagName('input')[inAll]; //Array with all the matching inputs.
	inOutput++;
	}
inAll++;
}
return finalOutput;
}
function MyFunc() {
  GiveElementsByName("Lol1")[1].value = "I don't like potatos anymore";
}
<input type="text" name="Lol1" value="I like potatos">
<input type="text" name="Lol1" value="I like potatos">
<input type="text" name="Lol1" value="I like potatos">
<input type="text" name="Lol1" value="I like potatos">
<br><br><br><br>
<input type="text" name="Lol2" value="I like potatos more">
<input type="text" name="Lol2" value="I like potatos more">
<input type="text" name="Lol2" value="I like potatos more">
<input type="text" name="Lol2" value="I like potatos more">
<br><br><br><br>
<input type="button" value="Click me!" onClick="MyFunc()">

Could you help me shrink down the function and make it quicker?

share|improve this question
    
    
@Jamal Yup, yup, i know, I didnt wait for 200_success to answer me and foolishly edited the question. Any way to undo? –  The SuperCuber Mar 10 at 17:30
    
I have already done so. –  Jamal Mar 10 at 17:31
    
@Jamal Oh, thanks :D –  The SuperCuber Mar 10 at 17:31
    
@Jamal Sorry for @ ing you for no reason, but can I share a code I made, with no asking about performance or anything? Just share? –  The SuperCuber Mar 10 at 18:08

4 Answers 4

up vote 1 down vote accepted
  • Naming: Give… is unconventional; usually we say get…. The function only looks at <input> elements, so that should be part of the name. The "final" in finalOutput doesn't contribute to the clarity.
  • Performance: You're calling document.getElementsByTagName() many times. That DOM access is probably the most expensive call in your code, so you should do it just once and remember its result.
  • Initialization: This is one long line with poor readability:

    var finalOutput = [], times = document.getElementsByTagName('input').length, inOutput = 0, inAll = 0; //For use later.
    

    Eliminate as many variables as you can, and break up the rest into multiple lines of code.

  • Looping: A common idiom for a loop that runs n times is

    for (var i = 0; i < n; i++) {
        …
    }
    

    There are times when while (times--) { … } is appropriate, but this is not one of them, since you need an inAll that counts up anyway.

  • Building the array: If you use Array.push(), then you don't have to keep track of inOutput.
function getInputElementsByName(name) {
    var inputs = document.getElementsByTagName('input');
    var out = [];
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].name == name) {
            out.push(inputs[i]);
        }
    }
    return out;
}
share|improve this answer
    
OK. gonna implement one by one. How do i look at all the tags instead of inputs only? would "*" work? –  The SuperCuber Feb 20 at 18:33
    
    
    
Not sure if you will see this, but I'm very sorry for delaying working on this thing for such a long time. You might have forgotten me :D. So my question is, how do I correctly update my code? I mean i could answer my question but that would make others unable to answer... –  The SuperCuber Mar 10 at 16:52
    

The GiveElementsByName function is poorly indented. And the variable declarations should not be only a single extremely long var line, but each variable should be on its own line. It's better like this:

function GiveElementsByName(name) {
    var finalOutput = [],
        times = document.getElementsByTagName('input').length,
        inOutput = 0,
        inAll = 0;
    while (times--) {
        if (document.getElementsByTagName('input')[inAll].name == name) {
            finalOutput[inOutput] = document.getElementsByTagName('input')[inAll]; 
            inOutput++;
        }
        inAll++;
    }
    return finalOutput;
}

It seems to me that there is an easier way to do this using document.querySelectorAll, which should be supported by modern browsers:

function GiveElementsByName(name) {
    return document.querySelectorAll('input[name=' + name + ']');
}
share|improve this answer

The big thing would be to call getElementsByTagName no more than you need to. In your method, you call it once to get the length, then twice more for every result (once to get the name, then again to add it to your array). This could require the code to parse the DOM an excessive number of times.

In the example code below, I call document.getElementsByTagName only once.

function GiveElementsByName(name) {
    var finalOutput = [], tags = document.getElementsByTagName('input'), inOutput = 0, inAll = 0, times = tags.length; //For use later.
    while(times--){
        if (tags[inAll].name == name){ //Apply to all inputs with specified name.
            finalOutput[inOutput] = tags[inAll]; //Array with all the matching inputs.
            inOutput++;
        }
        inAll++;
    }
    return finalOutput;
}

However, since you're really looking for two different properties of the elements (the tag name "input" as well as the name attribute) you could try using document.querySelectorAll instead of getElementsByTagName, which allows you to specify a complex CSS selector.

At a glance, your function could thus be replaced with:

function GiveElementsByName(name) {
    return document.querySelectorAll("input[name="+name+"]");
}
share|improve this answer
    
Ermmm... Hmm... Realizes he's stupid... Well, I choose the fancy way! –  The SuperCuber Feb 20 at 18:35
    
Not stupid, just taking a different approach. In fact, depending on the browser and the element(s) being selected, getElementsByTagName can be faster than querySelectorAll. Check out this jsperf test for some comparisons. –  Thriggle Feb 20 at 18:52

After reading all the above (or the below, i dont know) answers, and working a little, I've made this fancy thing:

function getInputsByName(Name) {
	var output = [],
	inputs = document.getElementsByTagName("input");
	for(i = 0; i < inputs.length; i++) if(inputs[i].name == Name) output.push(inputs[i]);
	return output;
}





function MyFunc() {
	getInputsByName("Lol1")[1].value = "Nope, I'm the most!";
}
<input type="text" name="Lol1" value="I like potatoes">
<input type="text" name="Lol1" value="I like potatoes">
<input type="text" name="Lol1" value="I like potatoes">
<input type="text" name="Lol1" value="I like potatoes">
<br><br><br><br>
<input type="text" name="Lol2" value="I like potatoes more">
<input type="text" name="Lol2" value="I like potatoes more">
<input type="text" name="Lol2" value="I like potatoes more">
<input type="text" name="Lol2" value="I like potatoes more">
<br><br><br><br>
<input type="button" value="Click me!" onClick="MyFunc()">

Thanks for helping me and tipping me everyone who answered! I will vote you all up as soon as I reach 15 reputation! :D

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.