How to wrap each word of an element in a span tag?

You don't need jQuery for this simple task. String.prototype.replace and regex should do the trick.

I just made some simple utility functions, that wraps letters, words and lines:

/**
 * Wraps a string around each character/letter
 *
 * @param {string} str The string to transform
 * @param {string} tmpl Template that gets interpolated
 * @returns {string} The given input as splitted by chars/letters
 */
function wrapChars(str, tmpl) {
  return str.replace(/\w/g, tmpl || "<span>$&</span>");
}

/**
 * Wraps a string around each word
 *
 * @param {string} str The string to transform
 * @param {string} tmpl Template that gets interpolated
 * @returns {string} The given input splitted by words
 */
function wrapWords(str, tmpl) {
  return str.replace(/\w+/g, tmpl || "<span>$&</span>");
}

/**
 * Wraps a string around each line
 *
 * @param {string} str The string to transform
 * @param {string} tmpl Template that gets interpolated
 * @returns {string} The given input splitted by lines
 */
function wrapLines(str, tmpl) {
  return str.replace(/.+$/gm, tmpl || "<span>$&</span>");
}

The usage is pretty simple. Just pass in the string to wrap as first argument. If you need custom markup, pass it in as the second argument, while $& is replaced by each char/word/line.

var str = "Foo isn't equal\nto bar.";
wrapChars(str); // => "<span>F</span><span>o</span><span>o</span> <span>i</span><span>s</span><span>n</span>'<span>t</span> <span>e</span><span>q</span><span>u</span><span>a</span><span>l</span> <span>t</span><span>o</span> <span>b</span><span>a</span><span>r</span>."
wrapWords(str); // => "<span>Foo</span> <span>isn</span>'<span>t</span> <span>equal</span> <span>to</span> <span>bar</span>."
wrapLines(str); // => "<span>Foo isn't equal</span> <span>to bar.</span>"

If your element contents contains child elements (HTML) then the above solutions are not useful.

Here's a jsfiddle I've come up with that preserves HTML (elements and their attributes). The shortcoming of this small snippet is that if you have events binded to the element's contents then they will be lost since innerHTML is being reassigned to something else.

This code does not require any special libraries (like jQuery).

https://jsfiddle.net/4b5j0wjo/3/

var e = document.getElementById('words');
e.innerHTML = e.innerHTML.replace(/(^|<\/?[^>]+>|\s+)([^\s<]+)/g, '$1<span class="word">$2</span>');

It's gonna be a little more complicated than that. You're gonna have to find out all the words and re-append them to your element, wrapped in a span.

var words = $("p").text().split(" ");
$("p").empty();
$.each(words, function(i, v) {
    $("p").append($("<span>").text(v));
});

Live example