0

I am new to coding and so to JavaScript as well.

I tried to find a solution to my problem on Stack Overflow, but only found answers to parts of it. I patched up a code below that obviously doesn't work.

I aim to select links on a web page with particular domain in the href attribute, then change the href of the selected links so that only the first 106 characters of the url string would be kept and a new bit ("groupid=provider") added to it. These links are also supposed to receive a class attribute with a value of "wrongLink". At the moment when I load the web page that has the script below, every link on the webpage is affected, regardless of the domain in the url of the link.

Code:

window.onload = function() {
       /* onload code */

var anchors = document.getElementsByTagName("a");

for (var i = 0; i < anchors.length; i++) {
    var urltobechanged = anchors[i].href;  
       /* urltobechanged to store the url */

    var domaincheck = urltobechanged.startsWith("example.com");

    if (domaincheck = true){
       /* if the stored url starts with "example.com", then.. */

        anchors[i].href = urltobechanged.substring(0,105) + "groupid=provider";
       /* keep the first 106 characters of the url and add "goupid=provider" to it */

        anchors[i].setAttribute("class", "wrongLink");
       /* add class with "wrongLink" attribute to the the changed link element */
    }
}
}

Any help would be much appreciated. Thanks

dev-at
  • 13
  • 2
  • 5
    `if (domaincheck = true)` is an assignment, not a test for equality which is done with == (equals) or === (strictly equals) - Since it is a boolean, you do not even need the =(==): `if (domaincheck) { ...` will work fine – mplungjan Jan 20 '20 at 15:55
  • 2
    It also looks like you're adding code comments just for the sake of commenting. – Brandon Dyer Jan 20 '20 at 15:59

3 Answers3

