我正在使用this question的接受答案来构建一个文本区域,当文本溢出时,它会垂直扩展:
<!DOCTYPE html>
<html>
<head>
<title>autoresizing textarea</title>
<style type="text/css">
textarea {
border: 0 none white;
overflow: hidden;
padding: 0;
outline: none;
background-color: #D0D0D0;
resize: none;
}
</style>
<script type="text/javascript">
var observe;
if (window.attachEvent) {
observe = function (element, event, handler) {
element.attachEvent('on'+event, handler);
};
}
else {
observe = function (element, event, handler) {
element.addEventListener(event, handler, false);
};
}
function init () {
var text = document.getElementById('text');
function resize () {
text.style.height = 'auto';
text.style.height = text.scrollHeight+'px';
}
/* 0-timeout to get the already changed text */
function delayedResize () {
window.setTimeout(resize, 0);
}
observe(text, 'change', resize);
observe(text, 'cut', delayedResize);
observe(text, 'paste', delayedResize);
observe(text, 'drop', delayedResize);
observe(text, 'keydown', delayedResize);
text.focus();
text.select();
resize();
}
</script>
</head>
<body onload="init();">
<textarea rows="1" style="height:1em;" id="text"></textarea>
</body>
</html>
直到textarea的大小比浏览器窗口长,它才能正常工作。此时,每按一次键,窗口顶部就会跳到文本区域的顶部。你能帮我理解为什么以及如何解决它吗?
理想的解决方法是保持页面不移动。但是,如果将页面底部绑在textarea的底部更容易,那也可以。
我在Firefox 21.0和Chrome 28.0中遇到此问题:http://jsfiddle.net/CbqFv/
答案 0 :(得分:8)
保存scrollLeft
,scrollTop
值,然后在调整textarea大小后恢复它们:
function resize () {
var scrollLeft = window.pageXOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollLeft;
var scrollTop = window.pageYOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollTop;
text.style.height = "auto";
text.style.height = text.scrollHeight + 'px';
window.scrollTo(scrollLeft, scrollTop);
}
JSFiddle:http://jsfiddle.net/losnir/nnkeH/1
答案 1 :(得分:1)
你应该将页面滚动到:滚动条位置+(调整大小后的textarea高度 - 调整大小之前的textarea高度)
这是代码:
function resize () {
var scrollLeft = window.pageXOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollLeft;
var scrollTop = window.pageYOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollTop;
var prevHeight = text.style.height.slice(0, -2);
text.style.height = "auto";
var nextHeight = text.scrollHeight;
text.style.height = text.scrollHeight + 'px';
window.scrollTo(scrollLeft, scrollTop + (nextHeight - prevHeight));
}
或者您可以使用jquery(基于this answer)执行此操作:
$('body').on('keyup', 'textarea', function (e) {
var scrollTop = $(document).scrollTop();
var prevHeight = $(this).height();
$(this).css('height', 'auto');
var nextHeight = this.scrollHeight;
$(this).height(nextHeight);
$(document).scrollTop(scrollTop + (nextHeight - prevHeight));
});
$( 'textarea' ).keyup();
答案 2 :(得分:1)
Re losnir 的回答,在 Firefox Desktop (88) 中,window.pageXOffset
似乎返回一个非整数值,但 window.scrollTo()
将其四舍五入为整数值。因此,如果初始 window.pageXOffset
值的小数部分为 0.5 或更多,那么在每次更改文本时,textarea 框都会向下移动少量。这可能发生在其他浏览器上。解决方案是将滚动变量声明为四舍五入,然后在第一次更改文本时有一个小的移位,之后所有值无论如何都将是整数,并且不会发生进一步的移位。这给出:
function resize () {
var scrollLeft = Math.round(window.pageXOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollLeft);
var scrollTop = Math.round(window.pageYOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollTop);
text.style.height = "auto";
text.style.height = text.scrollHeight + 'px';
window.scrollTo(scrollLeft, scrollTop);
}
答案 3 :(得分:0)
当文本区域位于可滚动的div中时,一种可以接受的答案的方法:
function getScrollParent(node) {
if (node == null) {
return null;
}
if (node.scrollHeight > node.clientHeight) {
return node;
} else {
return getScrollParent(node.parentNode);
}
}
function resize(){
// 'this' is the textarea
const scrollParent = getScrollParent(this);
const scrollTop = scrollParent ? scrollParent.scrollTop : null;
const scrollLeft = scrollParent ? scrollParent.scrollLeft : null;
this.style.height = "auto";
this.style.height = this.scrollHeight + "px";
if (scrollParent) {
scrollParent.scrollTo(scrollLeft, scrollTop);
}
};
答案 4 :(得分:0)
我的回答基于接受的height of textarea increases when value increased but does not reduce when value is decreased答案中的小提琴。
这适用于页面加载以及以任何方式(剪切,粘贴,键入等)更改文本的情况
$('textarea').on('keyup keydown', function () {
var $this = $(this);
var initialHeight = $this.height();
$this
.height(initialHeight - 40)
.height($this[0].scrollHeight + 20);}).trigger('keyup');
我抓住初始高度的原因是,textarea不必跳到1或任何其他静态数字即可触发scrollHeight的值。 (据我了解,是因为文本框设置为该静态高度(通常为1)然后展开,导致屏幕更改滚动的原因)我向scrollHeight添加20的原因是因为有时scrollHeight关闭了1或2px,并且文本看起来像堆在底部。因此,为了给它更多空间,我个人添加了20。
答案 5 :(得分:0)
发现这是迄今为止最好的解决方案,结合 Adam Beres-Deak 和 @losnir 的代码并得出以下结果。
迄今为止最有用的:
URL Links
0 https://stackoverflow.com/questions/ask [#, https://stackoverflow.com, /company, #, /t...
if(window.attachEvent){
observe = function(element, event, handler){ element.attachEvent('on'+event, handler); };
}else{
observe = function(element, event, handler){ element.addEventListener(event, handler, false); };
}
function init(){
var textAreas = [].slice.call(document.querySelectorAll('textarea[data-adaptheight]'));
textAreas.forEach(function(el){
function resize(){
var scrollLeft = window.pageXOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollLeft;
var scrollTop = window.pageYOffset ||
(document.documentElement || document.body.parentNode || document.body).scrollTop;
el.style.resize = "none";
el.style.overflow = 'hidden';
el.style.boxSizing = el.style.mozBoxSizing = 'border-box';
el.style.height = "auto";
el.style.height = el.scrollHeight + 'px';
window.scrollTo(scrollLeft, scrollTop);
}
observe(el, 'input', resize);
resize();
});
}
init();