Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
203 views
in Technique[技术] by (71.8m points)

javascript - Close iframe cross domain

I am trying to do something similar to the Clipper application here http://www.polyvore.com/cgi/clipper

I can make the iframe appear in another website (cross domain). But I cannot make the "close" button to work.

This is what I used but it doesn't work for cross domain (basically remove the iframe element)

window.parent.document.getElementById('someId').parentNode.removeChild(window.parent.document.getElementById('someId'));    

Can you help? Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should use a library that abstracts this (e.g. http://easyxdm.net/wp/ , not tested). Fragment ID messaging may not work in all browsers, and there are better approaches, such as postMessage.

However, your example (Clipper) is using a hack called fragment id messaging. This can be cross-browser, provided the page containing your iframe is the top level. In other words, there are a total of two levels. Basically, the child sets the fragment of the parent, and the parent watches for this.

This is a similar approach to Clipper's:

parent.html

<html>
<head>
<script type="text/javascript">
function checkForClose()
{
    if(window.location.hash == "#close_child")
    {
      var someIframe = document.getElementById("someId");
      someIframe.parentNode.removeChild(someIframe);
    }
    else
    {
      setTimeout(checkForClose, 1000)
    }
}
setTimeout(checkForClose, 1000);
</script>
</head>
<body>
<iframe name="someId" id="someId" src="child.html" height="800" width="600">foo</iframe>
</body>
</html>

child.html:

<html>
<head>
<script type="text/javascript">
setTimeout(function(){window.parent.location.hash = "close_child";}, 5000);
</script>
<body style="background-color: blue"></body>
</html>

EDIT2: Cross-domain and independently controlled are different. I dug into the (heavily minified/obfuscated) Polyvore code to see how it works (incidentally, it doesn't in Firefox). First remember that bookmarklets, such as the Clipper, live in the context of the page open when they start. In this case, the bookmarklet loads a script , which in turn runs an init function which generates an iframe, but also runs:

Event.addListener(Event.XFRAME, "done", cancel);

If you digg into addListener, you'll find (beautified):

if (_1ce2 == Event.XFRAME) {
                        if (!_1cb3) {
                            _1cb3 = new Monitor(function () {
                                return window.location.hash;
                            },
                            100);
                            Event.addListener(_1cb3, "change", onHashChange);
                        }
                    } 

cancel includes:

removeNode(iframe);

Now, the only remaining piece is that the iframe page loads another script with a ClipperForm.init function that includes:

Event.addListener($("close"), "click", function () {
            Event.postMessage(window.parent, _228d, "done");
        });

So we see clearly they are using fragment ID messaging.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...