【发布时间】:2015-12-03 01:18:26
【问题描述】:
我正在构建一个 Chrome 扩展程序,它在任何 HTML 页面(即在浏览器窗口中查看的任何页面)内创建一个 iFrame。
iFrame 由 Chrome 扩展程序的内容脚本“注入”到 HTML 页面中。生成的 HTML 如下所示:
<html>
<head>..</head>
<body>..</body>
<iframe id="myIframe">...</iframe>
</html>
在内容脚本将 iFrame 添加到主页的 DOM 之后,它会继续通过操作自己的 DOM 来使用内容填充 iframe。我使用 Zurb CSS 来设置 iframe 内容的样式。
这一切都很好。
我现在正在尝试将 Zurb Joyride 添加到 iframe 的内容中,但我无法开始工作。
我的清单的 content_scripts 声明如下所示:
"content_scripts": [{
"matches": ["*://*/*"],
"js": ["js/externalJS/jquery-2.1.4.min.js",
"js/externalJS/foundation.min.js",
"js/content_script.js"],
"run_at": "document_end"
}],
我怀疑 iframe 本身需要访问 Zurb 脚本,以及作为扩展的一部分由清单加载的foundation.min.js,我的内容脚本还在 iframe 内添加了相关标签(通过操作 DOM)。我的理解是 iframe 中的关键元素是:
- Zurb JS 文件的标签
- 将兜风附加到 (id="testjoyride") 的对象
- 兜风内容本身
- foundation() 的初始化调用
因此,考虑到这一点,我的清单的 web_accessible_resources 声明如下所示:
"web_accessible_resources": [
"js/externalJS/jquery-2.1.4.min.js",
"js/externalJS/vendor/modernizr.js",
"js/externalJS/vendor/fastclick.js",
"js/externalJS/foundation.min.js",
"css/foundation.css",
"css/app.css"
],
然后使用内容脚本在 iframe 中构建以下 HTML:
<iframe id="myIframe">
<html>
<head>
<!-- the foundation style sheet (which works fine already) -->
<link type="text/css" rel="stylesheet" href="chrome-extension://extension_id/css/foundation.css">
<!-- the first two scripts -->
<script src="chrome-extension://extension_id/js/externalJS/vendor/modernizr.js"></script>
<script src="chrome-extension://extension_id/js/externalJS/jquery-2.1.4.min.js"></script>
</head>
<body>
<!-- a test object to attach the joyride too -->
<input type="submit" id="testjoyride">
<!-- now the rest of the iframe content -->
... content ...
<!-- the other two scripts -->
<script src="chrome-extension://extension_id/js/externalJS/vendor/fastclick.js"></script>
<script src="chrome-extension://extension_id/js/externalJS/foundation.min.js"></script>
<!-- default joyride code from foundation.zurb.com -->
<ol class="joyride-list" data-joyride="">
<li data-id="testjoyride" data-class="custom so-awesome" data-text="Next" data-prev-text="Prev">
<h4>Stop #1</h4>
</li>
<li data-button="end" data-prev-text="Prev">
<h4>Stop #3</h4>
</li>
</ol>
</body>
</html>
</iframe>
然后,最后,当所有上述内容都附加到 iframe(当然,iframe 附加到父页面的 DOM)时,我从 content_script 调用 Foundation()。
我想我需要这样称呼它: $(window.frames.myIframe.contentWindow.document).foundation('joyride', 'start');
即传入 iframe 的文档对象,而不是父页面**
所以我做了所有这些,但没有任何反应。兜风不会出现,HTML 也不会转换为自动生成的输出(如 here 所述)。
我在一个简单的 HTML 页面中创建了一个测试用例,它运行良好,我尝试将该测试页面移动到 iframe 中,但 Joyride 停止工作。因此,尽管没有太多信心,但我怀疑问题在于 iframe,而不是 Chrome 扩展。
** 注意,我把这个调用放在所有 DOM 操作的末尾。在我将我创建的新 HTML 添加到 iframe 的 DOM 之后,并在创建我所有的侦听器等之后。所以我相信脚本和游戏应该在那时“那里”。但是,如果我在调用foundation('joyride','start') 之前粘贴一个alert(),则警报会在其后面显示一个空的iframe,并且只有在我关闭警报之后才会填充iframe。这是否重要,或者只是警报的奇怪效果,我不知道。
【问题讨论】:
-
暗示您在内容脚本中创建 iframe 尝试使用
window.postMessage(example) 向您的 iframe 脚本发送事件,然后在 iframe 中注入一个额外的简单脚本,并为此添加一个侦听器将调用foundation('joyride', 'start');的消息。或者使用 chrome API 来交换消息,但这可能会比较麻烦。 -
就是这样!我不明白的三件事:1)正如你所说,@wOxxOm,从 iframe 调用
foundation('joyride','start')就是答案。但是为什么从内容脚本(传入 iframe 文档)调用它不起作用? 2) 如果我只使用innerHTML += '<script src='...,将外部脚本添加到 iframe 中不起作用。我必须使用document.createElement('script'),然后使用appendChild()将其添加到DOM。 3) 在调用 postMessage() 之前,我必须强制延迟内容脚本。我使用window.timeout(),即使延迟设置为 0,它也可以工作。这看起来很奇怪。 -
如果您将其发布为详细答案会很好,因为我只提供了一个提示并且无法测试代码。至于您的问题: 1. 因为每个文档(iframe 是一个文档)在其自己的沙箱中运行代码 2. idk,我从不使用
+=用于 innerHTML,因为我认为它非常糟糕 3.setTimeout(..., 0)将代码排队一个单独的事件任务/作业,在任何其他排队之后执行,包括 DOM 更新。 -
@wOxxOm 感谢您对这三点的反馈,更不用说首先解决问题了。这是一个巨大的帮助,真的很感激。我会尽快给出详细的答复。但这是否意味着我不给你任何“提示”投票?毕竟,这是我做错的核心......
-
将信息汇总到一个好的答案中是一项比幸运猜测更大的任务,因此您可以继续进行,因为您已经完成了与我不同的测试。
标签: javascript iframe google-chrome-extension zurb-foundation zurb-joyride