0

I'm new to Javascript, and need some help with creating a script that adds 'onclick' to href links of a particular class on an HTML page, upon page load - using the link's href URL, without touching the inline code. The script would modify a regular link, from this

<a href="URL" class="XYZ">

to this:

<a href="#" onclick="location.href='URL';" class="XYZ">

The URL changes for each link but the class remains the same. Here is what I got so far, but I was wondering if it can be improved:

window.onload = function() {

// Saving all links with XYZ-class in a variable
let links = document.getElementsByClassName('XYZ');

// Iterating through the links, changing the onclick attribute
for(let i = 0; i < links.length; i++) {
    // Saving the URL 
    let grabbedURL = links[i].getAttribute('href');

    // Putting it in onclick
    links[i].setAttribute('onclick', `location.href='${grabbedURL}'`);

    // Replacing href with '#'
    links[i].setAttribute('href', '#');

}
smartino
  • 3
  • 1
  • 4
  • Please update your question with your JS code segment that shows us your best attempt at resolving this yourself, and explain at what point you're encountering an issue. – devlin carnate Jun 29 '20 at 20:54
  • Curious why you think you need to do this. The end result will be the exact same behavior in the browser when user clicks the link – charlietfl Jun 29 '20 at 20:57
  • Why not just change the `href` of links with a particular class? – Scott Marcus Jun 29 '20 at 22:06
  • Hi there, I need this to force a page reload for the tabbed navigation of my Wordpress LMS. This is to avoid Wordpress native short codes not being displayed correctly when pages are loaded from cache and not the server. The onclick forces a refresh of the page from the server. – smartino Jun 30 '20 at 22:06

5 Answers5

0

Here's an approach using a for...of loop; you can change that if you want:

// iterate through all results of a css selector
for (let link of document.querySelectorAll('a.XYZ')) {
  // set onclick attribute as text
  link.setAttribute('onclick', 'location.href = ' + JSON.stringify(link.href) + ';');
  // set href attribute to empty anchor (#)
  link.href = '#';
}
<body>
<a href="https://example.com/" class="XYZ">http://example.com/</a>
<br>
<a href="https://foo.bar/" class="XYZ">http://foo.bar/</a>
</body>

There could be more modern solutions to your problem using EventTarget.addEventListener(), but so far that's what you requested. If you have a question to this answer please write a comment under it.
And as you new to Stack Overflow: If you had a helpful answer for your question, you can mark it as accepted. Of cause only if you want. Doesn't have to be mine.

Niklas E.
  • 1,848
  • 4
  • 13
  • 25
  • I used `document.querySelectorAll` instead of `document.getElementsByClassName` to make sure it is a link (`a`) that can provide a `href` attribute. A even better selector than `a.XYZ` would be `a.XYZ[href]`. See [CSS Selector Reference](https://www.w3schools.com/cssref/css_selectors.asp) – Niklas E. Jun 29 '20 at 21:15
  • Better yet, use event delegation and just create one event handler. – Scott Marcus Jun 29 '20 at 22:07
0

Placing this in your JS should do it:

const convert = () => {

  const links = document.querySelectorAll("a");

  for(let i = 0; i < links.length; i++){
    let href = links[i].getAttribute("href");
    let handleClick = () => {
      console.log("the url is:",href)
      window.location.href = href;
    }
    links[i].onclick = handleClick;
    links[i].setAttribute("href","#");
  }
}

convert();
Pavlos Karalis
  • 2,893
  • 1
  • 6
  • 14
0

I think you might be missing a larger point here. An anchor is designed for navigation, if you want to change the destination, don't set an onclick and then disable the href, just update the href to where you want to go.

And, to do this in the simplest way, use event delegation, where we leverage the fact that events bubble up from their origin to the document. We just create one event handler on a common ancestor of all the elements in question and handle the even there. When we do, we check to see if the event originated at an element that we care about using event.target and if it did, we act accordingly.

Here's an example:

let url = "https://example.com";

// Set an event listener on the document itself
document.addEventListener("click", function(event){
  // Check to see if the event originated at an
  // element we want to handle.
  if(event.target.nodeName === "A" && event.target.classList.contains("XYZ")){
    // Just update the href of the element
    event.target.href = url;
  }
});
<p>Click the links below. Only the XYZ links will take you to example.com</p>
<a href="URL" class="XYZ">XYZ</a>
<a href="URL" class="abc">abc</a>
<a href="URL" class="qrs">qrs</a>
<a href="URL" class="XYZ">XYZ</a>
<a href="URL" class="zzz">zzz</a>
<a href="URL" class="XYZ">XYZ</a>
<a href="URL" class="aaa">aaa</a>
<a href="URL" class="XYZ">XYZ</a>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • As I pointed out in a comment above, I need to force a page refresh each time a link is clicked (due to some issue with a Wordpress plugin) - so 'onclick' does the trick. It may not be the best solution, but the one I knew. Thanks for your suggestion. – smartino Jun 30 '20 at 22:21
-1

If I'm understanding your question, I think you want something like this:

function updateLink() {
    var link = document.getElementById("linkId");
    link.setAttribute('href', "http://google.com");
}

Then just add an 'id' to your link. Or get the class rather than the id.

stuckCode6
  • 36
  • 5
  • `id`s make for brittle and bloated code. Also, instead of `setAttribute()` (which does work), you could just set the `.href` property of the element directly. – Scott Marcus Jun 29 '20 at 22:18
-2
document.getElementsByClassName('XYZ')[0].setAttribute("onclick","location.href='URL' ")

Try this..

For after page load effect add script at the very end of your body tag

Karan Goyal
  • 447
  • 5
  • 10
  • [No, no, no, no, no!](https://stackoverflow.com/questions/54952088/how-to-modify-style-to-html-elements-styled-externally-with-css-using-js/54952474#54952474) – Scott Marcus Jun 29 '20 at 22:05