JavaScript代码,如何控制文本输入域textarea高度自适应而不出现滚动条?

星级:
HTML中,文本输入域的scrollHeight为输入域元素包含隐藏高度在内的真正高度,如果使用js代码监听输入域的propertychange、input和focus等属性变化,每次监听后利用其scrollHeight重新计算其高度,就可以实现文本输入域的高度自适应而不出现滚动条的需求。

HTML中,文本输入域<textarea></textarea>的高度在正常情况下是固定不变的。当文本输入域内部的文本超过设定的高度时,文本输入域会出现滚动条。

假如有用户需求需要将文本输入域的高度设定为自适应,即

当文本输入域内部的文本行数变多时,文本输入域高度增加相应的高度;

当文本输入域内部的文本行数变少时,文本输入域的高度减少相应的高度;

这样,使得文本输入域高度永远与内部文本相适应,而不出现滚动条;

如果想要实现以上功能,其实可以利用JavaScript代码监控相应文本输入域的propertychange、input和focus属性值变化,当这些属性值发生变化时,利用文本输入域的scrollHeight重新计算文本输入域高度即可。

<!DOCTYPE html> 

<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>文本框根据输入内容自适应高度</title>
<style type="text/css">
body{
background: #666;
text-align: center;
padding-top: 100px;
}
#test-textarea {
font: 16px Arial;
overflow: hidden;
width: 550px;
line-height: 24px;
height: 96px;
padding:10px;
}
</style>
<script>
</script>
</head>
<body>
<textarea id="test-textarea"></textarea>
</body>
<script>
/**
* 文本框根据输入内容自适应高度
* @author tang bin
* @param {HTMLElement} 输入框元素
* @param {Number} 设置光标与输入框保持的距离(默认10)
* @param {Number} 设置最大高度(可选)
*/
var autoTextarea = function (elem, extra, maxHeight) {
extra = extra || 10;
var isFirefox = !!document.getBoxObjectFor || 'mozInnerScreenX' in window,
isOpera = !!window.opera && !!window.opera.toString().indexOf('Opera'),
addEvent = function (type, callback) {
elem.addEventListener ?
elem.addEventListener(type, callback, false) :
elem.attachEvent('on' + type, callback);
},
getStyle = elem.currentStyle ? function (name) {
var val = elem.currentStyle[name];

if (name === 'height' && val.search(/px/i) !== 1) {
var rect = elem.getBoundingClientRect();
return rect.bottom - rect.top -
parseFloat(getStyle('paddingTop')) -
parseFloat(getStyle('paddingBottom')) + 'px';
};

return val;
} : function (name) {
return getComputedStyle(elem, null)[name];
},
minHeight = parseFloat(getStyle('height'));


elem.style.resize = 'none';

var change = function () {
var scrollTop, height,
padding = 0,
style = elem.style;

if (elem._length === elem.value.length) return;
elem._length = elem.value.length;

if (!isFirefox && !isOpera) {
padding = parseInt(getStyle('paddingTop')) + parseInt(getStyle('paddingBottom'));
};
scrollTop = document.body.scrollTop || document.documentElement.scrollTop;

elem.style.height = minHeight + 'px';
if (elem.scrollHeight > minHeight) {
if (maxHeight && elem.scrollHeight > maxHeight) {
height = maxHeight - padding;
style.overflowY = 'auto';
} else {
height = elem.scrollHeight - padding;
style.overflowY = 'hidden';
};
style.height = height + extra + 'px';
scrollTop += parseInt(style.height) - elem.currHeight;
document.body.scrollTop = scrollTop;
document.documentElement.scrollTop = scrollTop;
elem.currHeight = parseInt(style.height);
};
};
//添加监听事项
addEvent('propertychange', change);
addEvent('input', change);
addEvent('focus', change);
change();
};
//获取textarea元素
var text = document.getElementById("test-textarea"),
tip = '可以在这里输入测试文本';

autoTextarea(text);// 调用

text.value = tip;

text.onfocus = function () {
if (text.value === tip) text.value = '';
};
text.onblur = function () {
if (text.value === '') text.value = tip;
};
</script>
</html>