0
  • if (domaincheck = true) is an assignment, not a test for equality which is done with == (equals) or === (strictly equals) - Since it is a boolean, you do not even need the =s: if (domaincheck) { ... will work fine

  • The href will not start with example.com unless you get the href attribute. The actual href of the achor will start with the site your are on, for example https://example.com which means you need to create a URL and look at the hostname

Here is code using the attribute. Note I use

  • spread [... ] to convert the nodeList to an array to allow slightly older browsers to run a forEach on it and I use

  • classList.add to allow other classes to exist on the link

window.addEventListener("load", function() {
  [...document.querySelectorAll("a")].forEach(function(anchor) {

    const urltobechanged = anchor.getAttribute("href");
    const domaincheck = urltobechanged.startsWith("example.com");

    if (domaincheck) {
      anchor.href = urltobechanged.substring(0, 105) + "?groupid=provider"; // remove the ? if your href already has one in pos 106
      /* keep the first 106 characters of the url and add "groupid=provider" to it */

      anchor.classList.add("wrongLink");
    }
  })
})
.wrongLink { background-color:red }
<a href="example.com">Example.com</a><br>
<a href="NOT example.com">NOT Example.com</a>

Here is code using the hostname

window.addEventListener("load", function() {
  [...document.querySelectorAll("a")].forEach(function(anchor) {

    const urltobechanged = new URL(anchor.href);
    const domaincheck = urltobechanged.hostname.startsWith("stacksnippets.net"); // change to example.com or whatever
    if (domaincheck) {
      anchor.href = urltobechanged.pathname += "?groupid=provider"
      anchor.classList.add("wrongLink");
    }
  })
})
.wrongLink { background-color:red }
<a href="page.html">https://stacksnippets.net/page.html</a><br>
<a href="https://somethingelse.com">NOT stacksnippet.net</a>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Question: doesn't `document.querySelectorAll` return a list? Why are you spreading the list into a list? Isn't `[...a] == a`? – Brandon Dyer Jan 20 '20 at 16:14
  • 1
    Not all newer browsers support forEach on a nodelist https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach – mplungjan Jan 20 '20 at 16:14
  • You could add information on why you changed `anchors[i].setAttribute("class", "wrongLink");` to `anchor.classList.add("wrongLink");` – Nicolas Jan 20 '20 at 16:17
0

There is a few errors / things that could be improved, in your code but you are on the right track.

  • when you check that the url starts with example.com, most of the time, they will starts with http:// or https://. Better use indexOf('example.com') !== -1 instead. ( Or a regex if the rest of the string could contains an url, like https://someUrl.com/?url=example.com/`
  • You are trying to use an assignement to compare ( = vs ===) in your if condition. Since your are comparing with true, you could simply do if(domaincheck).
  • you are assiging a boolean to a variable than comparing the boolean in a if statement. This can be improved by passing the compare expression directly to the if ( if(urltobechanged.indexOf("example.com") !== -1)
  • when you are adding values to your url ) + "groupid=provider", it looks like it is not going to be a valid get parameters. You need ? or & in it aswell. ( https://example.com/test would become https://example.com/testgroupid=provider rather than https://example.com/test?groupid=provider.
  • You should use let instead of var for multiple reasons
  • When you are adding a class to your element, you should use the classList property which returns a string containing the classes. We can then append our new class to this string. element.className += "new class"

Here is a revised version of your code.

let anchors = document.getElementsByTagName("a");

for (let i = 0; i < anchors.length; i++) {
    let urltobechanged = anchors[i].href;  
       /* urltobechanged to store the url */

    if ( urltobechanged.indexOf("example.com") !== -1){
       /* if the stored url starts with "example.com", then.. */
        
        // we check if the url already contains get parameters
        // we are using a ternary operator which is resumed to 
        // condition ? true : false
        let symbolToAdd = urltobechanged.indexOf('?') !== -1 ? '&' : '?';
        anchors[i].href = urltobechanged.substring(0,105) + symbolToAdd + "groupid=provider";
       /* keep the first 106 characters of the url and add "goupid=provider" to it */

        anchors[i].className += " wrongLink";
        // classList.add might be a better choice.
       /* add class with "wrongLink" attribute to the the changed link element */
    }
}
<a href="https://example.com">test</a>
<a href="https://notgoingToBechanged.com">i won't be changed</a>
Nicolas
  • 8,077
  • 4
  • 21
  • 51
  • you mean `classList.add`, no? `+=` would be `className += " wrongLink"` – mplungjan Jan 20 '20 at 16:17
  • @mplungjan, actually, i meant `className`, but `classList.add` might be better. both work though. – Nicolas Jan 20 '20 at 16:19
  • 1
    Sorry, I wasn't clear in the description of the issue because in my code I did include "http://" before example.com. Also, I know that the 106th character of all the links that need changed is a "?". So only by changing the if statement as recommended made the code work perfectly. I appreciate all the advices though and I have altered my code accordingly. Thanks ! – dev-at Jan 20 '20 at 16:23
  • 1
    `anchors[i].className += "wrongLink"` would not work if there was another class in there. If it had class="myLink" it would become "myLinkwronglink" – mplungjan Jan 20 '20 at 16:28
  • @mplungjan you are right, thanks for pointing it out. I've added a space before the class. – Nicolas Jan 20 '20 at 16:34
0

Two things:

  • if (domaincheck = true) needs to be if (domaincheck)
  • You need to use .getAttribute on your anchor
window.onload = function() {
    /* onload code */

    var anchors = document.getElementsByTagName("a");

    for (var i = 0; i < anchors.length; i++) {
        var urltobechanged = anchors[i].getAttribute("href");
        /* urltobechanged to store the url */

        var domaincheck = urltobechanged.startsWith("example.com");

        if (domaincheck) {
            /* if the stored url starts with "example.com", then.. */

            anchors[i].href =
                urltobechanged.substring(0, 105) + "groupid=provider";
            /* keep the first 106 characters of the url and add "goupid=provider" to it */

            anchors[i].setAttribute("class", "wrongLink");
            /* add class with "wrongLink" attribute to the the changed link element */
        }
    }
};
Brandon Dyer
  • 1,316
  • 12
  • 21