Закрыть кросс-домен iframe - PullRequest
       8

Закрыть кросс-домен iframe

10 голосов
/ 02 февраля 2010

Я пытаюсь сделать что-то похожее на приложение Clipper здесь http://www.polyvore.com/cgi/clipper

Я могу сделать так, чтобы iframe появился на другом веб-сайте (кросс-домен). Но я не могу заставить работать кнопку "Закрыть".

Это то, что я использовал, но оно не работает для междоменных доменов (в основном, удаляют элемент iframe)

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

Вы можете помочь? Спасибо.

Ответы [ 3 ]

19 голосов
/ 02 февраля 2010

Вы должны использовать библиотеку, которая абстрагирует это (например, http://easyxdm.net/wp/, не тестировалась). Обмен сообщениями с идентификаторами фрагментов может работать не во всех браузерах, поэтому существуют более подходящие подходы, например postMessage .

Тем не менее, в вашем примере (Clipper) используется хак под названием фрагмент идентификации сообщения . Это может быть кросс-браузер, при условии, что страница с вашим iframe является верхним уровнем. Другими словами, существует всего два уровня. По сути, дочерний элемент устанавливает фрагмент родительского элемента, и родительский элемент следит за этим.

Это аналогично подходу Клипера:

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: междоменный и независимый контроль отличаются. Я копался в (сильно минимизированном / запутанном) коде Polyvore, чтобы посмотреть, как он работает (кстати, в Firefox этого нет). Сначала помните, что букмарклеты, такие как Clipper, живут в контексте страницы, открытой при запуске. В этом случае букмарклет загружает скрипт , который, в свою очередь, запускает функцию init, которая генерирует iframe , но также запускает:

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

Если вы покопаетесь в addListener, вы найдете ( beauified ):

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

отмена включает в себя:

removeNode(iframe);

Теперь единственная оставшаяся часть состоит в том, что страница iframe загружает другой скрипт с функцией ClipperForm.init, которая включает в себя:

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

Итак, мы ясно видим, что они используют обмен сообщениями по фрагментам.

1 голос
/ 02 февраля 2010

Попробуйте скрыть содержимое iframe и не беспокойтесь о том, чтобы фактически избавиться от элемента iframe в родительском элементе.

0 голосов
/ 23 ноября 2010

Есть еще одна реализация старого хеш-хака.Он обратно совместим, легок только для JavaScript и очень прост в реализации:

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

...