1

i'm completely new to Javascript and I wanted to create an Greasemonkey Script that replaced "/text/othertext/" to "/text2/text3" on all the href elements of the document. That's what i came up with, and as expected, it doesn't work:

var links = document.getElementsByTagName('a');
for (i=0; i<links.length; i++)
 {
   var gethref = links[i].getAttribute('href');
   gethref = gethref.replace(/text\/othertext/g,'text2\/text3');
   links[i].setAttribute("href", gethref);
  }

Thanks in advance!


Edit: ok, i know why my script is not working, but i don't know if it can be fixed, i'm trying to replace elements that load after the page is completely loaded (maybe with ajax?) https://i.stack.imgur.com/Kjm6P.png

4 Answers4

1

This code works. Your code looks okay too. Perhaps you are loading the script before the document elements? Note how my elements are listed before my script:

<a href="before">link</a>
<a href="before">link</a>
<script>
    var links = document.getElementsByTagName('a');
    for(var i = 0; i < links.length; i++) {
        var href = links[i].getAttribute('href');
        href = href.replace('before', '#');
        links[i].setAttribute('href', href);
    }
</script>

Edit, based on your comments a dirty fix to cause delay in your app before running a script is to use the setTimeout function. To delay five seconds for example, you might use it like this:

<a href="before">link</a>
<a href="before">link</a>
<script>
    setTimeout(function() {
        var links = document.getElementsByTagName('a');
        for(var i = 0; i < links.length; i++) {
            var href = links[i].getAttribute('href');
            href = href.replace('before', '#');
            links[i].setAttribute('href', href);
        }
    }, 5000); // < --- note the time in ms here
</script>
ThisClark
  • 14,352
  • 10
  • 69
  • 100
  • Ok, i know what i was missing, can you have a look at my edit? – Manuestaire Aug 27 '15 at 02:24
  • @Manuestaire I believe your edit makes this problem more complex. It seems you need to listen to changes on the DOM itself, so perhaps this post can help you solve this: [Most efficient method of detecting/monitoring DOM changes?](http://stackoverflow.com/questions/2457043/most-efficient-method-of-detecting-monitoring-dom-changes) – ThisClark Aug 27 '15 at 02:58
  • I think that's getting out of my span, i've tried with `setInterval(function() { var anchors......., 2000);` and despite it continuosly runs the script, it doesn't seem to change the new elements that appear when the dropdown menu appears. Will listen at DOM changes help? – Manuestaire Aug 27 '15 at 03:07
  • @Manuestaire If all you want is a delay after page load, use `setTimeout` method. See my edit. – ThisClark Aug 27 '15 at 03:12
  • If this happens after a dropdown menu appears, listening to the DOM changes may be your most efficient timing. Otherwise, you could cause unnecessary delay or worse miss the event because you used a timeout and it happened too early. – ThisClark Aug 27 '15 at 03:16
  • Nah, a delay won't help, the element containing the href i'm modifing (a dropdown menu) is loaded when clicking on an element. What i tried was that the script was iterating forever, but it didn't seem to work. I've had a look at http://api.jquery.com/Ajax_Events/ and i think that if that's the only way to go, i'll be giving up on this, i don't know where to start with Ajax... – Manuestaire Aug 27 '15 at 03:20
  • You can add an `onclick` event to the element and try putting your logic in there – ThisClark Aug 27 '15 at 03:26
  • That looks terribly scaring: http://imgur.com/LzWrk9m Honestly I'm not even sure that with my knowledge i'd be able to trigger the logic on click, so i'm getting off in here. Thanks a lot for your help, at least i think I've learnt a lot of javascript with this thread! :D – Manuestaire Aug 27 '15 at 03:35
0

Not too sure why your code wouldn't be working.

I've put together the following snippet which might help.

(function() {
  var anchors = document.querySelectorAll('a');
  for(var i = 0; i < anchors.length; i++) {
    var newHref = anchors[i].getAttribute('href').replace(/text\/othertext/g,'text2\/text3');
    anchors[i].setAttribute('href', newHref);
  }
}());
a {
  display: block;
}
<!DOCTYPE html>
<head></head>
<body>
  <a href="text/othertext">Some link</a>
  <a href="egerg">Some other link</a>
</body>

If you run this snippet you'll see only one anchor is updated correctly as intended.

Hope that helps you out!

Jhey
  • 1,377
  • 7
  • 10
  • Tried with `window.onload = function(){ var anchors = document.querySelectorAll('a'); for(var i = 0; i < anchors.length; i++) { var newHref = anchors[i].getAttribute('href').replace(/admin\/e/g,'moderator'); anchors[i].setAttribute('href', newHref); } }; alert('"it runs"');` Links still not changing, i'm willing to provide my skype to share desktop if i can get any help in that way... – Manuestaire Aug 27 '15 at 02:09
  • Hey @Manuestaire , where is your script file being loaded into the DOM? I would personally avoid `window.onload` and use the code as I've written it inside an IIFE. (the safety wrapper function) so that it runs anyway. Make sure however that your script tag is the last element within the body after all of your links. Hope that helps you out. – Jhey Aug 27 '15 at 10:37
0

The easiest solution would be to wrap your code in this:

window.onload = function(){
    /* your code here */
};

This will ensure that your code (especially if you've placed your script in the of the document, won't load until the whole page is loaded (including text, images, etc).

Aaron_H
  • 1,623
  • 1
  • 12
  • 26
0

window.onload = function() {
  document.body.innerHTML = document.body.innerHTML
    .replace('<a href="text/othertext/"', '<a href="text2/text3"');
};
<!DOCTYPE html>

<head></head>

<body>
  <a href="text/othertext/">Some link</a>
  <a href="egerg">Some other link</a>
</body>
Vidul
  • 10,128
  • 2
  • 18
  • 20