Вызов родительской оконной функции из iframe

Я хочу вызвать функцию JavaScript родительского окна из iframe.

<script>
    function abc()
    {
        alert("sss");
    }
</script>

<iframe id="myFrame">
    <a onclick="abc();" href="#">Call Me</a>
</iframe>

11 ответов

Решение
<a onclick="parent.abc();" href="#" >Call Me </a>

Смотрите window.parent

Возвращает ссылку на родителя текущего окна или подкадра.

Если у окна нет родителя, его родительское свойство является ссылкой на себя.

Когда окно загружается в <iframe>, <object>, или же <frame>, его родитель - это окно с элементом, внедряющим окно.

Window.postMessage()

Этот метод позволяет безопасно cross-origin коммуникации.

И если у вас есть доступ к коду родительской страницы, то любой родительский метод может быть вызван, а любые данные могут быть переданы непосредственно из Iframe, Вот небольшой пример:

Родительская страница:

if (window.addEventListener) {
    window.addEventListener("message", onMessage, false);        
} 
else if (window.attachEvent) {
    window.attachEvent("onmessage", onMessage, false);
}

function onMessage(event) {
    // Check sender origin to be trusted
    if (event.origin !== "http://example.com") return;

    var data = event.data;

    if (typeof(window[data.func]) == "function") {
        window[data.func].call(null, data.message);
    }
}

// Function to be called from iframe
function parentFunc(message) {
    alert(message);
}

Код iframe:

window.parent.postMessage({
    'func': 'parentFunc',
    'message': 'Message text from iframe.'
}, "*");

Рекомендации:

Недавно мне пришлось выяснить, почему это тоже не сработало.

Javascript, который вы хотите вызвать от дочернего элемента, должен находиться в голове родителя. Если он находится в теле, сценарий недоступен в глобальной области видимости.

<head>
    <script>
    function abc() {
        alert("sss");
    }
    </script>
</head>
<body>
    <iframe id="myFrame">
        <a onclick="parent.abc();" href="#">Click Me</a>
    </iframe>
</body>

Надеюсь, что это поможет любому, кто снова столкнется с этой проблемой.

Я разместил это как отдельный ответ, поскольку он не связан с моим существующим ответом.

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

На этот раз ответ состоял в том, чтобы изменить document.domain родительской страницы и iframe, чтобы они были одинаковыми. Это обманет те же проверки политики происхождения, что они будут сосуществовать в одном и том же домене (субдомены считаются другим хостом и не пройдут ту же проверку политики происхождения).

Вставьте следующее в <head> страницы в iframe, чтобы соответствовать родительскому домену (настройте для вашего типа документа).

<script>
    document.domain = "mydomain.com";
</script>

Обратите внимание, что это приведет к ошибке при разработке localhost, поэтому используйте проверку, подобную следующей, чтобы избежать ошибки:

if (!window.location.href.match(/localhost/gi)) {
    document.domain = "mydomain.com";
} 

Ты можешь использовать

window.top

смотрите следующее.

<head>
    <script>
    function abc() {
        alert("sss");
    }
    </script>
</head>
<body>
    <iframe id="myFrame">
        <a onclick="window.top.abc();" href="#">Click Me</a>
    </iframe>
</body>

parent.abc() будет работать только на одном домене в целях безопасности. Я попробовал этот обходной путь, и мой работал отлично.

<head>
    <script>
    function abc() {
        alert("sss");
    }

    // window of the iframe
    var innerWindow = document.getElementById('myFrame').contentWindow;
    innerWindow.abc= abc;

    </script>
</head>
<body>
    <iframe id="myFrame">
        <a onclick="abc();" href="#">Click Me</a>
    </iframe>
</body>

Надеюсь это поможет.:)

Еще одно дополнение для тех, кому это нужно. Решение Эша Кларка не работает, если они используют разные протоколы, поэтому будьте уверены, что если вы используете SSL, то ваш iframe также использует SSL, или это нарушит функцию. Его решение действительно работает на домены, так что спасибо за это.

Решение Ash Clarke для поддоменов прекрасно работает, но учтите, что вам нужно включить document.domain = "mydomain.com"; как в заголовке страницы iframe, так и в заголовке родительской страницы, как указано в ссылке, одни и те же проверки политики происхождения

Важное расширение той же политики происхождения, реализованной для доступа к DOM JavaScript (но не для большинства других разновидностей проверок одного и того же происхождения), заключается в том, что два сайта, совместно использующие общий домен верхнего уровня, могут предпочесть связь, несмотря на отказ "одного хоста" проверьте путем взаимной установки соответствующего свойства DOM document.domain к тому же квалифицированному правому фрагменту их текущего имени хоста. Например, если http://en.example.com/ и http://fr.example.com/ оба установят document.domain в "example.com", они будут с этого момента считаться одним источником для цель манипулирования DOM.

С Firefox и Chrome вы можете использовать:

<a href="whatever" target="_parent" onclick="myfunction()">

Если myfunction присутствует и в iframe, и в parent, будет вызвана родительская функция.

Хотя некоторые из этих решений могут работать, ни одно из них не следует передовой практике. Многие присваивают глобальные переменные, и вы можете вызывать несколько родительских переменных или функций, что приводит к загроможденному и уязвимому пространству имен.

Чтобы избежать этого, используйте шаблон модуля. В родительском окне:

var myThing = {
    var i = 0;
    myFunction : function () {
        // do something
    }
};

var newThing = Object.create(myThing);

Затем в iframe:

function myIframeFunction () {
    parent.myThing.myFunction();
    alert(parent.myThing.i);
};

Это похоже на паттерны, описанные в главе "Наследование" оригинального текста Крокфорда "Javascript: The Good Parts". Вы также можете узнать больше на странице w3 о лучших методах работы с Javascript. https://www.w3.org/wiki/JavaScript_best_practices

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

https://gist.github.com/clinuxrulz/77f341832c6025bf10f0b183ee85e072

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

Другие вопросы по тегам