Bug Tracker

Opened 14 years ago

Closed 12 years ago

#4059 closed bug (wontfix)

AppendTo not working under IE7 when select element from another frame.

Reported by: fournaise Owned by:
Priority: low Milestone: 1.next
Component: manipulation Version: 1.4.4
Keywords: Cc:
Blocked by: Blocking:

Description (last modified by jitter)

Hello, I have 2 frames; in bottom frame I select a element in the other frame and try to append the selected element to a existing element in the bottom frame. Works under FF3, but failed in IE6 and IE7.

Hereafter the test :

--- index.html ---

<frameset rows="50%,50%" >
   <frame src="haut.html" name="haut" frameborder="yes">
   <frame src="bas.html" name="bas" frameborder="yes">
</frameset>

--- haut.html ----

<html><head></head>
<body>
<div class="classRecup">TEST</div>
</body>
</html>

--- bas.html ---

<html><head>
<script language="javascript" src="jquery-1.3.1.min.js"></script>
<script language="javascript">
$().ready(function() {
	$(".classRecup",parent.haut.document).appendTo("#divTitrePage");
});
</script>
</head>
<body><div id="divTitrePage" style="border:solid 1px blue">Mon texte :</div>
</body>
</html>

Change History (11)

comment:1 Changed 14 years ago by dmethvin

Component: unfilledcore
Priority: majorminor

comment:2 Changed 13 years ago by aakoch

I was able to reproduce this error in jQuery 1.3.2 and 1.4.1. The error is "htmlfile: Invalid argument." This sounds like the same issue encountered in bug #4348.

I have another example of this behavior between a parent document and a child document within an iframe.

parent.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
<title>Parent</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.js" type="text/javascript"></script>

</head>

<body>
<iframe src="child.html" id="childIframe"></iframe>

<script type="text/javascript">
$("#childIframe").load(function () {
    var childElements = $(this).contents().find(".pullup");
    //childElements.appendTo("body");
    $("body").append(childElements);
});
</script>

</body>
</html>

child.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
<title>Child</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.js" type="text/javascript"></script>

</head>

<body>

Child
<div class="pullup">Pull-up Element</div>
<div class="pushup">Push-up Element</div>

<script type="text/javascript">
$(".pullup").add(".pushup").mouseover(function () {
    $(this).append(".");
});
$(function () {
    var childElements = $(this).find(".pushup"),
        topBody = top.jQuery("body");
    //childElements.appendTo(topBody);
    topBody.append(childElements);
});
</script>

</body>
</html>

Both trying to pull the elements up from the parent and pushing the elements up from the child both fail in the "clean" method with the error "htmlfile: Invalid argument." in IE7. The code works fine in FF 3.5.

Here's part of the stack:

append
domManip
clean - line "fragment.appendChild( ret[i] );}}}"

comment:3 Changed 13 years ago by aakoch

I believe the problem is because you cannot appendChild when the fragment and the element (ret[i] in this case) don't have the same ownerDocument. You have to use importNode or adoptNode and IE7 doesn't support these. I'm looking into a solution like the one found at http://www.alistapart.com/articles/crossbrowserscripting/.

More on my research can be found here: http://stackoverflow.com/questions/2284356/cant-appendchild-to-a-node-created-from-another-frame/2291553#2291553

comment:4 Changed 13 years ago by aakoch

I was able to fix this by changing fragment.appendChild( ret[i] ); on line 4500 to

if (document.adoptNode || fragment.ownerDocument == ret[i].ownerDocument) {
    fragment.appendChild( ret[i] );
}
else {
    fragment.appendChild(_importNode(fragment, ret[i], true ));
    ret[i].parentNode.removeChild(ret[i]);
}

and adding this function

_importNode = function(document, node, allChildren) {
	/* find the node type to import */
	switch (node.nodeType) {
		case 1:
			/* create a new element */
			var newNode = document.createElement(node.nodeName);
			/* does the node have any attributes to add? */
			if (node.attributes && node.attributes.length > 0)
				/* add all of the attributes */
				for (var i = 0, il = node.attributes.length; i < il;)
					newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName));
			/* are we going after children too, and does the node have any? */
			if (allChildren && node.childNodes && node.childNodes.length > 0)
				/* recursively get all of the child nodes */
				for (var i = 0, il = node.childNodes.length; i < il;)
					newNode.appendChild(_importNode(document, node.childNodes[i++], allChildren));
			return newNode;
			break;
		case 3:
		case 4:
		case 8:
			return document.createTextNode(node.nodeValue);
			break;
	}
};

comment:5 Changed 13 years ago by dmethvin

Component: coremanipulation

comment:6 Changed 12 years ago by snover

#6840 is a duplicate of this ticket.

comment:7 Changed 12 years ago by snover

Keywords: needsreview bikeshed added
Milestone: 1.3.2
Priority: minorlow
Version: 1.3.11.4.3

comment:8 Changed 12 years ago by jitter

#2253 is a duplicate of this ticket.

comment:9 Changed 12 years ago by jitter

Description: modified (diff)
Milestone: 1.next
Version: 1.4.31.4.4

comment:10 Changed 12 years ago by jitter

#8010 is a duplicate of this ticket.

#8010 holds additional http://jsfiddle.net test cases

Last edited 12 years ago by jitter (previous) (diff)

comment:11 Changed 12 years ago by dmethvin

Keywords: needsreview bikeshed removed
Resolution: wontfix
Status: newclosed

There are many other issues with trying to manipulate elements across a frame boundary, including memory leaks and security issues if the frame navigates to a different domain. Perhaps someone could write a plugin to do this safely?

Note: See TracTickets for help on using tickets.