【问题标题】:Using Twitter Bootstrap JS in iframe in chrome extension在 chrome 扩展的 iframe 中使用 Twitter Bootstrap JS
【发布时间】: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');
  });
}

我的扩展的生命周期是:

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

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

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

【问题讨论】:

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


【解决方案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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 2012-08-15
    相关资源
    最近更新 更多