Iframe

# Iframe

参考教程:[iframe,我们来谈一谈 (opens new window)]

[TOC]

# 一、认识 iframe

  • iframe - 内联框架,能够将另一个HTML页面嵌入到当前页面中。

# 1.1 优缺点

# 1.1.1 优点

# 1.1.2 缺点

  • iframe会阻塞主页面的Onload事件。
  • iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。

如果需要使用iframe,最好是通过javascript 动态给iframe添加src属性值,这样可以绕开以上两个问题。

  • 搜索引擎的检索程序无法解读这种页面,不利于SEO。

# 1.2 常用的属性

  • frameborder:是否显示边框,1(yes),0(no)。
  • height:框架作为一个普通元素的高度,建议在使用css设置。
  • width:框架作为一个普通元素的宽度,建议使用css设置。
  • name:框架的名称,window.frames[name]时专用的属性。
  • scrolling:框架的是否滚动。yes,no,auto。
  • src:内框架的地址,可以使页面地址,也可以是图片的地址。
  • srcdoc , 用来替代原来HTML body里面的内容。但是IE不支持。
  • sandbox: 对iframe进行一些列限制,IE10+支持。

# 二、HelloWorld

# 2.1 简单示例

  • hello.html
<iframe src="./test.html" frameborder="1"></iframe>
1
  • test.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        body{
            margin: 0;
        }
        .ide{
            display: flex;
        }
        textarea{
            flex: 1;
        }
        iframe{
            width: 100%;
        }
    </style>
</head>
<body>
    <div class="ide">
        <textarea placeholder='HTML' id='h'></textarea>
        <textarea placeholder='CSS' id='c'></textarea>
        <textarea placeholder='JS' id='j'></textarea>
    </div>
    <iframe id=i></iframe>
    <script>
        document.oninput = () => {
            i.srcdoc = `${h.value}<style>${c.value}</style><script>${j.value}</srcipt>`;
        }
    </script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 2.2 获取信息

  • 获取当前的父窗口对象。

    • 如果一个窗口没有父窗口,则它的 parent 属性为自身的引用。
    • 如果当前窗口是一个 <iframe>, <object>, 或者 <frame>,则它的父窗口是嵌入它的那个窗口。
let parentWindow = window.parent;
1
  • 获取iframe元素的window对象。
    • 可以使用这个Window对象来访问iframe的文档及其内部DOM。
    • contentWindow为只读,但是可以像操作全局Window对象一样操作其属性。
let frame = document.getElementsByTagName('iframe')[0].contentWindow;
1

# 2.3 动态嵌入iframe

let frame = document.createElement("iframe");
frame.name = 'newFrame';
frame.name="showframe" ;
frame.width="195";
frame.height="126";
frame.marginwidth="0"; 
frame.marginheight="0"; 
frame.hspace="0";
frame.vspace="0";
frame.frameborder="0";
frame.scrolling="no";
frame.src='';
$('body').appendChild(frame);
1
2
3
4
5
6
7
8
9
10
11
12
13

如果使用innerHTML的话可显示内容

# 三、跨域示例

# 3.1 前端部分

  • staticReq/index.html
<div id="father">
    <p>这里3000端口</p>
    <input type="text"/>
    <button>发送信息</button>
    <p style="text-align: left;">message :  <span></span></p>
</div>
<iframe id="child" src="http://localhost:3001"></iframe>
<script>
    var input = document.getElementsByTagName('input')[0];
    var span = document.getElementsByTagName('span')[0];
    var btn = document.getElementsByTagName('button')[0];
    // 获取iframe元素的window对象
    var frame = document.getElementById('child').contentWindow;

    btn.onclick = function () {
        var msg = input.value;
        frame.postMessage('收到信息:' + msg + ' --from 3000 port!😨', 'http://localhost:3001');
    }

    function receiveMessage (event) {
        if (event.origin !== 'http://localhost:3001') {
            return false
        }
        var data = event.data;
        span.innerHTML = data;
    }

    // 监听消息事件
    window.addEventListener('message', receiveMessage, false);
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  • staticRes/index.html
<p style="text-align: center;">这里是3001端口</p>
<p>message: <span></span></p>
<script>
    // postMessage跨域适合于同一页面的不同窗体(iframe),所以在3001这个页面不会收到信息。
    var input = document.getElementsByTagName('input')[0];
    var span = document.getElementsByTagName('span')[0];
    var btn = document.getElementsByTagName('button')[0];
    var parentWin = window.parent;

    function receiveMessage (event) {
        if (event.origin !== 'http://localhost:3000') {
            return false
        }
        var data = event.data;
        span.innerHTML = data;
        parentWin.postMessage('我收到你的信息了😀--from 3001 port', 'http://localhost:3000/');
    }

    window.addEventListener('message', receiveMessage, false);
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 3.2 后端部分

  • serverReq.js
var express = require('express');
var app = express();

var requestPort = 3000;

app.use(express.static(__dirname + '/staticReq')); //3000端口的静态文件,即index.html

app.listen(requestPort, function () {
    console.log('Requester is listening on port '+ requestPort);
});
1
2
3
4
5
6
7
8
9
10
  • serverRes.js
var express = require('express');
var app = express();

var responsePort = 3001;  // 请求页面跑在3001端口

app.use(express.static(__dirname + '/staticRes')); //3001端口的静态文件,即index.html

app.listen(responsePort, function () {
    console.log('Responser is listening on port '+ responsePort);
});
1
2
3
4
5
6
7
8
9
10