1

I'm trying to run a script in Tampermonkey and have it run one single time in a tab or on a given webpage page before it stops. The script currently automatically clicks any "a" element link that has a given word within it. Example HTML code like so:

<a href="adbc.com">Contact</a>

The script will click on that link given that I have specified the word "Contact" in the script. The script I have, unfortunately, continues to run infinitely within a single page / tab in my browser, no matter how many times it has been clicked. I want this to stop - and be used one single time within a tab (even when it goes to the next link that's been clicked).

I want this script to stop once it has clicked on a single link - or only run once in a single tab or from a single page. Oftentimes this is usually not a problem because the next loaded page (the clicked link) won't contain a link with the given phrase... But sometimes it will, which will cause the page to just click on links infinitely. I need a way to avoid this problem - to only have the script click once or on one link. This can involve exiting the script, pausing the script, or simply just having the program run one single time.

Right now I have the following code, which automatically clicks any links with the phrase "Contact" within them:

// ==UserScript==
// @name     Music Submissions Contact
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @include  *
// @grant    GM_addStyle
// ==/UserScript==

var TargetLink = $("a:contains('Contact')")

if (TargetLink.length)
    window.location.href = TargetLink[0].href

I want a way for this script to stop/exit/close/pause/suspend after one single click. I've been unable to find the correct syntax or logic, so any advice would surely help.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
theCrabNebula
  • 731
  • 2
  • 13
  • 29
  • 2
    What is probably happening is that it's clicking on the link (well, actually modifying the URL, rather than clicking), which loads the page in the same tab, which gives makes a *new* copy of the script to run, which clicks the link, which opens the page in the same tab...etc, etc. You can try [GM.openInTab](https://wiki.greasespot.net/GM.openInTab), so you don't modify the current tab. Or [GM.setValue](https://wiki.greasespot.net/GM.setValue) and GM.getValue to write a token that a link has already been used. Not sure if you can do it for each tab, though. – VLAZ Sep 19 '18 at 23:22
  • 1
    As @vlaz states, there's multiple ways to go about it, depending on your needs. For the simplest case of redirecting the "Contact" link only once, you could set `GM.setValue("lastLink", "Contact")` inside your if statement, and then check if `GM.getValue("lastLink")` is equal to "Contact". Like this `if (TargetLink.length && GM.getValue("lastLink", "") != "Contact") { GM.setValue("lastLink", "Contact") ;window.location.href = TargetLink[0].href; }` – Exfridos Sep 20 '18 at 00:11
  • 1
    @Exfridos, the difficulty with that is if you have the same script running in multiple instances. It can get quite messy. That's why TM provides `GM_saveTab()`, etc. – Brock Adams Sep 20 '18 at 01:05
  • 1
    @theCrabNebula , If you are going to use `@include *` ([generally something to avoid](https://stackoverflow.com/questions/52225924/is-it-risky-to-run-my-own-userscripts-on-all-addresses)), you should strongly consider also adding `@noframes`. – Brock Adams Sep 20 '18 at 01:08
  • 1
    This seems easy to fix without any knowledge of tamper monkey, use a boolean guard ? – Rheijn Sep 20 '18 at 09:39
  • 1
    Thanks for the replies. Also did not know about @noframes – theCrabNebula Sep 20 '18 at 21:09

1 Answers1

2

You can do this in Tampermonkey using GM_getTab() and GM_saveTab() (Here's the doc page for both).

These functions set and retrieve data that persists only in a given tab, regardless of page loads or domain changes.

Here's a fully working script (just adjust the pages it runs on) that demonstrates the technique:

// ==UserScript==
// @name     _Data that persists only in tab, cross-domain, cross page loads
// @match    *://YOUR_SERVER.COM/YOUR_PATH/*
// @grant    GM_saveTab
// @grant    GM_getTab
// ==/UserScript==
/* eslint-disable no-multi-spaces */

GM_getTab ( thisTabData => {
    console.log ("thisTabData: ", thisTabData);
    if (thisTabData.bornOn) {
        console.info ("Userscript has already run for this tab.");
        return;
    }
    var tmStamp         = (new Date() ).getTime ();
    thisTabData.bornOn  = tmStamp;
    GM_saveTab (thisTabData);

    scriptMain ();
} );

function scriptMain () {
    // PUT THE CODE THAT YOU ONLY WANT TO RUN ONCE PER TAB, HERE.
    console.log ("Script main code ran.");
}
Brock Adams
  • 90,639
  • 22
  • 233
  • 295