views:

69

answers:

3

Are there any text selector in jquery ?

My Code

<anything>Hello World! Hello World!</anything>

Reslut Should be (Using Jquery)

<anything>Hello <span>World</span>! Hello <span>World</span>!</anything>
+1  A: 

You can do a regex replacement, etc for your simple case, but for a more general answer: no.

jQuery just doesn't provide much help when dealing with text nodes, it's designed primarily for dealing with element node types (nodeType == 1), not text node types (nodeType == 3)...so yes you can use it where it helps (e.g. .contents() and .filter()), but that won't be often since it's not the library's main purpose.

Nick Craver
Typo: `noteType` should be `nodeType`
Day
@Day - oops typo, thanks for the catch! updated
Nick Craver
+1  A: 
Šime Vidas
@bobince Good catch. Instead of text(), the html() method has to be used... However, now we have to be careful that the regexp does not destroy tags in the innerHMTL string
Šime Vidas
Yes (oops! I moved the comment). The above is dangerous as it will happily match non-text content. And also it's unreliable for strings in general as the browser decides which characters to HTML-escape (not a problem for the letters `World`, but can be for other strings). And also it destroys and recreates all contained elements, which will wipe out any non-serialisable properties, such as form values or event handlers. It's hacking HTML with regex, which for a simple element containing only text you might get away with, but all the usual problems are lurking there.
bobince
I elected to delete my answer as everything that can possibly be wrong with it is wrong.
BoltClock
@bobince Yes, my solution is OK only for strings that are pure text. Therefore, it is a limited solution. But, if the OP's situation is such where he deals with raw text only, then he should be fine. I personally prefer more elaborate solutions (like the solution you proposed).
Šime Vidas
Indeed. I wanted to make this clear so that the next Googler doesn't come along and start using `html()` replacement in a more complicated case, like over an element with child element content. Unfortunately this is commonly done and it often leads to bugs and security holes in such cases.
bobince
+1  A: 

No. jQuery works primarily with elements and gives you very little for handling text.

To do a find-and-replace on text you will need to check each text node separately and do DOM splitText operations to take it apart when a match is found. For example:

function findText(element, pattern, callback) {
    for (var childi= element.childNodes.length; childi-->0;) {
        var child= element.childNodes[childi];
        if (child.nodeType==1) {
            var tag= child.tagName.toLowerCase();
            if (tag!=='script' && tag!=='style' && tag!=='textarea')
                findText(child, pattern, callback);
        } else if (child.nodeType==3) {
            var matches= [];
            var match;
            while (match= pattern.exec(child.data))
                matches.push(match);
            for (var i= matches.length; i-->0;)
                callback.call(window, child, matches[i]);
        }
    }
}

findText(element, /\bWorld\b/g, function(node, match) {
    var span= document.createElement('span');
    node.splitText(match.index+match[0].length);
    span.appendChild(node.splitText(match.index));
    node.parentNode.insertBefore(span, node.nextSibling);
});
bobince
I recommend using blocks in compound statements like if, for and while.
Šime Vidas