如何从 chrome 扩展访问 iframe?
Posted
技术标签:
【中文标题】如何从 chrome 扩展访问 iframe?【英文标题】:How to access an iframe from chrome extension? 【发布时间】: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?
【问题讨论】:
您好,作为您上一个问题的延续,我得到了一个可行的解决方案。 【参考方案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 是否在同一个域中?我读过这可能是个问题。以上是关于如何从 chrome 扩展访问 iframe?的主要内容,如果未能解决你的问题,请参考以下文章