Before splitting the string into individual characters, split it into an array of words. You can then loop through each word, loop through the characters in each word, and do what you need to do in between.
In the example I've got here, I've split things into a couple functions to break things up. This example also includes the ability to conditionally add css classes to the wrapping element.
The basic method here:
- Split the text up into an array of words.
- Loop over the
words
array, adding a wrapper to each word, and passing it to a function that wraps each character.
- push the result to a new array
- return the joined version of the array to create the new string.
Quick note: I used a bit of es6 syntax here, so if you don't want to use template literals, you can replace things with string contatination.
/**
* Add wrappers to individual characters in a word
* @method addWrappers
* @param {String} word - The word to be processed
* @param {String} tag - The HTML tag to be used for the wrappers
* @param {String} classes - OPTIONAL - Any CSS classes to be applied
* @return {String} - Wrapped chracters as a new string.
*/
function addWrappers(word, tag, classes) {
// Split into individual characters.
const chars = word.split('');
// The array the newly wrapped
// characters will be added to.
const wrappedChars = [];
// The loop
chars.forEach(function(char) {
// Check if any classes were passed.
// If so add them, else just use a basic tag.
const openTag = classes ? `${tag} class="${classes}"` : tag;
wrappedChars.push(`<${openTag}>${char}</${tag}>`);
});
return wrappedChars.join('');
}
// A basic implementation.
function initBasic() {
const element = document.querySelector('.fancy-word')
const text = element.textContent;
// Split the string into words
const words = text.split(' ');
// Our array of processed words
const newContent = [];
// The main loop
words.forEach(function(word) {
newContent.push(`<span class="word">${addWrappers(word, 'span', 'word__inner')}</span>`);
});
// Add a space to keep the words looking
// right wirhout styling, but you can easily just
// leave it out and use margins or padding
// to create the desired effect.
element.innerHTML = newContent.join(' ');
console.log(element.outerHTML);
}
initBasic();
<h1 class="fancy-word">About my site</h1>
EXAMPLE WITHOUT TEMPLATE LITERALS:
/**
* Add wrappers to individual characters in a word
* @method addWrappers
* @param {String} word - The word to be processed
* @param {String} tag - The HTML tag to be used for the wrappers
* @param {String} classes - OPTIONAL - Any CSS classes to be applied
*/
function addWrappers(word, tag, classes) {
const chars = word.split('')
const wrappedChars = [];
chars.forEach(function(char) {
const openTag = classes ? tag + ' class="' + classes + '"' : tag;
wrappedChars.push('<' + openTag + '>' + char + '</' + char + '>')
});
return wrappedChars.join('');
}
function initBasic() {
const element = document.querySelector('.fancy-word')
const text = element.textContent;
const words = text.split(' ');
const newContent = [];
words.forEach(function(word) {
newContent.push('<span class="word">' + addWrappers(word, 'span', 'word__inner') + '</span>');
});
element.innerHTML = newContent.join(' ');
console.log(element.outerHTML);
}