※ 이 팁은 javascript framework 인 prototype.js 가 필요합니다.
예전에 비슷한 것을 만든 적이 있는데, 이번엔 조금 다른 방식으로 접근해봤습니다.
이번엔 "예측" - 즉, 때려맞추기 방법을 썼습니다. -_-;;
구글 녀석들이 조금 비슷하게 쓰는 것 같길래... 히~
클래스 생성하고, Event 를 attach 하는 쪽에서 prototype.js 에 의존적입니다. protoytpe.js 를 쓰기 시작한지 1년이 조금 넘은 것 같은데, 쓰면 쓸수록 너무 편합니다. 1년 사이에 만들어낸 스크립트들이 거의 다 이넘을 기반으로 하고 있어서 공개도 안하고 있다가... 그나마 이넘은 의존성이 적어서 쉽게 수정하실 수 있을 것 같아 공개합니다. ^^
[code type=js]
/*
* textarea auto expander by gony (http://mygony.com)
* 2006. 7. 10
* dependent on prototype.js (http://prototype.conio.net)
*/
var Textarea = Class.create();
Textarea.prototype = {
.initialize : function(obj) {
..this._obj = $(obj);
..this._fwidth = 0;
..this._fheight = 0;
..this._minRows = parseInt(this._obj.rows); // minimum size
..if (isNaN(this._minRows)) this._minRows = 5;
..Event.observe(this._obj, 'focus', this.init.bind(this));
..Event.observe(this._obj, 'keydown', this.onKeydown.bindAsEventListener(this));
..Event.observe(this._obj, 'keyup', this.onKeyup.bindAsEventListener(this));
.},
.init : function() {
..if (this._fwidth != 0) return;
..var container = document.createElement('SPAN');
..$(container).setStyle({
...'visibility' : 'hidden',
...'padding' : '0px',
...'fontSize' : this._obj.style.fontSize==''?'9pt':this._obj.style.fontSize
...});
..document.body.appendChild(container);
..container.innerHTML = 'a'; // for width of 1 byte
..this._fwidth = container.offsetWidth;
..this._fheight = container.offsetHeight;
..document.body.removeChild(container);
.},
.getBytes : function(str) {
..var code,bytes = 0;
..var len = str.length;
..for(var i=0; i < len; i++) {
...code = str.charCodeAt(i);
...if (code > 128) bytes += 2;
...else if (code > 63 && code < 91) bytes += 1.5;
...else bytes += 1;
..}
..return bytes;
.},
.onKeydown : function(event) {
..if (event.keyCode == Event.KEY_RETURN || (event.ctrlKey && event.keyCode == 86)) {
...// enter key or Ctrl+V
...this.fitSize();
..}
.},
.onKeyup : function(event) {
..var k = event.keyCode;
..if (k < 65 || (k > 90 && k < 97) || (k > 122 && k < 127)) {
...this.fitSize();
..}
.},
.fitSize : function() {
..var str = this._obj.value + ' ';
..var strings = str.split(/\n/g);
..var bpl = Math.floor(this._obj.offsetWidth / this._fwidth); // bytes per line
..var lines = 0;
..for(var i=0; i < strings.length; i++) {
...if (this.getBytes(strings[i]) < bpl) {
....lines++;
...} else {
....lines += Math.ceil(this.getBytes(strings[i])/bpl);
...}
..}
..lines += 2;
..if (lines < this._minRows) {
...this._obj.rows = this._minRows;
..} else {
...this._obj.rows = lines;
..}
..this._obj.focus();
.}
}
[/code]
예제는 아래 링크를 클릭하세요(예고없이 사라질 수 있습니다. 제가 잘 날려먹어서...ㅠ_ㅠ)
http://funnyfog.net/textarea.html
아... 그리고... 말 안해도 IE, FF에 잘~ 호환되는 거는 아시죠? ^^
style="overflow:visible"; 해서 IE전용으로 textarea 크기를 자동으로 조절해왔는데 이건 FF 겸용인가보네요 + _+
언제 시간내어서 분석해봐야겠습니다~
예제를 실행해 봤는데
IE에서는 엔터쳐도 늘어나지 않네요?
FF에서는 잘 되지만 커서가 보이지 않습니다..