1

I'm trying to set multiple attributes to an element at one shot. I found this answer, and this comment to that answer. In the JSFiddle there, he doesn't use a string for the property name, as opposed to the answer which uses a string.

The problem with the JSFiddle in the comment, is that it doesn't have the ability to edit the text for the element. I tried adding that capability, but it didn't work.

I added the following at line 7:

else if (at[prop] === html) {
    this.innerHTML = set[idx];
}

But I got the following error:

Uncaught ReferenceError: html is not defined

How can I add the functionality of changing the text to the commented JSFiddle?

Code

Answer JSFiddle

Comment JSFiddle (edited)

3
  • 2
    html is not defined in your code..I guess it should be 'html' in condition.. Commented Feb 23, 2016 at 4:14
  • @RayonDabre Thanks! The error doesn't show up, but if you insert console.log in that if statement, you see it never gets called Commented Feb 23, 2016 at 4:19
  • Can you be more specific about ` doesn't have the ability to edit the text` ? Do you want to set different string rather 'hello' in the if-else loop? Because I don't get it why are you adding else if (at[prop] === html) { this.innerHTML = set[idx]; } in line 7? Did you change the variables in the given JSFiddle link because in that code, first of all at[prop] is not a variable. You may replace attrs with at but here prop is the index of attrs[idx]. So I just don't get it. Commented Feb 23, 2016 at 5:11

2 Answers 2

1

Use 'html' in your comparison. Also pass this context in recursiveSet function to refer this to div element. this always refers to the “owner” of the function we're executing. If there is no owner, it will refer to the window..

Try this:

var manipulateAttributes = function(attr, element) {
  var recursiveSet = function(at, set) {
    for (var prop in at) {
      /* check if object and not a dom node or array */
      if (typeof at[prop] == 'object' && at[prop].dataset == null && at[prop][0] == null) {
        recursiveSet(at[prop], set [prop]);
      } else if (prop == 'html') {
        this.innerHTML = at[prop];
      } else {
        set [prop] = at[prop];
      }
    }
  }.bind(element);
  recursiveSet(attr, element);
}
var test = document.getElementById("test");

manipulateAttributes({
  html: 'hellop',
  style: {
    background: "lightGreen",
    color: "blue",
    width: "100px"
  },
  className: "testclass",
  onclick: function(e) {
    alert("the test div has been clicked and its width is: " + this.style.width);
  }
}, test);
.testclass {
  font-size: 32px;
  font-weight: bold;
  cursor: pointer;
}
<div id="test" style="width:200px;height:200px;background:#000;color:#fff;">Test</div>

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

6 Comments

Thanks! Also, how do I make it a function rather than extending the object?
I don't like extending a host object, i.e. this line: Element.prototype.setAttributes. How can I use it as a regular function?
Thanks! Is there a way of doing it with 1 function only? Meaning not having recursiveSet? I feel like it's repetitive.
Which do you suggest?
It is going to be lots of ifs and for...in loop inside for...in loop...There is no other way..And it is not repetitive..
|
0
else if (at[prop] === html) {

replace the above line of code as below to get into the loop

else if (at[prop] === 'hellop') {

1 Comment

Value of the key will be different in every cases..So you should be testing key of the object rather than value of the key...Makes sense ?

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.