태그 보관물: javascript

textarea 자동 높이 맞추기 Javascript 예제

아래는 textarea에 작성된 내용의 길이에 맞춰 style의 height를 계산하는 예제이다.

function textareaAutoHeight(el) {
    setTimeout(() => {
        el.style.height = 'auto';

        let scrollHeight = el.scrollHeight;
        let outlineHeight = el.offsetHeight - el.clientHeight;

        el.style.height = (scrollHeight + outlineHeight) + 'px';
    }, 0);
}

위 코드는 textarea의 스타일이 box-sizing: border-box;일 때 완벽하게 동작한다.

위 코드에서 중요한 부분은 바깥쪽을 포함한 높이 offsetHeight와 안쪽의 높이 clientHeight의 차를 textarea 높이에 더해준다는 것이다.

만약 이 계산을 포함하지 않으면 textarea에 테두리(border)가 있을 경우에 테두리의 위(border-top-width) + 아래(border-bottom-width) 만큼 손해를 보게 된다.

주의할 점은 border-width 값을 직접 더해주면 안된다. border-width의 단위는 픽셀(px)이 아닐 수도 있다. 그렇기 때문에 element 객체의 offsetHeight – clientHeight 로 테두리의 높이를 구해야 한다.

자바스크립트 클래스 구현시 고민할 부분 – 1

* 이 글은 자바스크립트에서 클래스를 흉내내는 방법에 대해 설명하지 않습니다.

아래는 prototype을 이용하여 클래스를 만들고 객체를 생성하여 사용한 코드 입니다.

function A() {
    this.n = 10;
}
A.prototype.run = function () {
    alert(this.n);
};

var a = new A();

// CASE1: undefined
setTimeout(a.run, 1);
// CASE2: 10
setTimeout(function () {a.run();}, 1);
// CASE3: 11
a.n = 11;
setTimeout(function () {a.run();}, 1);

위의 코드에서 보는 바와 같이 CASE1은 쓸 수 없습니다.
alert(this.n)의 this는 a를 가르켜는 것이 아니기 때문입니다.
그리고 CASE3 처럼 n의 값을 임의로 바꿀 수 있습니다.

CASE1, CASE2가 모두 동작하도록 아래와 같이 구현하는 방법도 있습니다.

function A() {
    var n = 10;
    this.run = function () {
        alert(n);
    };
}

var a = new A();

// CASE1: 10
setTimeout(a.run, 1);
// CASE2: 10
setTimeout(function () {a.run();}, 1);
// CASE3: 10
a.n = 11;
setTimeout(function () {a.run();}, 1);

이번에는 CASE1, CASE2 모두 원하는대로 동작하고 CASE3도 n의 값이 변경되지 않았습니다.
그런데 이렇게 prototype을 사용하지 않으면 생성되는 객체 각각마다 run()을 가지게 되어 prototype을 사용한 방법보다 메모리를 더 차지하게 됩니다.