skip to Main Content

I’m trying to force <a> links on my webpage to open in a new tab. I have tried using this code:

window.addEventListener('DOMContentLoaded', function() {
  var links = document.getElementsByTagName('a');
  for (var i = 0; i < links.length; i++) {
    var link = links[i];
    link.setAttribute('target', '_blank');
  }
});

But it simply doesn’t work. I guess this could be because the content is updated after the page is fully loaded due to some kind of scripting, but I have tried rechecking every second for new links so I doubt it. Here is the relevant code:

function checkForNewLinks() {
  var links = document.getElementsByTagName('a');
  for (var i = 0; i < links.length; i++) {
    var link = links[i];
    link.setAttribute('target', '_blank');
  }
}

window.addEventListener('DOMContentLoaded', function() {
  // Initial check on page load
  checkForNewLinks();

  // Check for new links every second
  setInterval(checkForNewLinks, 1000);
});

Let me know if you need any additional info.

2

Answers


  1. Clear your cashe. If that doesn’t work, use MutationObserver.

    Login or Signup to reply.
  2. If the following code doesn’t solve your issue, it should give you a starting point for debugging it more effectively:

    (() => {
      const modified = new WeakSet();
      const separator = '-'.repeat(40);
      let cycle = 0;
      
      function checkForNewLinks() {
        const allLinks = [...document.getElementsByTagName('a')];
        const virginLinks = allLinks.filter((link) => !modified.has(link));
        const linkCount = virginLinks.length;
        for (var i = 0; i < linkCount; i++) {
          const link = virginLinks[i];
          link.setAttribute('target', '_blank');
          modified.add(link);
        }
        console.debug(`Cycle ${++cycle}n  Total Links: ${allLinks.length}n  Newly Modified Links: ${linkCount}n${separator}`);
        setTimeout(checkForNewLinks, 1000);
      }
      
      if (document.readyState === 'interactive') {
        checkForNewLinks();
      } else {
        window.addEventListener('DOMContentLoaded', checkForNewLinks());
      }
    })();
    

    This uses a WeakSet to track previously modified links and outputs stats on each cycle. As far as your code is concerned, it looks fine and appears to work on the few pages I tested it on.

    There are several failure points that could be affecting you at runtime based on the environment:

    • Usage in a worker
    • Usage in an iframe element
    • Usage in a content script
    • Usage on a page with polluted or overridden native prototypes
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search