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

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

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

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

Ответ 1

<a onclick="parent.abc();" href="#" >Call Me </a>

См. window.parent

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

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

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

Ответ 2

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

javascript, который вы хотите вызвать из дочернего iframe, должен находиться во главе родителя. Если он находится в теле, script недоступен в глобальной области.

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

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

Ответ 3

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.'
}, "*");
// Use target origin instead of *

ОБНОВЛЕНИЕ:

Примечание по безопасности:

Всегда указывайте конкретный targetOrigin, НЕ *, если вы знаете, где должен находиться другой документ окна. Если не указать конкретную цель, раскрываются данные, которые вы отправляете на любой заинтересованный вредоносный сайт (комментарий ZalemCitizen).

Ссылки:

Ответ 4

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

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

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

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

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

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

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

Ответ 5

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

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>

Ответ 6

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

Ответ 7

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

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

Ответ 8

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>

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

Ответ 9

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

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

Если myfunction присутствует как в iframe, так и в родительском, будет вызываться родительский.

Ответ 10

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

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

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#Avoid_globals