还有另一个关于这个的帖子,我试过了。但有一个问题:如果你删除内容,文本区域不会缩小。我找不到任何方法将其缩小到正确的大小- clientHeight值返回为文本区域的完整大小,而不是它的内容。
该页面的代码如下:
function FitToContent(id, maxHeight)
{
var text = id && id.style ? id : document.getElementById(id);
if ( !text )
return;
var adjustedHeight = text.clientHeight;
if ( !maxHeight || maxHeight > adjustedHeight )
{
adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
if ( maxHeight )
adjustedHeight = Math.min(maxHeight, adjustedHeight);
if ( adjustedHeight > text.clientHeight )
text.style.height = adjustedHeight + "px";
}
}
window.onload = function() {
document.getElementById("ta").onkeyup = function() {
FitToContent( this, 500 )
};
}
改进的响应式纯JS解决方案,以@DreamTeK的第二个选项为基础
下面还处理了底部填充以及窗口大小的调整。像这样,这对我来说是一个近乎完美的解决方案。非常感谢他。
let textareas = document.getElementsByClassName("auto-resize-textarea");
// Loop through textareas and add event listeners as well as other needed css attributes
for (const textarea of textareas) {
// Initially set height as otherwise the textarea is not high enough on load
textarea.style.height = textarea.scrollHeight.toString();
// Hide scrollbar
textarea.style.overflowY = 'hidden';
// Call resize function with "this" context once during initialisation as it's too high otherwise
resizeTextarea.call(textarea);
// Add event listener to resize textarea on input
textarea.addEventListener('input', resizeTextarea, false);
// Also resize textarea on window resize event binding textarea to be "this"
window.addEventListener('resize', resizeTextarea.bind(textarea), false);
}
function resizeTextarea() {
// Textareas have default 2px padding and if not set it returns 0px
let padding = window.getComputedStyle(this).getPropertyValue('padding-bottom');
// getPropertyValue('padding-bottom') returns "px" at the end it needs to be removed to be added to scrollHeight
padding = parseInt(padding.replace('px',''));
this.style.height = "auto";
this.style.height = (this.scrollHeight) + "px";
}
textarea {
width:40%;
padding:20px 25px;
border-radius: 20px;
}
<textarea class="auto-resize-textarea">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</textarea>
<textarea placeholder="Type, paste, cut text here..." class="auto-resize-textarea"></textarea>
注意:jsfiddle有一个奇怪的问题,文本区域太高,底部有太多的空间,但是复制和粘贴这段代码到一个空的html文件是完美的。
有一个小问题,但当滚动条出现在页面和文本区域收缩和包装文本,并创建一个新的行。上面的函数没有考虑到这一点,我提出了一个问题,但似乎没有人知道解决办法。如果你有解决这个问题的建议,我将非常高兴。
React的一个示例实现:
const {
useLayoutEffect,
useState,
useRef
} = React;
const TextArea = () => {
const ref = useRef();
const [value, setValue] = useState('Some initial text that both wraps and uses\nnew\nlines');
// This only tracks the auto-sized height so we can tell if the user has manually resized
const autoHeight = useRef();
useLayoutEffect(() => {
if (!ref.current) {
return;
}
if (
autoHeight.current !== undefined &&
ref.current.style.height !== autoHeight.current
) {
// don't auto size if the user has manually changed the height
return;
}
ref.current.style.height = "auto";
ref.current.style.overflow = "hidden";
const next = `${ref.current.scrollHeight}px`;
ref.current.style.height = next;
autoHeight.current = next;
ref.current.style.overflow = "auto";
}, [value, ref, autoHeight]);
return (
<textarea
ref={ref}
style={{
resize: 'vertical',
minHeight: '1em',
}}
value={value}
onChange={event => setValue(event.target.value)}
/>
);
}
ReactDOM.render(<TextArea />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>
jQuery的解决方案
请根据实际情况调整CSS
css……
div#container textarea {
min-width: 270px;
width: 270px;
height: 22px;
line-height: 24px;
min-height: 22px;
overflow-y: hidden; /* fixes scrollbar flash - kudos to @brettjonesdev */
padding-top: 1.1em; /* fixes text jump on Enter keypress */
}
javascript……
// auto adjust the height of
$('#container').delegate( 'textarea', 'keydown', function (){
$(this).height( 0 );
$(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keydown();
或替代jQuery 1.7+…
// auto adjust the height of
$('#container').on( 'keyup', 'textarea', function (){
$(this).height( 0 );
$(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keyup();
我已经创建了一个具有绝对最小样式的小提琴作为您的实验的起点……
http://jsfiddle.net/53eAy/951/
jQuery的解决方案是设置文本区域的高度为'auto',检查scrollHeight,然后调整文本区域的高度,每次文本区域改变(JSFiddle):
$('textarea').on( 'input', function(){
$(this).height( 'auto' ).height( this.scrollHeight );
});
如果你在动态添加文本区域(通过AJAX或其他方式),你可以在$(document)中添加这个。准备好确保所有带有类'autoheight'的文本区域保持与它们的内容相同的高度:
$(document).on( 'input', 'textarea.autoheight', function() {
$(this).height( 'auto' ).height( this.scrollHeight );
});
测试和工作在Chrome, Firefox, Opera和IE。还支持剪切和粘贴,长字等。