0

I'm playing around with web development and looking to test some dynamically generated content, specifically just listing in a Chrome Extension popup all of the links on a site page. I referenced a great resource here but I was testing with an output tag versus a ul and the creation of li for that list to show on the page.

popup.html

<div>
  <h3>Page output</h3>
  <output id="outputkey3">pages go here</output>
</div>

popup.js

function (tabs) {
  var tab = tabs[0];
  var url = tab.url;
  if (url != null) {
      var host = new URL(url).hostname;
    ...

var outputKey3 = document.getElementById("outputKey3")
if (outputKey3 != null) {
  for(var i = document.links.length; i --> 0;) {
    if(document.links[i].hostname === host) {
      //urls.push(document.links[i].href);
      outputKey3.appendChild(document.links[i]);
    }
  }
}

Even for a single link this does not seem to be working. Not sure if this is meant to be done with a list versus another element that does not format the data with a preceding number or •. What I'd really like to do is just show a list that looks like a new line of data for each index value, perhaps as a bunch of p's.

Matthew
  • 3,976
  • 15
  • 66
  • 130
  • Where are you defining the 'host' variable? Your code looks OK other than that. – troyw1636 Feb 03 '19 at 23:46
  • Possible duplicate of [How to access the webpage DOM rather than the extension page DOM?](https://stackoverflow.com/questions/4532236/how-to-access-the-webpage-dom-rather-than-the-extension-page-dom) – wOxxOm Feb 04 '19 at 08:41
  • Updated to show assigning of `var host = new URL(url).hostname;` – Matthew Feb 04 '19 at 15:59

1 Answers1

0

You have a couple of things going against you here in your code.

  1. host is never defined. You probably mean location.host
  2. You rarely want to compare a host to a hostname. One includes the port and one does not.
  3. As a best practice, you'll want to use a cloned form of the array. This is because the list can change while you are computing.
  4. document.links includes all links, including the ones you add. Yet another reason to copy the array before changing page contents.
  5. appendChild() will attempt to move the <a> and this could break the rest of the page. You probably want to clone the element.
  6. <output> may have semantics that are inhibiting the additions. It is intended for computed results and may only have phrasing content. Consider changing to a <div> if you don't want a <ul>.

Suggestion using clone

var outputKey3 = document.getElementById("outputKey3")
if (outputKey3 != null) {
  // Get new array of filtered links
  // Document.links is not an array, but can be used by Array.prototype
  let links = Array.prototype.filter.call(document.links, function(link) {
    return (link.hostname === location.hostname)
      && (link.parentElement !== outputKey3);
  });
  // For each link, change its value to a clone of it
  let newLinks = link.map(function(link) {
    return link.cloneNode();
  });
  // For each clone, add it to the list.
  newLinks.forEach(function(link) {
    outputKey3.appendChild(link);
  });
}

If you must use a for loop:

var outputKey3 = document.getElementById("outputKey3")
if (outputKey3 != null) {
  for(var i = document.links.length; i-- > 0;) {
    if((document.links[i].hostname === location.hostname)
    && (link.parentElement !== outputKey3)) {
      //urls.push(document.links[i].href);
      outputKey3.appendChild(document.links[i].cloneNode());
    }
  }
}
Fuzzical Logic
  • 12,947
  • 2
  • 30
  • 58
  • @wOxxOm : Absolutely true, but until the OP provides additional info, this is the proscribed code fix. If (and probably when) the OP changes his/her post, then I'll change my answer accordingly. – Fuzzical Logic Feb 04 '19 at 08:29