views:

191

answers:

8
+2  Q: 

Finding text node

Is there a clever jQuery selector for selecting a text node like this:

<div><input type="text">one <span>two</span> three</div>

I would like to get three from the markup above and wrap it in a strong tag like this:

<div><input type="text">one <span>two</span> <strong>three</strong></div>
A: 

Is there a reason why you can't wrap three in some html element when you are generating the markup? It isn't really possible to grab some random word from the text and wrap it - unless you know it will always be the absolute last word in the div. If so you could do this to get the word:

var txt = $(div).text();
var txtArr = txt.split();
var wordToWrap = txtArr[txtArr.length - 1];
Keith Rousseau
+1  A: 

Not without some programming. If your main DIV had an ID or class, you could do this:

var html = $("#my_div").html();
var array = html.split("</span>");
array[1] = "<strong>" + array[1] + "</strong>";
html = array[0] + "</span>" + array[1];

$("#my_div").html(html);
tambler
caution: the above is not a general solution and never will be ;)
naugtur
A: 

I'm not sure you can easily do that with straight jQuery, unless you can wrap that word in another tag when writing it out. You could resort to regular expressions, something like:

function wrapWithTag(tagname, element, text)
{
    var html = element.html();
    var rx = new RegExp('(' + text + ')', "gi");

    element.html(html.replace(rx, '<' + tagname + '>$1</' + tagname + '>'));
}

$(function(){
    wrapWithTag('strong', $('div'), 'three');
});

The regular expression will need some tuning if you're trying to match text in different places within the element though.

Mark B
As I've already written on this page - using replace on html is risky.
naugtur
I agree it's not a perfect solution, but this is why I mentioned that regex alterations might be necessary. You could, for example, write the expression so that it only matches text that *isn't* within opening and closing angle brackets (`<>`), which would stop any HTML tags being messed up.
Mark B
A: 
//finds most inner element that has 'three' in it
var el = $(':contains(three):last');
//actual replacement
el.html(el.html().replace('three', '<strong>three</strong>'));
vava
that can be desctructive. imagine a word "type" instead of "three" - Your code breaks HTML then. Been there, done that ;)
naugtur
A: 

Check out this jQuery highlight plugin: http://tinyurl.com/6rk6ae

It might not do exactly what you want, but the source contains good examples of working with text nodes and efficiently modifying the DOM around them.

Pointy
+4  A: 

Here is how to select text nodes using jQuery:

var x = $('div') 
  .contents() 
  .filter(function() { 
    return this.nodeType == 3;
    //return this.nodeType == Node.TEXT_NODE;  this works unless using IE 7
  }); 

In your example x will then contain 'one' at index 0 and 'three' at index 1. Like Keith Rousseau said, you can't really just grab that text, but if you know it will be last you can get it like this:

var elemThree = x[x.length-1];

You can also add the strong tag like this:

$(x[x.length-1]).wrap("<strong></strong>");

This questions describes selecting text nodes with jQuery (my first code snippet).

rosscj2533
A: 

CSS can't select text nodes

jQuery uses css3 selectors that only select elements. To get the desired effect, you'll need to do the following:

var div = $('find the div')[0];
var txtNode = div.lastChild
var str = document.createElement('strong')
str.appendChild(txtNode) //removes the text node from the dom.
div.appendChild(str)
Kyle Butt
A: 

If it's not about the last word, but about the div's pure content try this:

var chld=$('div').children().clone();
$(div).children().remove();
//now do what You want with the text, eg.
$(div).html('<strong>'+$(div).text()+'</strong>'); //or something like that :)
$(div).prepend(chld); //This is a bottleneck, cause You have to know that 
          //all the text was after all the markup, but it refers to Your example.
naugtur