给定一个iframe窗口,是否可以轻松访问拥有的iframe?

时间:2011-11-28 00:58:23

标签: javascript

我一直在玩 postMessage ,只是为了更好地理解它是如何工作的,使用以下示例:

http://hashcollision.org/tmp/hello-iframe.html

稍微详细一点:对于邮件中的每个字符,这会构造一个来自http://hashcollision.org/tmp/hello-iframe-inner.html的iframe。然后我使用postMessage与每个iframe进行通信,告诉它要显示什么字符。此外,iframe也通过postMessage将iframe的几何体传递回父页面。这一切都没用,但它是一个可爱的测试页面。

目前尴尬的一个问题是,在iframe窗口的情况下,找到拥有的iframe。

我正在做 for 循环来遍历我的所有iframe并使用 === 检查窗口,但这看起来有点傻。有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

不,没有。 (而且我不确定除此之外该说些什么,你已经做到了最好的事情。)

答案 1 :(得分:0)

我能想出的最佳解决方案是:为每个iframe生成一个随机标识符。在iframe和父窗口之间的所有通信中,iframe将在postMessage的内容中包含其“self”标识符。这允许父母在收到消息时快速轻松地查找。

以下是修改后的示例, hello-iframe.html 的内容为:

<html>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>
<script>

var run = function() {
    var msg = "Hello world, this is a test of the emergency broadcast system.";
    var i;
    document.body.appendChild(document.createElement("hr"));
    for (i = 0; i < msg.length; i++) {
        spawnCharacterIframe(msg.charAt(i));
    }
    document.body.appendChild(document.createElement("hr"));
};

var _gensymCounter = 0;
var gensym = function() {
    var result = [], i;
    var LEN = 32;
    result.push((_gensymCounter++) + "_");
    var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
    for (i = 0; i < LEN; i++) {
        result.push(chars.charAt(Math.floor(Math.random() * chars.length)));
    }
    return result.join('');
};

var spawnCharacterIframe = function(ch, id) {
    id = id || gensym();
    var newIframe = document.createElement("iframe");
    newIframe.setAttribute("frameborder", "0");
    newIframe.setAttribute("border", "0px");
    newIframe.setAttribute("width", "0px");
    newIframe.setAttribute("height", "0px");
    newIframe.setAttribute("src", "hello-iframe-inner.html?selfId=" + encodeURIComponent(id));
    newIframe.setAttribute("id", id);
    $(newIframe).data('ch', ch);
    document.body.appendChild(newIframe);
};

var findIframe = function(w) {
    var found;
    $('iframe').each(function() {
        if (this.contentWindow == w) {
            found = this;
        }  
    });
    return found;
};



$(window).on('message',
             function(e) {
                 var data = e.originalEvent.data;
                 var source = e.originalEvent.source;
                 var iframe, sourceId;

                 if(data.match(/^([^,]+)[,](.+)$/)) {
                     sourceId = RegExp.$1;
                     data = RegExp.$2;
                     if (document.getElementById(sourceId)) {
                         iframe = document.getElementById(sourceId);
                     } else {
                         return;
                     }
                 } else {
                     return;
                 }

                 if (data === 'ready') {
                     iframe.contentWindow.postMessage($(iframe).data('ch'), '*');
                 } else if (data.match(/^(\d+),(\d+)$/)) {
                     var w = RegExp.$1;
                     var h = RegExp.$2;
                     if (iframe.width !== w + 'px') {
                         iframe.width = w + "px";
                     }
                     if (iframe.height !== h + 'px') {
                         iframe.height = h + "px";
                     }
                 }
             });


$(document).ready(run);
</script>
<body>
<h1>testing iframes</h1>
</body>
</html>

hello-iframe-inner.html 的内容为:

<html><head></head>
<script>

// http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
var urlParams = {};
(function () {
    var e,
        a = /\+/g,  // Regex for replacing addition symbol with a space
        r = /([^&=]+)=?([^&]*)/g,
        d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
        q = window.location.search.substring(1);

    while (e = r.exec(q))
       urlParams[d(e[1])] = d(e[2]);
})();


var SELF_ID = urlParams.selfId;
window.addEventListener("message",
         function(e) {
             if (e.data === ' ') {
                 document.body.innerHTML = "&nbsp;";
             } else {
                 document.body.appendChild(
                     document.createTextNode(e.data));
             }
         });


window.onload = function() {
    document.body.style.margin = '0px';
    var w, h;
    if (window.parent && SELF_ID) {
        window.parent.postMessage(SELF_ID + ',ready', '*');

        setInterval(function() {
            if (h !== document.body.scrollHeight ||
                w !== document.body.scrollWidth) {
                w = document.body.scrollWidth;
                h = document.body.scrollHeight;
                if (window.parent) {
                    window.parent.postMessage(SELF_ID + ',' + w + ',' + h, '*');
                }
            }
        }, 1000);
    }
};

</script>
<body></body>
</html>