开发者

Handle a callback when the calling frame (and execution context) has disappeared

开发者 https://www.devze.com 2023-03-02 19:21 出处:网络
Let us assume you have two frames, A and B (or a page with an iframe). A has a function foo() in it that, when complete, calls a callbac开发者_C百科k. A script in B calls foo() from A, but before it c

Let us assume you have two frames, A and B (or a page with an iframe). A has a function foo() in it that, when complete, calls a callbac开发者_C百科k. A script in B calls foo() from A, but before it completes (and calls the callback from B), B's src is replaced entirely, so that the callback no longer has an execution context. In most browsers, this will generate some sort of error.

Is there any way to detect that the callback is from a runtime that no longer has execution context, and thus should not be called?

Here is the wrapping page:

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

And here is the iframe src page:

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

Click on the link in the first page, the iframe is loaded with the second source page. Click on the link in the second page, it calls top.frameLoad with a callback. Before the callback is run, the iframe src gets changed to www.google.com, destroying the execution context for the callback. The callback is run and creates an error.

How can we check the execution context of the callback - or perhaps of the calling function - before attempting to execute the callback?

(Ignore the formatting, use of global vars, the fact that jquery would handle it better than document.getElementById, etc. This is just a test.)


I don't know how to check if the execution context is gone, but two workarounds that occur to me are:

  1. Put the callback call in a try/catch and ignore any exception.

  2. Define the callback function in the same frame as your frameLoad function so then from the iframe your call to frameLoad will look like this: top.frameLoad(top.someCallbackFunction);

If you know the whole point of the frameLoad function is to replace the contents of the iframe that defines the callback then why use a callback at all? Any non-trivial callback is going to want to interact with the original content isn't it? Could you achieve something similar by defining an onunload in the document that was originally within the iframe?

UPDATE:

When I suggested a try/catch I meant in your parent document script like this:

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
   }
}; 

You could also try if (cb != undefined) cb(); or similar.

0

精彩评论

暂无评论...
验证码 换一张
取 消