views:

42

answers:

2

I have this script, which I thought was relatively simple. It basically makes a tree-layout of an iframe's contents. When parts of the tree are hovered, their corresponding iframe elements are 'selected'. But it isn't working, for the life of me. Here is some quick half-pseudo code:

function traverseTree(c,o){
    //c = the tree subset to put more stuff in
    //o = the element to traverse
    var treeNode = D.createElement('div');
    c.appendChild(treeNode);
    treeNode.innerHTML = o.tagName;
    treeNode['refNode'] = o;
    treeNode.addEventListener('mouseover',check,false);
    loop(o.children){
        traverseTree(treeNode,o.child);
    }
}
function check(e){
    alert(e.target.refNode);
}

The problem occurs with e.target.refNode. It only gives an element reference with the first node (or the HTML tag). The rest are undefined. But, when I check treeNode.refNode right after setting it, it is always right.

EDIT:

So, I made a quick test:

<html>
<head>
    <title>Test</title>
    <script>
        window.onload = function(){
            createTree(document.getElementById('tree'),
                document.getElementById('page').contentWindow.document);
        }

        function createTree(c,o){
            //get list of children
            var children = o.childNodes;
            //loop through them and display them
            for (var i=0;i<children.length;i++){
                if (typeof(children[i].tagName) !== 'undefined'){
                    //Create a tree node
                    var node = document.createElement('div');
                    if (children[i].childNodes.length > 0){
                        node.style.borderLeft = '1px dotted black';
                        node.style.marginLeft = '15px';
                    }
                    c.appendChild(node);
                    //Reference to the actual node
                    node.refNode = children[i];
                    //Add events
                    node.addEventListener('mouseover',selectNode,false);
                    //Display what type of tag it is
                    node.innerHTML += "&lt;"+children[i].tagName.toLowerCase()+"&gt;";
                    //Add in its child nodes
                    createTree(node,children[i]);
                    //ending tag... CRASHES THE PROGRAM
                    node.innerHTML += "&lt;/"+children[i].tagName.toLowerCase()+"&gt;";
                }
            }
        }

        function selectNode(e){
            document.getElementById('info').innerHTML = e.target.refNode;
        }
    </script>
</head>
<body>
    <iframe id='page' src='some_page.html'></iframe>
    <div id='info' style='border-bottom:1px solid red;margin-bottom:10px;'></div>
    <div id='tree'></div>
</body>
</html>

and I figured out that adding innerHTML after appending the child tree nodes was taking away the children's refNode property. So, that's where the problem is occurring.

A: 

You cannot store objects in attributes of elements. What you see if you check the attribute is the string-representation of the assigned node. If you would use jquery, you could implement that with jQuery.data()

Dr.Molle
No, but you can store objects as properties of an element. Paste this into the address bar of your browser: javascript: var o = document.body.appendChild(document.createElement("div")); o['foo'] = { prop: "value" }; alert(o.foo.prop);
gilly3
If you think, adding properties is an good idea, take a look at this: http://perfectionkills.com/whats-wrong-with-extending-the-dom/
Dr.Molle
Well, minor DOM extensions won't really matter in the long run, especially if it won't be distributed, like my script is.
Azmisov
So you will still have to check if the browsers you will use this script inside(and the addons/plugins too) does already use the property-name.
Dr.Molle
A: 

So, I guess the solution would just be to change .innerHtml to .appendChild(document.createTextNode(...)). My script is only for local use, and only built for FF3+, so other than that, there should be no problems.

Azmisov