javascript - 在 Chrome 扩展的 iframe 中使用 Twitter Bootstrap JS

标签 javascript jquery twitter-bootstrap iframe google-chrome-extension

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

这是我的 list 的脚本部分:

"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');
  });
}

我的扩展的生命周期是:

  1. 加载 content_script(使用扩展加载的 jquery 和 bootstrap 作为 content_scripts)。
  2. 初始化并注入(inject) iframe。
  3. 异步获取数据并以 HTML 形式注入(inject) iframe
  4. 调用渲染,将点击监听器附加到 iframe 中的元素

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

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

最佳答案

我的解决方案非常迂回。我最终创建了一个可以在运行时注入(inject)的脚本,并将其公开为 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 和注入(inject)的脚本在运行时通过 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') 的调用替换为自定义事件,该事件可以“扔到墙上”到我的注入(inject)脚本中。

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

通过这种方式,我能够在我的扩展中加载 iframe 的 Bootstrap ,并能够与我的扩展正在使用的 jquery 进行通信。一切都不会污染 DOM。

关于javascript - 在 Chrome 扩展的 iframe 中使用 Twitter Bootstrap JS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33642747/

相关文章:

javascript - 谷歌图表 API : Line Chart - chart date against date?

Jquery循环,在滚动图像的顶部放置一个div

jquery - 带有 Twitter Bootstrap 的全日历?

twitter-bootstrap - 导航菜单不适用于使用 Bootstrap 的 vue.js

javascript - 在 Bootstrap 3.0 中设置下拉列表的宽度

javascript - 从 html 源代码中删除 vbscript 或停用 vbscript

javascript - 如何取消 Cypress 中的特定请求?

javascript - 声明构造函数的优点/缺点

php - 基于导航菜单ajax加载json/mysql内容列表?

javascript - css 未加载,因为它在 Meteor JS 中的 MIME 类型