Question

when we appendChild in B.js,there is an undefined error!

//sample code    
//A.js
this.node = document.getElementById("area");
window.open("B.html");

//B.js
document.getElementById("area").appendChild(window.opener.node);
Was it helpful?

Solution

The document in B.js is a different #document to the one in A.js. This means window.opener.node is a Node from a different #document and therefore you have to call document.importNode on it before you can use it here

// B.js
var node = document.importNode(window.opener.node, /* deep */ true);
document.getElementById("area").appendChild(node);

Please note that this new Node is a copy, if you have large structures you may wish to also destroy the original.


If you want to support old IE browsers that have reached their end of life, here are some shims


Using a <div> and setting it's innerHTML

if (!document.importNode) {
    document.importNode = function (node, deep) {
        var wrapper_old = node.ownerDocument.createElement('div'),
            wrapper_new = document.createElement('div');
        wrapper_old.appendChild(node.cloneNode(!!deep));
        wrapper_new.innerHTML = wrapper_old.innerHTML;
        return wrapper_new.removeChild(wrapper_new.firstChild);
    };
}

It should work on everything that can be a child of <div>


Invoking cloneNode from your new #document (I haven't tested it)

if (!document.importNode) {
    document.importNode = function (node, deep) {
        return Node.prototype.cloneNode.call(node, !!deep);
    };
}

Assuming it works, it will work for more Nodes, but will drop id attributes.


A custom import/clone function (this will clone id attributes)

if (!document.importNode) {
    document.importNode = function (node, deep) {
        var e, i, a;
        if (node.nodeType === 3) // #text
            return document.createTextNode(node.data);
        if (node.nodeType === 8) // #comment
            return document.createComment(node.data);
        if (node.nodeType !== 1) // #document/other
            throw new TypeError('Unsupported nodeType: ' + node.nodeType);
        // Element
        e = document.createElement(node.tagName);
        a = node.attributes;
        for (i = 0; i < a.length; ++i) {
            e.setAttribute(a[i].name, a[i].value);
        }
        if (deep)
            for (i = 0; i < node.childNodes.length; ++i) {
                e.appendChild(clone(node.childNodes[i]));
            }
        return e;
    };
}

OTHER TIPS

Surely you will get and undefined error. Because there are 2 different files. The new opened window does not have access to the other HTML elements(say A.html).

The element with id area should be present in the HTML. Otherwise it will give undefined error. you can try with iframe you can access the elements of iframe and you can append data to the node.

window.frames['iframe'].document.getElementsByTagName('body')

The following works fine in Chrome and Firefox. Notice that the "area" div is removed from A.html

A.html

<html>
<body>
<div id="area">test</div>
<script>
this.node = document.getElementById("area");
window.open("B.html");
</script>
</body>
</html>

And B.html

<html>
<body>
<div id="area1"></div>
<script>
document.getElementById("area1").appendChild(window.opener.node);
</script>
</body>
</html>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top