Fiddle: http://jsfiddle.net/nvLBZ/1/
I only have (2 hours) a script that always limits the height of the text area to 3 lines.
- The largest possible width of a character is calculated for a particular text area (if it has not already been calculated before).
- The minimum words per line are calculated.
The text field is cloned to check if you need to continue working with this function. When the input is valid, the function returns without interrupting the user.
Otherwise, the cloned text area is used as a link, and the user's text area is erased. A custom text box is also temporarily invisible for performance reasons.
- The text field is populated using the efficient method. Blocks that are known to be smaller than the width of the textarea are added to the text box.
- When the added blocks exceed the maximum size, the last characters are deleted individually until the maximum limit is reached.
- The default values ββare restored.
The code is below, the code is implemented below ( $(document).ready(...)
).
(function(){ var wordWidthMappers = {}; function checkHeight(textarea, maxLines){ if(!(textarea instanceof $)) return; /*JQuery is required*/ if(isNaN(maxLines) || !isFinite(maxLines) || maxLines == 0) return; var areaWidth = textarea.width(); var oldHeight = textarea.css("height"); var oldOverflow = textarea.css("overflow-y"); var lineHeight = parseFloat(textarea.css("line-height")); var maxTxtHeight = maxLines*lineHeight + "px"; /*Calculations for an efficient determination*/ var fontstyles = "font-size:"+textarea.css("font-size"); fontstyles += ";font-family:"+textarea.css("font-family"); fontstyles += ";font-weight:"+textarea.css("font-weight"); fontstyles += ";font-style:"+textarea.css("font-style"); fontstyles += ";font-variant:"+textarea.css("font-variant"); var wordWidth = wordWidthMappers[fontstyles]; if(!wordWidth){ var span = document.createElement("span"); span.style.cssText = fontstyles+";display:inline;width:auto;min-width:0;padding:0;margin:0;border:none;"; span.innerHTML = "W"; //Widest character document.body.appendChild(span); wordWidth = wordWidthMappers[fontstyles] = $(span).width(); document.body.removeChild(span); } textarea = textarea[0]; var temparea = textarea.cloneNode(false); temparea.style.visibility = "hidden"; temparea.style.height = maxTxtHeight; temparea.value = textarea.value; document.body.appendChild(temparea); /*Math.round is necessary, to deal with browser-specific interpretations of height*/ if(Math.round(temparea.scrollHeight/lineHeight) > maxLines){ textarea.value = ""; textarea.style.visibility = "hidden"; if(oldOverflow != "scroll") textarea.style.overflowY = "hidden"; textarea.style.height = maxTxtHeight; var i = 0; var textlen = temparea.value.length; var chars_per_line = Math.floor(areaWidth/wordWidth); while(i <= textlen){ var curLines = Math.round(textarea.scrollHeight/lineHeight); if(curLines <= maxLines){ var str_to_add = temparea.value.substring(i, i+chars_per_line); var nextLn = str_to_add.indexOf("\n"); if(nextLn > 0) str_to_add = str_to_add.substring(0, nextLn); else if(nextLn == 0) str_to_add = "\n"; i += str_to_add.length; textarea.value += str_to_add; } else if(curLines > maxLines){ textarea.value = textarea.value.substring(0, textarea.value.length-1); i--; if(Math.round(textarea.scrollHeight/lineHeight) <= maxLines) break; } } textarea.style.visibility = "visible"; textarea.style.height = oldHeight; textarea.style.overflowY = oldOverflow; } temparea.parentNode.removeChild(temparea); } $(document).ready(function(){/* Add checker to the document */ var tovalidate = $("#myTextarea"); tovalidate.keyup(function(){ /*Add keyup event handler. Optionally: onchange*/ checkHeight(tovalidate, 3); }); }); })();
Rob w source share