1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| $(function() { var hiddenTextarea;
var HIDDEN_STYLE = ` height:0 !important; visibility:hidden !important; overflow:hidden !important; position:absolute !important; z-index:-1000 !important; top:0 !important; right:0 !important; `;
var CONTEXT_STYLE = [ 'letter-spacing', 'line-height', 'padding-top', 'padding-bottom', 'font-family', 'font-weight', 'font-size', 'text-rendering', 'text-transform', 'width', 'text-indent', 'padding-left', 'padding-right', 'border-width', 'box-sizing' ]; function calculateNodeStyling(targetElement) { var style = window.getComputedStyle(targetElement);
var boxSizing = style.getPropertyValue('box-sizing');
var paddingSize = ( parseFloat(style.getPropertyValue('padding-bottom')) + parseFloat(style.getPropertyValue('padding-top')) );
var borderSize = ( parseFloat(style.getPropertyValue('border-bottom-width')) + parseFloat(style.getPropertyValue('border-top-width')) );
var contextStyle = CONTEXT_STYLE .map(function(value){ return value + ':' + style.getPropertyValue(value) }).join(';');
return { contextStyle, paddingSize, borderSize, boxSizing }; } $('body').on('focus', 'textarea', function () { var _this = $(this); if (!hiddenTextarea) { hiddenTextarea = document.createElement('textarea'); document.body.appendChild(hiddenTextarea); } var { paddingSize, borderSize, boxSizing, contextStyle } = calculateNodeStyling(_this[0]); hiddenTextarea.setAttribute('style', HIDDEN_STYLE + contextStyle); }).on('keydown keyup', 'textarea', function(){ var _this = $(this); var { paddingSize, borderSize, boxSizing, contextStyle } = calculateNodeStyling(_this[0]); hiddenTextarea.setAttribute('style', HIDDEN_STYLE + contextStyle); hiddenTextarea.value = _this[0].value || _this[0].placeholder || '';
var height = hiddenTextarea.scrollHeight;
if (boxSizing === 'border-box') { height = height + borderSize; } else if (boxSizing === 'content-box') { height = height - paddingSize; }
hiddenTextarea.value = ''; var singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;
var minRows = _this.attr('rows') ? _this.attr('rows') : _this.attr('data-min-rows') ? _this.attr('data-min-rows') : 1; var maxRows = _this.attr('data-max-rows') ? _this.attr('data-max-rows') : null; if (minRows !== null) { var minHeight = singleRowHeight * minRows; if (boxSizing === 'border-box') { minHeight = minHeight + paddingSize + borderSize; } height = Math.max(minHeight, height); } if (maxRows !== null) { var maxHeight = singleRowHeight * maxRows; if (boxSizing === 'border-box') { maxHeight = maxHeight + paddingSize + borderSize; } height = Math.min(maxHeight, height); }
_this.css('height', height + 'px'); }).on('blur', 'textarea', function () { hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea); hiddenTextarea = null; }) })
|