0

I'm a novice in jQuery and I got stuck whit a problem for a while now. I am trying to discover all the links to an external page and add a target="_blank" attribute to them. So far I have created the following script:

$(document).on('load',function() {
$('a').each(function () {
    if (location.hostname !== this.hostname) {
        $(this).attr('target', '_blank');
    }
});
});

This works fine on the elements that are loaded on the page in the first instance, but when new elements are added dynamically it doesn't fire again to add the target attribute. I have tried to change the "ready" function to "on('load')" but to no success.

Any help is highly appreciated and I am grateful for the people who take a second to answer silly questions like this.

Edit: I created and infinite scroll script that loads more elements through an AJAX call. This elements contain "a" tags and I would like the script to run again for them.

Mipod
  • 135
  • 1
  • 12
  • 1
    What do you mean by elements that are added Dynamically? How do you add those? Both load and ready function run once when the document it's ready or loaded so you function only runs to the elements that are loaded to the DOM the first time. If somehow you can add new links trough Jquery or JS you need to add the attribute blank again. Be more explicit in that sense and I think I can answer properly. – DanielPanic May 31 '17 at 18:51
  • The best solution would be a *Mutation Observer* https://stackoverflow.com/questions/13277212/mutation-observer-for-creating-new-elements – Jonas Wilms May 31 '17 at 18:55

3 Answers3

1

You have to trigger that function whenever you add new elements. Because you is the best person to know when new links are being added, so you have to set up the scripts in that way.

function setTargetBlank () {
  $('a').each(function () {
    if (location.hostname !== this.hostname) {
      $(this).attr('target', '_blank');
    }
  });
}

// On load
$(function () {
  setTargetBlank();
  loadSomeContent(function () {
    // And after it is loaded, trigger again the function
    setTargetBlank();
  });
});

If you cannot control these, you can simply set up a timer which will always trigger that function every few seconds:

 // This is not really good for performance, but it will work
 // It will trigger the function every 3 seconds
 setInterval(setTargetBlank, 3 * 1000);
Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
1

I would wrap your link-changing code in a function which you can call a) onload and b) when your content changes.

$(document).ready(function() {
  linkChanger();
});

function linkChanger() {
  $('a').each(function () {
      if (location.hostname !== this.hostname) {
          $(this).attr('target', '_blank');
      }
  });
}

then if you add content/links later, you can call linkChanger() to check/convert your page again:

$('#something').click(function () {
  // code that gets more content, if async provide a callback that calls linkChanger()
  linkChanger();
});
James
  • 20,957
  • 5
  • 26
  • 41
  • I tried "on('load')" but that seems to be triggered before the elements are loaded because it doesn't affect any of the "a" tags – Mipod May 31 '17 at 19:02
  • I change the "on('load')" to "ready" and added the function to my infinite scroll script after the new elements are loaded and it worked. Thank you very much – Mipod May 31 '17 at 19:06
0

It is possible that you are targeting the A links before the new elements have been created, Try running the code in a setTimeout function. for example

$(document).on('load',function() {

setTimeout(function(){ $('a').each(function () { if (location.hostname !== this.hostname) { $(this).attr('target', '_blank');
} }); }, 5000);

});