Select numbers on a page with jQuery or Javascript
Asked Answered
C

4

13

I'm just wondering if there's a way to locate numbers on a page with jQuery or plain Javascript.

Here's what I want to do:

Say "June 23" is on the page. What I want to do is be able to prepend and append some <span> selectors to the number.

Using :contains() with jQuery selects the whole thing, not just the number.

These strings are being generated without any wrapping elements by a Wordpress theme I'm working on, and I only want to select the number.

Any help would be appreciated! Thanks for even thinking about it.
-George

Currish answered 25/6, 2011 at 22:2 Comment(2)
Do you know the exact element your date is in? Could you do some regex-ing maybe and find a date?Jaggery
+1 for the interesting questionAguirre
S
12

You can walk through all the elements, looking at text nodes, and replacing them with updated content that has the number wrapped.

var regex = /(\d+)/,
    replacement = '<span>$1</span>';

function replaceText(el) {
    if (el.nodeType === 3) {
        if (regex.test(el.data)) {
            var temp_div = document.createElement('div');
            temp_div.innerHTML = el.data.replace(regex, replacement);
            var nodes = temp_div.childNodes;
            while (nodes[0]) {
                el.parentNode.insertBefore(nodes[0],el);
            }
            el.parentNode.removeChild(el);
        }
    } else if (el.nodeType === 1) {
        for (var i = 0; i < el.childNodes.length; i++) {
            replaceText(el.childNodes[i]);
        }
    }
}

replaceText(document.body);

Example: http://jsfiddle.net/JVsM4/

This doesn't do any damage to existing elements, and their associated jQuery data.


EDIT: You could shorten it a bit with a little jQuery:

var regex = /(\d+)/g,
    replacement = '<span>$1</span>';

function replaceText(i,el) {
    if (el.nodeType === 3) {
        if (regex.test(el.data)) {
            $(el).replaceWith(el.data.replace(regex, replacement));
        }
    } else {
        $(el).contents().each( replaceText );
    }
}

$('body').each( replaceText );

Example: http://jsfiddle.net/JVsM4/1/

Note that the regex requires the g global modifier.

Probably a little slower this way, so if the DOM is quite large, I'd use the non-jQuery version.

Sathrum answered 25/6, 2011 at 22:27 Comment(0)
A
1

Just thinking out loud, but do you reckon this would work?

document.body.innerHTML = document.body.innerHTML.replace(/(\d+)/g, "<span class='number'>$1</span>")
Adverb answered 25/6, 2011 at 22:22 Comment(6)
@andreas That seems like it would grab the numbers, but I only want to prepend and append the span. Would $1 replace the number? (I'm a javascript noob)Currish
@Currish It replaces all numbers N with <span class='number'>N</span>, so all numbers get wrapped in <span>s. I just did it on this page and it does tend to break things. :)Adverb
@Currish it'll do exactly what you want it to - but instead of appending and prepending (which is only possible with DOM manipulation against elements) it'll take the number (as string) and then prepend &lt;span class='number'> and append &lt/span>, then replacing the number text form the document with the result from the previous operationAguirre
Replacing on document.body.innerHTML is a bad idea. For instance, it will destroy any event handlers such as .click().Overlap
Thanks guys. This solution worked, but, like you said, it crashed some .click() and like .mouseenter() events I had going on. Patrick DW's solution worked best.Currish
You can't parse (X)HTML with regex.. And replacing the entire HTML is completely wrong.Exhibitor
J
0

It is fully dependent on what format your date is.

I found this website with a lot of different regular expressions (because you are just searching a normal piece of text for a date).

This seems a good option if this is your format for your date (dd MMM yyyy): http://regexlib.com/REDetails.aspx?regexp_id=405

I assume, because it is a template, that your dates will be the same for all pages. So the format will be the same as well. You can use the regular expression on every piece of text on your template if you define it well.

Jaggery answered 25/6, 2011 at 22:17 Comment(2)
Thanks for the input, but it's not formatted dates I'm looking for. Just numbers, not necessarily in any formatCurrish
Thanks Everyone @Patrick DW 's solution works great. Thanks man!Currish
G
0

You can also select decimal numbers that contain comma as thousands separators:

let regex = /([,\d]*\.?\d+)/g;

This will match 1234 and 1,234 and 1234.5678 and 1,234.5678 and 0.5678 and .5678.

Refer to the above answer for full solution.

Gregg answered 24/12, 2021 at 11:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.