-1

I'm looking for a way to add a javascript object to the DOM without redefining the object.

I have created a function that puts all object methods into a new object, redefines the object as a new DOM element, and puts all the objects back onto it but this is not exactly what I want. I need the object to be updated without using any return statements.

I have an example here: http://jsfiddle.net/y56wS/

function addToDOM(obj) {
    temp = {};
    for (p in obj) {
        temp[p] = obj[p];
    }
    obj = document.createElement('prop');
    document.body.appendChild(obj);
    for (p in temp) {
        obj[p] = temp[p];
    }
    return obj;
}

var obj = {var1:123};
obj = addToDOM(obj);

The resulting code template should be something like this:

function addToDOM(obj) {
    //Code for method
    //No return statement
}

var obj = {var1:123};
//No obj=
addToDOM(obj);

To accomplish this, there really has to be no obj = within the addToDOM function so that it is never redefined and there is no need for a return statement. Is there a way to simply extend the javascript object onto the DOM?

2
  • "I'm looking for a way to add a javascript object to the DOM" - Let me stop you right there and say huh? Why? Obviously I've completely missed the point, because the idea of adding a JS object to the DOM makes no sense to me. How would the browser display it? And if it doesn't display it why would you do it at all? Commented Aug 15, 2012 at 7:09
  • I'm very sorry for not elaborating more. I'm trying to create a defineObject getter/setter polyfill(ish) thing so that my code will work in IE6+ as well as all other major browsers. As many know this is only possible in IE8 if the object is part of the DOM and I have a workaround for IE6/7 if it is in the DOM as well. Object.defineProperty works perfectly as long as I call obj = addToDOM(obj) after defining obj = {}. I just want to make it so I can include addToDOM(obj) as part of the polyfill and to do that I have to add it to a DOM element without redefining it. Was that more clear? Commented Aug 15, 2012 at 7:18

2 Answers 2

1

No, JavaScript objects can't be added to the document just like that - the appendChild() method is expecting objects of certain type, usually created with document.createElement() method.

So you must create new DOM element, or clone existing one, every time.

Assuming you want to have sort of "template" element I suggest using global variable to hold that element, create it once then clone it every time and put the new attributes.

Code for that would be:

var _globalDOMobj = 0;
function addToDOM(obj) {
    temp = {};
    for (p in obj) {
        temp[p] = obj[p];
    }
    if (!_globalDOMobj) {
        _globalDOMobj = document.createElement('prop');
        _globalDOMobj.className = "myprop";
    }
    obj = _globalDOMobj.cloneNode(true);
    obj.innerHTML = "I am dynamic element";
    document.body.appendChild(obj);
    for (p in temp) {
        obj.setAttribute(p, temp[p]);
    }
    return obj;
}

addToDOM({"var1": "123", "style": "color: red;"});
addToDOM({"var2": "789", "style": "color: blue;"});

As you see, you can pass the object directly to the function no need to assign it to variable first.

Also, to have the object properties applied in the DOM element you have to use setAttribute() otherwise those properties won't be part of the DOM.

In the above code, the template has the same class for all instances, so you can apply some CSS to affect them all e.g.

.myprop { font-weight: bold; }​

​Live test case.

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

2 Comments

This code is not exactly what I need, but it got me thinking about new ways to accomplish this task that I hadn't thought of before. If I do figure out a way to do this, I will post it.
Cheers, not sure what you need then so please update me if you figure a better way. :)
1

The concept of "adding a JS object to the DOM" really doesn't make any sense, and in fact your code is not doing so, it is creating a new <prop> element and assigning it properties from your object. I don't see the point of that: what do you expect the browser to do with a <prop> element?

Anyway, moving on to your question about how to not have to return an object from the function and assign it back to your variable, you can't. JavaScript passes arguments by value - where in this case the "value" is a reference to an object. You can change the properties of the object, but can't make the variable that was passed in point to some other object. (Obviously you can make the declared parameter obj point to some other object, as you are doing.)

But this leads to a possible workaround that might help you: how about instead you simply add a property to the existing object, with the new property referencing the DOM object -

function addToDOM(obj) {
    var temp = document.createElement('prop');
    document.body.appendChild(temp);
    for (var p in obj) {
        temp[p] = obj[p];
    }
    obj.myDOMElement = temp;
}

var obj = {var1:123};
//No obj=
addToDOM(obj);
// obj now has a property myDOMElement that references the DOM element

Note that I have simplified your function somewhat: you don't need to copy all of the obj properties into temp and then copy all the properties back to obj after you reassign obj to the new DOM element. (Even if you decided to stay with your current code's idea of returning the new object you can use my simplified form and just return temp.)

And note that you should declare your variables with var or they will be global.

1 Comment

Very good and thought out answer. I am trying to develop getter/setter methods that work in IE6+. They work in all browsers with my polyfill as long as I include obj = addToDOM(obj) after defining what obj is. Since they are getter and setter methods I have to be able to detect when the object is being accessed and in IE 6/7/8 this can only be done when the object is in the DOM. I wanted to do that automatically for all occurances in the script so it wouldn't have to be written out every time a getter or setter is applied.

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.