【问题标题】:How to access an iframe from chrome extension?如何从 chrome 扩展访问 iframe?
【发布时间】:2017-10-22 16:49:18
【问题描述】:

如何让我的扩展程序像 adblock 一样在所有帧上工作?

我尝试将"all_frames" : true 添加到我的清单文件中,但没有成功。

我尝试使用此代码获取具有特定 ID 的文本:

var theId = "starts with something";
var myArray = [];
$('[id^="theId"]').each(function(i, obj) {
    myArray.push($(this).text());
}); 

$.unique(myArray);

console.log(myArray);

但它说我的数组是空的。当我检查页面上的元素时,我看到一个“顶层”层和一个“目标内容”层。该代码仅在我在“目标内容”层的控制台中执行时才有效。我可以在内容脚本中使用此代码,还是需要以某种方式使用 background.js?

【问题讨论】:

  • 您好,作为您上一个问题的延续,我得到了一个可行的解决方案。

标签: javascript jquery iframe google-chrome-extension


【解决方案1】:

Continued from SO44122853

我看到您发现内容是在 iframe 中加载的。所以我在这里有一个工作演示PLUNKER,sn-p 在这里,以防 plunker 出现故障。

详情见PLUNKER

演示

由于需要运行 2 个单独的页面而无法正常工作

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
  <style></style>
</head>

<body>
  <!--iframe is same as the one on the site, with the exception
  of the src-->
  
  <iframe id="ptifrmtgtframe" name="TargetContent" title="Main Content" frameborder="0" scrolling="auto" width='90%' src="tables.html"></iframe>
  
 <!--The data is displayed as a one string-->
  <output id='display'></output>
  
  <script>
  
  // Reference the iframe
    var iFID = document.getElementById("ptifrmtgtframe");
  // Register the load event on iframe
    iFID.onload = function(e) {
      // Callback is extractText function
      return extractText('#ptifrmtgtframe', '#display', '.PSLONGEDITBOX');
    }

    /* Pass iframe and display as a single selector
    || Pass targets as a multiple selector
    */
    function extractText(iframe, display, targets) {
      var iArray = [];
      var iFrame = document.querySelector(iframe);
      var iView = document.querySelector(display);
      var iNode = "";
      
      /* .contentWindow is property that refers to content
      || that is in an iframe. This is the heart of the
      || demo.
      */
      var iContent = iFrame.contentDocument || iFrame.contentWindow.document;
      var iTarget = iContent.querySelectorAll(targets);
      
      /* .map() will call a function on each element
      || and return a new array as well.
      */
      Array.from(iTarget).map(function(node, idx) {

        iNode = node.textContent;
        iView.textContent += iNode;
        iArray.push(iNode);
        return iArray;
      });
      console.log(iArray);
    }
  </script>
</body>

【讨论】:

  • 注册一个事件监听器到被点击的按钮,并使用你的代码作为回调。 $('button').on('click', function(e) {..CALLBACK....}); iframe 加载速度很慢,所以我使用了 onload 事件,这是加载页面期间的最后一个事件。您查看过Plunker 吗?选择器是您网站中使用的真实选择器。您需要做的就是添加您的扩展代码(例如exec.command()。)
  • 是的,那将是一个更好的选择器,否则您将需要切换 129 个单元格。
  • 原来我被愚弄了。它仍然无法正常工作。该代码仅在我将其键入到检查元素中“目标”层的控制台时才有效。知道为什么它不适用于所有帧吗?
  • 刚刚用documentContent 选项更新了windowConent.document。 Chrome.ext 窗口对象似乎与 JS 窗口对象不同,因此 windowContent 属性将未定义。 documentContent 应该适用于 Chrome 分机。看到这个post和这个post
  • 顺便说一句,在这一点上,我很确定就 DOM 收集而言,我们做得很好。我认为现在可能是 Chrome-ext 方面的问题。
【解决方案2】:

我认为您的脚本可能在 DOM 加载之前执行,请尝试将您的函数放入其中:

document.addEventListener('DOMContentLoaded', function() {

});

编辑 该事件似乎在内容脚本中没有任何作用,我认为这是因为它们在 DOM 加载后已经加载,并且永远不会触发。

但是这似乎触发了,但不知道为什么:

$(function(){
//something
});

这也需要注入 jQuery

【讨论】:

  • 我如何检查这个?我不知道在哪里可以找到 console.log。另外,我以前试过这个,所以它可能不起作用
  • 在内容脚本中,不是吗?
  • 我试过 $(function(){ console.log("something");});在内容脚本中并被触发,但是 document.addEventListener('DOMContentLoaded'... 似乎没有被触发,试试这种方式
  • 是的,它在内容脚本中。我在里面放了一个警报,没有弹出任何东西。仅当我将警报作为第一行时
  • 这些 iframe 是否在同一个域中?我读过这可能是个问题。
猜你喜欢
  • 2012-10-27
  • 2013-03-15
  • 2012-07-08
  • 1970-01-01
  • 2011-04-25
  • 2017-05-04
  • 1970-01-01
  • 2012-07-24
  • 1970-01-01
相关资源
最近更新 更多