Tampermonkey find exact span text, then run command?

Scorpion Ghost

Elite Member
Executive VIP
Jr. VIP
Joined
Mar 22, 2013
Messages
9,144
Reaction score
10,489
I'm using Firefox. I need for a tampermonkey script to wait until an exact number appears in a span, and then run a command.

This is the code:

HTML:
<span class="time">31</span>

I want my script to run only when the number there is 0.

I tried this, and it works, but has an issue:

Code:
// ==UserScript==
// @name     bla
// @include  https://site
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a major design change
    introduced in GM 1.0.
    It restores the sandbox.
*/



//--- Note that contains() is CASE-SENSITIVE.
waitForKeyElements ("span:contains('0')", clickOnFollowButton);

function clickOnFollowButton (jNode) {
setTimeout(function(){ location.reload(); }, 15*1000);
}

The problem is that this runs even if the number is 10, 20, 30, etc.

---

I think my answer lies in .filter, but after going through a number of Stackoverflow threads, I can't figure out how to use it.

https://stackoverflow.com/questions/2338439/select-element-based-on-exact-text-contentshttps://stackoverflow.com/questions...containing-a-specific-text-value-using-jquery
Maybe something like this?

Code:
$("span").filter(function() { return ($(this).text().indexOf('FIND ME') > -1) }); -- anywhere match
$("span").filter(function() { return ($(this).text() === 'FIND ME') }); -- exact match

I don't care if the solution is jquery or javascript or waitforkeyelements. Whatever works.
 
The site won't let me edit my post for some reason. I mean, I can edit it, but I can't save, it throws an error. So I'll quote myself.

The problem is that this runs even if the number is 10, 20, 30, etc.

I need my code to run only when the number is a lone 0.
 
JavaScript:
var timeElements = document.getElementsByClassName("time");
var selectedSpan;

for (var i = 0; i < timeElements.length; i++) {
    if (timeElements[i].innerText === "31") {
   
        selectedSpan = timeElements[i];
    
        console.log(selectedSpan);
        break;
    }
}

Better but it's just a demo:

JavaScript:
function checkAndUpdate() {
    var textElements = document.getElementsByClassName("time");

    for (var i = 0; i < textElements.length; i++) {
        if (textElements[i].innerText === "0") {
            return;
        }
    }

    setTimeout(function () {
        location.reload();
    }, 1000);
}

checkAndUpdate();
 
Last edited:
JavaScript:
var timeElements = document.getElementsByClassName("time");
var selectedSpan;

for (var i = 0; i < timeElements.length; i++) {
    if (timeElements[i].innerText === "31") {
     
        selectedSpan = timeElements[i];
      
        console.log(selectedSpan);
        break;
    }
}

Nice, works. Cheers mate :)
 
@reaaski let me run another one by you. Similar situation, but need it to locate more specifically.

Code:

Code:
<li>
<a href="https://.site.com" title="MyTitle"> My Title <img data-cfsrc="https://site.com/img/bla.jpg" class="icon-token" alt="" src="https://site.com/img/ta.png" pcjr278ap="" width="16px">
<strong class="one-two three">5,012</strong>
</a>
</li>

Basically, I want it to run my code only if that number there (5,012) has 4 digits, and the first digit is 5.

If I just put your code for 5, it will run at 555 and 55 and 3275 etc. But I can't put an exact number either, because the number doesn't hit 5,000 and stops, but it can be 5,012 and 4,963 etc etc.

I tried your code and it works:

Code:
// ==UserScript==
// @name         nama
// @match        https://site.com/*
// @version      1.0
// @description  Block iFrame
// @author       You
// @grant        none
// ==/UserScript==

function checkAndUpdate() {
    var textElements = document.getElementsByClassName("one-two.three");

    for (var i = 0; i < textElements.length; i++) {
        if (textElements[i].innerText === "5") {
            return;
        }
    }

    setTimeout(function () {
alert('Hello world!');
    }, 5000);
}

checkAndUpdate();

So this works well. But it will fire if it finds any 5 in the number. But I need it to fire only if the first number is 5, and the number has a total of 4 numbers.

Alternatively, if easier, it can even fire if the number is anything above 4,900+

Any ideas?
 
Because I am a master of barely figuring it out, but figuring it out nontheless, I put this mess together :D

