我一直在玩 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并使用 === 检查窗口,但这看起来有点傻。有更好的方法吗?
答案 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 = " ";
} 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>