Ticket #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: | ||
| Blocking: | Blocked by: |
Description (last modified by jitter) (diff)
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
comment:1 Changed 4 years ago by dmethvin
- Priority changed from major to minor
- Component changed from unfilled to core
comment:2 Changed 3 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 3 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 3 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:7 Changed 3 years ago by snover
- Keywords needsreview bikeshed added
- Priority changed from minor to low
- Version changed from 1.3.1 to 1.4.3
- Milestone 1.3.2 deleted
comment:9 Changed 2 years ago by jitter
- Version changed from 1.4.3 to 1.4.4
- Description modified (diff)
- Milestone set to 1.next
comment:10 Changed 2 years ago by jitter
#8010 is a duplicate of this ticket.
comment:11 Changed 2 years ago by dmethvin
- Keywords needsreview bikeshed removed
- Status changed from new to closed
- Resolution set to wontfix
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?
Please follow the bug reporting guidlines and use jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.