Code:
// ==UserScript==
// @name         asas
// @match        https://site.com/*
// @version      1.0
// @description  Block iFrame
// @author       You
// @grant        none
// ==/UserScript==


var intv = setInterval(function() {

var targetCells     = document.evaluate (
                        "/html/body/div[9]/div[9]/div[1]/div/ul/li[7]/a/strong",
                        document,
                        null,
                        XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
                        null
                    );

for (var J = targetCells.snapshotLength - 1;  J >= 0;  --J)
{
    var thisCell    = targetCells.snapshotItem (J);

    //--- Get the age.  Key off (fe)male, {age in decimal years}<br> in the text of the table cell
    var ageTxt      = thisCell.textContent.match (/5[, ]+(\d+)/i);

    if (ageTxt  &&  ageTxt.length > 1)
    {
        var age     = parseInt (ageTxt[1]);
        if (age > 0)
        {

            alert('Hello world!');

        }
    }
}

        }, 5000);

It only runs if the number is above 5,000+. I will try to make it run at 4,900+, but I may fail...

I hate that it uses XPATH to locate the stuff, and I think the code is overly complicated and that it can be made better/smaller. But, that's what I got.

If anyone has a better way, I'm all ears :)
 
var element = document.querySelector('.one-two');

if (element && element.innerText.charAt(0) === '5') {
var modifiedText = element.innerText.replace(/,/g, '');

if (/^\d{4}$/.test(modifiedText)) {
console.log('First character is 5, and modified text has exactly 4 digits.');
} else {
console.log('First character is 5, but modified text does not have 4 digits.');
}
} else {
console.log('First character is not 5 or element not found.');
}
 
// Get the element with the class 'one-two'
const element = document.querySelector('.one-two');

// Remove commas from the inner text
const innerTextWithoutCommas = element.textContent.replace(/,/g, '');

// Convert the modified inner text to a number
const numberWithoutCommas = parseInt(innerTextWithoutCommas, 10);

// Check if the number is higher than 4900
if (numberWithoutCommas > 4900) {
console.log('The number is higher than 4900.');
} else {
console.log('The number is not higher th
an 4900.');
}
 
var element = document.querySelector('.one-two');

if (element && element.innerText.charAt(0) === '5') {
var modifiedText = element.innerText.replace(/,/g, '');

if (/^\d{4}$/.test(modifiedText)) {
console.log('First character is 5, and modified text has exactly 4 digits.');
} else {
console.log('First character is 5, but modified text does not have 4 digits.');
}
} else {
console.log('First character is not 5 or element not found.');
}

Okay, much better, but I think not what I need exactly.

Can it be these two:

first character is 4, and the numbers that come after it are below 900
first character is 5, and the numbers that come after it are below 0

In this way, my code will run at anything from 4,900+ and 5,000+

This would be perfection
 
// Get the element with the class 'one-two'
const element = document.querySelector('.one-two');

// Remove commas from the inner text
const innerTextWithoutCommas = element.textContent.replace(/,/g, '');

// Convert the modified inner text to a number
const numberWithoutCommas = parseInt(innerTextWithoutCommas, 10);

// Check if the number is higher than 4900
if (numberWithoutCommas > 4900) {
console.log('The number is higher than 4900.');
} else {
console.log('The number is not higher th
an 4900.');
}

Okay wait testing...
 
Okay, much better, but I think not what I need exactly.

Can it be these two:

first character is 4, and the numbers that come after it are below 900
first character is 5, and the numbers that come after it are below 0

In this way, my code will run at anything from 4,900+ and 5,000+

This would be perfection
The first character doesn't really matter if we only care about numbers above 4900. No?
 
// Get the element with the class 'one-two'
const element = document.querySelector('.one-two');

// Remove commas from the inner text
const innerTextWithoutCommas = element.textContent.replace(/,/g, '');

// Convert the modified inner text to a number
const numberWithoutCommas = parseInt(innerTextWithoutCommas, 10);

// Check if the number is higher than 4900
if (numberWithoutCommas > 4900) {
console.log('The number is higher than 4900.');
} else {
console.log('The number is not higher th
an 4900.');
}

It's like coding blindfolded. I can't do that. I attempted to do that from bed on a phone. I give up (white flag). :D

The first character doesn't really matter if we only care about numbers above 4900. No?

Oh yeah man, all good. The code above works to perfection.

Exactly what I wanted. You the man man, thank you :)
 
Back
Top