Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Remove text widows - words that wrap by themselves
$(document).ready(function() {
$('.no-widow, h1, h2, h3, a').each( function(){
antiWidowMaker( $(this) );
});
});
$(window).resize(function() {
$('.no-widow, h1, h2, h3, a').each( function(){
antiWidowMaker( $(this) );
});
});
function antiWidowMaker( text_element )
{
console.log('~ widow\'d');
var string = text_element.text();
var parent = text_element.parent();
var parent_width = parent.width();
var parent_height = parent.height();
// determine how many lines the text is split into
var lines = parent_height / getLineHeight(text_element.parent()[0]);
// if the text element width is less than the parent width,
// there may be a widow
if ( text_element.width() < parent_width )
{
// find the last word of the entire text
var last_word = text_element.text().split(' ').pop();
// remove it from our text, creating a temporary string
var temp_string = string.substring( 0, string.length - last_word.length - 1);
// set the new one-word-less text string into our element
text_element.text( temp_string );
// check lines again with this new text with one word less
var new_lines = parent.height() / getLineHeight(text_element.parent()[0]);
// if now there are less lines, it means that word was a widow
if ( new_lines != lines )
{
// separate each word
temp_string = string.split(' ');
// put a space before the second word from the last
// (the one before the widow word)
if ( lines > 2 ){
var words_to_cut = 2;
} else {
var words_to_cut = Math.round((temp_string.length / (lines - 1)) / 2);
}
temp_string[ temp_string.length - ( words_to_cut ) ] = '<br>' + temp_string[ temp_string.length - words_to_cut ] ;
// recreate the string again
temp_string = temp_string.join(' ');
// our element html becomes the string
text_element.html( temp_string );
}
else
{
// put back the original text into the element
text_element.text( string );
}
}
}
function getLineHeight(element){
var temp = document.createElement(element.nodeName);
temp.setAttribute("style","margin:0px;padding:0px;font-family:"+element.style.fontFamily+";font-size:"+element.style.fontSize);
temp.innerHTML = "test";
temp = element.parentNode.appendChild(temp);
var ret = temp.clientHeight;
temp.parentNode.removeChild(temp);
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment