defoification
defoification

Reputation: 313

How to access an iframe from chrome extension?

How can I get my extension to work on all frames like adblock does?

I tried adding "all_frames" : true to my manifest file but it didn't work.

I tried to use this code to get the text with specific ids:

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

$.unique(myArray);

console.log(myArray);

but it says my array is empty. When I inspect element on the page, I see a "top" layer, and a "target content" layer. The code only works when I execute it in the console on the "target content" layer. Can I use this code in a content script, or do I need to use background.js somehow?

Upvotes: 1

Views: 3734

Answers (2)

zer00ne
zer00ne

Reputation: 44086

Continued from SO44122853

I see you figured out that the content was loaded in an iframe. So I have a working demo here PLUNKER, the snippet is here just in case the plunker goes down.

Details are commented in PLUNKER

Demo

Not functional due to the need to run 2 separate pages

<!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>

Upvotes: 1

Rodrigo Gross
Rodrigo Gross

Reputation: 25

I think your script may be executing before the DOM loads, try putting your function inside:

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

});

EDIT That event seems to do nothing in content scripts, I think that is because they are already loading after DOM is loaded, and never fires.

However this seems to fire but not sure why:

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

This needs jQuery injected aswell

Upvotes: 1

Related Questions