Обработка обратного вызова, когда вызывающий кадр (и контекст выполнения) исчезли - PullRequest
1 голос
/ 03 мая 2011

Предположим, у вас есть два фрейма, A и B (или страница с фреймом).В A есть функция foo(), которая после завершения вызывает обратный вызов.Сценарий в B вызывает foo() из A, но до его завершения (и вызывает обратный вызов из B), src B полностью заменяется, так что обратный вызов больше не имеет контекста выполнения.В большинстве браузеров это приводит к некоторой ошибке.

Есть ли способ обнаружить, что обратный вызов происходит из среды выполнения, которая больше не имеет контекста выполнения и, следовательно, не должна вызываться?

Вот страница упаковки:

<html>
<head>
    <script>
        var load = function() {
            document.getElementById("link").onclick = function(){
                document.getElementById("iframe").src = "test-exec-context-frame-src.html";
                return(false);
            };
        };
        var frameLoad = function(cb) {
            // kill the frame and then callback
            document.getElementById("iframe").src = "http://www.google.com";
            cb();
        };
    </script>
</head>
<body onload="load();">
    <div>This is the first div, click <a id="link" href="#">here</a> to start</div>
    <iframe id="iframe"></iframe>
</body>

А вот страница управления iframe:

<html>
<head>
    <script>
        var load2 = function() {
            document.getElementById("link").onclick = function(){
                top.frameLoad(function(){
                    console.log("I am done");
                });
            };
        };
    </script>
</head>
<body onload="load2();">
    <div>This is the internal frame. Click <a href="#" id="link">here</a> to force the callback.</div>
</body>

Нажмите на ссылку вНа первой странице iframe загружается со второй исходной страницей.Нажмите на ссылку на второй странице, она вызывает top.frameLoad с обратным вызовом.Перед выполнением обратного вызова iframe src изменяется на www.google.com, разрушая контекст выполнения для обратного вызова.Обратный вызов запускается и создает ошибку.

Как мы можем проверить контекст выполнения обратного вызова - или, возможно, вызывающей функции - перед попыткой выполнить обратный вызов?

(Игнорировать форматированиеиспользование глобальных переменных, тот факт, что jquery справится с этим лучше, чем document.getElementById и т. д. Это всего лишь тест.)

1 Ответ

1 голос
/ 04 мая 2011

Я не знаю, как проверить, не исчез ли контекст выполнения, но мне приходят на ум два решения:

  1. Поместить обратный вызов в try / catch и игнорироватьлюбое исключение.

  2. Определите функцию обратного вызова в том же кадре, что и ваша frameLoad функция, поэтому из фрейма ваш вызов на frameLoad будет выглядеть так: top.frameLoad(top.someCallbackFunction);

Если вы знаете, что весь смысл функции frameLoad состоит в замене содержимого iframe, определяющего обратный вызов, тогда зачем вообще использовать обратный вызов?Любой нетривиальный обратный вызов захочет взаимодействовать с оригинальным контентом, не так ли?Не могли бы вы достичь чего-то подобного, определив onunload в документе, который изначально был внутри iframe?

ОБНОВЛЕНИЕ:

Когда я предложил попробовать / поймать, я имел в виду в сценарии вашего родительского документа, какэто:

var frameLoad = function(cb) {
   // kill the frame and then callback
   document.getElementById("iframe").src = "http://www.google.com";
   try {
      cb();
   } catch(e) {
      // callback didn't work; do something if necessary
   }
}; 

Вы также можете попробовать if (cb != undefined) cb(); или аналогичный.

...