0

I'm trying to replace multiple links but only the first one is replaced, all the other remain the same.

function rep(){
    var text = document.querySelector(".link").querySelector("a").href;

    var newText = text.replace(/http:\/\/test(.*)http:\/\/main(.*)com/, 'http://google$2com');

    document.querySelector(".link").querySelector("a").href = newText;
}

Any suggestions?

It's multiple a href links inside .link elements which I'm talking about.

YakovL
  • 7,557
  • 12
  • 62
  • 102
Marksyw
  • 69
  • 2
  • 6

3 Answers3

1

This doesn't use JQuery, and I've changed your regular expression to something that made more sense for the example. It also works when you run the snippet.

function rep() {

  var anchors = document.querySelectorAll(".link a");
  for (var j = 0; j < anchors.length; ++j) {
    var anchor = anchors[j];
    anchor.href = anchor.href.replace(/http:\/\/test(.*)com/, 'http://google$1com');
  }
}

rep();
a[href]:after {
  content: " (" attr(href)")"
}
<div class="link">
  <a href="http://testsomething.com">What kind of link is this?</a>
  <br/>
  <a href="http://testsomethingelse.com">And what kind of link is this?</a>
  <br/>
</div>

<div class="link">
  <a href="http://testsomething2.com">What kind of link is this?</a>
  <br/>
  <a href="http://testsomethingelse2.com">And what kind of link is this?</a>
  <br/>
</div>

Edit: Expanded example showing multiple anchor hrefs replaced inside multiple link classed objects.

Edit2: Thomas example is a more advanced example, and is more technically correct in using querySelectorAll(".link a"); it will grab anchors in descendants, not just children. Edited mine to follow suite.

If you intend to only select direct children of link class elements, use ".link>a" instead of ".link a" for the selector.

TylerY86
  • 3,737
  • 16
  • 29
  • i've tried the /g but its not working its has multiple a href links in the .name class – Marksyw Sep 27 '16 at 22:57
  • Yeah, the /g wasn't the problem. I thought you were talking about multiple replacements within the same href. You want to replace a bunch of separate hrefs. – TylerY86 Sep 27 '16 at 22:58
  • @Marksyw I've expanded the example to show the links being replaced. Just hit "Run code snippet." :) – TylerY86 Sep 27 '16 at 23:04
  • your code is not working in firefox.Run code snippet and its not working but working in chrome – Marksyw Sep 27 '16 at 23:34
  • I'm writing this post from Firefox, I just hit run snippet, and it looks like it works for me. Where do the links point to for you? – TylerY86 Sep 27 '16 at 23:37
  • @Marksyw This code behaves the same as the chosen answer. Have a good day. – TylerY86 Sep 27 '16 at 23:55
1

Your mistake is in using querySelector, so document.querySelector(".link").querySelector("a") literally translates to: get me the first a inside the first .link;

Use querySelectorAll; and you can combine the two selectors:

Vanilla JS:

[].forEach.call(document.querySelectorAll('.link a'), function(a){
    a.href = a.href.replace(/http:\/\/test(.*)http:\/\/main(.*)com/, 'http://google$2com');
});

Or, since you'll select items more often, a little utility:

function $$(selector, ctx){
    return Array.from((ctx && typeof ctx === "object" ? ctx: document).querySelectorAll(selector));
}

$$('.link a').forEach(function(a){
    a.href = a.href.replace(/http:\/\/test(.*)http:\/\/main(.*)com/, 'http://google$2com');
})

Or in jQuery:

$('.link a').each(function(){
    this.href = this.href.replace(/http:\/\/test(.*)http:\/\/main(.*)com/, 'http://google$2com');
});
Thomas
  • 11,958
  • 1
  • 14
  • 23
  • Just as a heads up, the regular expression looks weird doesn't it? Might be part of the problem. Could you put these in code snippets to show they work? The first one should technically be `Array.prototype.forEach` instead of `[]` to prevent instancing a new array, but it really doesn't matter. Brevity is cleaner. – TylerY86 Sep 27 '16 at 23:45
  • Your examples are more more technically correct in using `.querySelectorAll(".link a");` as they will grab anchors in descendants, not just children. – TylerY86 Sep 27 '16 at 23:48
  • @TylerY86, no it doesn't look weird, it looks like mapping `http://test.myCompany.net/redirect?url=http://main.projectDomain.com/` to `http://google.projectDomain.com` or sth like that. And `[].forEach` vs. `Array.prototype.forEach`: that's premature optimization. Don't bother, I'd rather be annoyed about having to type `[].forEach.call(document.querySelectorAll` more than once. That's why I included the example with the `$$` utility function. – Thomas Sep 28 '16 at 00:30
  • @Thomas lol It's not an optimization at all, it's intentional pedantics. If you microbenched the two, I wouldn't be supprised if `[].forEach` was faster. – TylerY86 Sep 28 '16 at 01:01
0

Try using a foreach loop for every ".link" element. It seems that every ".link" element have at least 1 anchor inside, maybe just one. Supposing every .link element has 1 anchor just inside, something like this should do:

    $('.link').each(function(){
       // take the A element of the current ".link" element iterated
       var anchor = $(this).find('a');
       // take the current href attribute of the anchor
       var the_anchor_href = anchor.attr('href');
       // replace that text and achieve the new href (just copied your part)
       var new_href = the_anchor_href.replace(/http:\/\/test(.*)http:\/\/main(.*)com/,'http://google$2com');
       // set the new href attribute to the anchor
       anchor.attr('href', new_href);
    });

I did't test it but it should move you to the way. Consider that we could resume this in 3 lines.

Cheers

EDIT

I give the last try, looking at your DOM of the updated question and using plain javascript (not tested):

var links = document.getElementsByClassName('link');
var anchors = [];
for (var li in links) {
 anchors = li.getElementsByTagName('A');
 for(var a in anchors){
   a.href = a.href.replace(/http:\/\/test(.*)com/, 'http://google$1com');
 }
}

I suggest to read the following post comment for some cooler methods of looping/making stuff foreach item.

How to change the href for a hyperlink using jQuery

Community
  • 1
  • 1
  • He was replacing the href property of anchors, not the attributes. Note that these have different string values. – TylerY86 Sep 27 '16 at 23:00
  • As he just mentioned in a comment on my answer, there are multiple anchors inside the link classed elements. – TylerY86 Sep 27 '16 at 23:01
  • __`in`__ only selects keys. Your example is broken. You meant __`of`__ in your for loops. That, or you need to select `var link = links[li]; anchors = link...` – TylerY86 Sep 27 '16 at 23:39
  • yeah you are right, it was too late here 2AM. bravo – Simone Bagnara Sep 28 '16 at 08:15