在 chrome 扩展的 iframe 中使用 Twitter Bootstrap JS

Posted

技术标签:

【中文标题】在 chrome 扩展的 iframe 中使用 Twitter Bootstrap JS【英文标题】:Using Twitter Bootstrap JS in iframe in chrome extension 【发布时间】:2016-02-12 02:00:18 【问题描述】:

我正在开发一个 chrome 扩展,它通过在渲染时附加事件侦听器,在动态创建的元素上使用 Bootstrap Collapse (v2.3.2) 功能。我遇到了一个问题,当我加载我的扩展时,父页面上的折叠使用不再起作用。我在bootstrap's documentation 上对此进行了测试,并且能够重现。当我的扩展正常运行时,崩溃在示例中停止运行。我想当我加载我的 bootstrap.js 版本时,全局 jQuery 对象一定有一些污染。

这是我的清单的脚本部分:

"content_scripts": [
  "run_at": "document_start",
  "matches": ["<all_urls>"],
  "js": [
    "js/vendor/jquery-min.js",
    "js/vendor/bootstrap.min.js",
    "js/content_script.js",
  ]
]

js/content_script.js里面

// #render
function render () 
  $elInIframe.find('.accordion-toggle').on('click', function() 
      var targetName = $(this).attr('data-target');
      var target = $elInIframe.find(targetName);
      target.collapse('toggle');
  );

我的扩展的生命周期是:

    加载 content_script(使用扩展加载的 jquery 和引导程序作为 content_scripts)。 初始化并注入 iframe。 异步获取数据并在 iframe 中作为 html 注入 调用渲染,将点击监听器附加到 iframe 中的元素

所以澄清一下,我的扩展按预期工作,但我正在破坏也使用 bootstrap.js 的页面。

作为一种可能的解决方案,我尝试将 bootstrap.js 移动到 web_accessible_resource 并将其加载到模板中。但是,这样做之后,调用 target.collapse 会导致错误(不是函数),因为我的扩展程序使用的 jquery 没有通过加载 bootstrap.js 进行修改——而且我什至不确定 bootstrap 是否在扩展的 iframe。

【问题讨论】:

我认为如果你 inject a &lt;script&gt; element 使用 onclick 处理程序以及 jQuery 和 bootstrap.js 进入 iframe,它会起作用。 【参考方案1】:

我的解决方案非常迂回。我最终创建了一个可以在运行时注入的脚本并将其公开为web_accessible_script

//manifest.json
"web_accessible_resources": [
  "js/bootstrap.min.js",
  "js/injected_script.js"
]


//injected_script.js
document.addEventListener('toggle-collapse', function (e) 
  var targetName = e.detail.targetName;
  var $iframe = $('#extension_iframe');
  var target = $iframe.contents().find(targetName)
  target.collapse('toggle')
, false);

Bootstrap 和注入的脚本在运行时通过 jquery 附加:

var injectedLink = chrome.extension.getURL('js/injected_script.js');
var bootstrapLink = chrome.extension.getURL('js/bootstrap.min.js');

var $iframeHead = iframe.contents().find('html').find('head')
injectScript($iframeHead, injectedLink);
injectScript($iframeHead, bootstrapLink);

function injectScript ($parent, url) 
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.src = url;
    $parent.append(s);

然后,我用一个自定义事件替换了对.collapse('toggle') 的调用,该事件可以“扔到墙上”到我注入的脚本中。

//content_script.js
document.dispatchEvent(new CustomEvent('toggle-collapse', 
    detail: 
        targetName: targetName
    
));

通过这种方式,我能够在我的扩展程序中为 iframe 加载引导程序,并能够与我的扩展程序正在使用的 jquery 进行通信。所有这些都不会污染 DOM。

【讨论】:

以上是关于在 chrome 扩展的 iframe 中使用 Twitter Bootstrap JS的主要内容,如果未能解决你的问题,请参考以下文章

在 chrome 扩展的 iframe 中使用 Twitter Bootstrap JS

使用 JavaScript 将 Chrome 扩展注入 iFrame

iframe如何在chrome扩展中访问父窗口

使用 Chrome 扩展修改具有本地源的 iframe 的元素

在 iFrame 中激活 Zurb Foundation 的 Joyride,来自 Chrome 扩展内容脚本

如何从 chrome 扩展访问 iframe?