0

I have some code which is replicated throughout the main.js file

Javascript duplicates examples:

Example 1
for (i = userVote; i < 5; i++) {
var newVotesInput = document.createElement("input");
newVotesInput.id = "vote" + i;
newVotesInput.classList.add("vote", "displayn");
newVotesInput.type = "radio";
newVotesInput.name = "vote";
newVotesInput.value = i;
someElement.appendChild(newVotesInput);
}

Example 2
for (i = 1; i <= userVote; i++) {
var newVotesLabel = document.createElement("label");
newVotesLabel.id = "voteLabel" + i;
newVotesLabel.classList.add("voteHover");
newVotesLabel.htmlFor = "vote" + i;
someElement.appendChild(newVotesLabel);
}

Example 3
var newImg = document.createElement("img");
newImg.classList.add("babeImg", "boxsb", "leftIn");
newImg.id = "imgSrc";
newImg.src = jsonData.imgSrc;
someElement.appendChild(newImg);

Example 4
var newShuffle = document.createElement("img");
newShuffle.classList.add("shuffleImg");
newShuffle.id = "shuffleImg";
newShuffle.src = "assets/img/refresh.png";
someElement.appendChild(newShuffle);

Example 5
newImg.classList.add("babeImg", "boxsb", "leftIn");
newImg.id = "imgSrc";
newImg.src = jsonData.imgSrc;
imgInner.appendChild(newImg);

As you can see the examples do the same which is creating an element but there are several parameters which differs from example to example. How do i make a function that i can use for all of them? right now i only know how to build one for exactly one specific example like so ->

function createElement(element, id, cls, src){
var newElement = document.createElement(element);
element.id = id;
element.classList.add(cls);
element.src = src;
someElement.appendChild(element);
}

This is bascially Example 4.. but how do i make this more efficient and useable on all of the examples?

1 Answer 1

4

I would suggest the following function:

function createElement(type, attributes) {
  var element = document.createElement(type);
  for (var key in attributes) {
    if (key == "class") {
        element.classList.add.apply(element.classList, attributes[key]); // add all classes at once
    } else {
      element[key] = attributes[key];
    }
  }
  someElement.appendChild(element);
}

The function takes a type (input, img, etc) and a list of attributes (i.e. an object/dictionary). We loop through the attributes and add them to the new element. The only special case is with classes, with use a different syntax (and we can have multiple classes). Here is how you can use it:

var input = createElement("input", {
  "id": "myId",
  "class": ["one-class", "another-class"],
  "name": "someName"
}); 

Note that the class has an array as a value.

The result will be:

<input id="myId" class="one-class another-class" name="someName">

Here is the jsfiddle.


EDIT

To better understand: in JS, objects are like dictionaries, i.e. a bunch of key-value pairs (and prototypes, but this is not important for this discussion).

If you have an object with an id attribute, you can access it using one of the following syntax:

myObject.id   // object style
myObject["id"] // dictionary style

The second syntax is very useful, since you can use variables to access object attributes:

var attr = "id";
myObject[attr];

Now, we can also iterate over an object, as we do with arrays. The only difference is that with arrays, the for in syntax returns the index, while with objects it returns the key or property name.

var myObject = { "id": 1, "name": "a name" }; // a basic object

for(var key in myObject) console.log(key, myObject[key]);
// will print 
// id 1
// name a name

If you understand these two mecanics, the code I gave you will get much clearer.

Sign up to request clarification or add additional context in comments.

4 Comments

This looks like nothing i have done before, i will take a good look at what you have done here and try to solve it.
Please don't use for-in on an Array. It causes problems. Either way, you really don't need a loop to add the classes from the Array. element.classList.add(...cls); Or to support older browsers without using a transpiler: element.classList.add.apply(element.classList, cls)
I tried to make it as simple as I could (for loops are often presented in the first JS lessons), but I completely agree with your comment and updated my answer.
I am really impressed by the way this works Thanks alot this will become very handy for me in the future :) Bookmarked and upvoted :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.