2012년 12월 4일 화요일

모바일 브라우저에서 글 내용에 따라 자동으로 늘어나는 textarea 만들기


제가 앞에 작성한 “모바일 브라우저에서 글 내용에 따라 자동으로 늘어나는 textarea 만들기” 는 글을 작성한 만큼 textarea의 크기가 늘어납니다. 하지만 작성한 글을 지워서 내용이 줄어들었을 때 textarea의 크기는 줄어들지 않고 계속 커진 상태로 남아 있습니다.
이점을 수정해서 글 내용이 많아질 때는 textarea의 크기가 커지고 글 내용이 줄어들었을 때는 textarea의 크기도 작아지도록 만들어봤습니다. 이것을 구현하기 위해 어떻게 해야할지 생각이 잘 안떠올랐는데 검색을 해보니 구현하신 분이 있어서 그 분의 아이디어를 그대로 가져와서 만들었습니다. 그 분의 글은 http://james.padolsey.com/javascript/jquery-plugin-autoresize/ 입니다.
textarea의 크기를 늘리는 기능은, 글 내용이 길어지면 textarea의 scrollHeight 값이 커지기 때문에 이 크기에 따라 textarea의 높이(height)를 조절해 주는 방식으로 만들수 있었지만 textarea의 크기를 줄이는 기능은 이 방법을 사용할 수 없었습니다. textarea의 높이가 글 내용 높이보다 작아서 스크롤바가 생기는 상황이라면 글 내용의 많고 적음에 따라 scrollHeight 값이 변하지만, 이미 textarea의 높이를 글 내용이 많아졌을 때에 맞게 늘렸었기 때문에 이 상태에서 글자를 지워서 글 내용 높이를 줄여도 scrollHeight의 값은 변하지 않게 되어 textarea 높이를 글 내용 높이에 맞게 줄여줄 기준값으로 사용할 수 없게 되기 때문입니다.
이 것을 해결하기 위해 제가 참고한 http://james.padolsey.com/javascript/jquery-plugin-autoresize/ 에서는 textarea의 clone을 만드는 방법을 사용하고 있었습니다. clone으로 만든 textarea는 사용자에게는 안보이도록 positin:absolute; top:0; left:-9999; 처리를 한 다음 사용자에게 보이는 진짜 textarea에 글씨가 입력될 때마다 clone textarea에도 그대로 글이 입력되게 합니다. 그리고 진짜 textarea의 높이 조절을 clone textarea의 scrollHeight 값을 가지고 조절하는 방식입니다.
(그런데 제가 참고한 사이트에서 clone을 사용한다는 아이디어만 참고하고 나머지 코드는 참고를 안해서 제가 만든 버전은 오류가 좀 있을 수도 있을 것 같습니다.)
제가 말씀으로 설명드려서 좀 복잡한데 소스코드를 보시면 이해가 되실 것 같습니다.
  1. // textarea의 id가 textarea인 경우를 가정해서 #textarea 사용
  2. (function() {
  3.  
  4. var textarea = $('#textarea'),
  5. originHeight = textarea.height(),
  6. originClientHeight = textarea[0].clientHeight,
  7. clone = textarea.clone(),
  8. extraHeight = parseInt(textarea.css('fontSize')),
  9. timer, content, cloneScrollHeight;
  10.  
  11. clone
  12. .removeAttr('id')
  13. .removeAttr('name')
  14. .css({
  15. position: 'absolute',
  16. top: 0,
  17. left: -9999,
  18. overflow: 'hidden'
  19. }).appendTo('body');
  20.  
  21. textarea.focus(function() {
  22.  
  23. timer = setInterval(function() {
  24. content = textarea.val();
  25. clone.val(content);
  26. cloneScrollHeight = clone[0].scrollHeight;
  27.  
  28. if (originClientHeight < cloneScrollHeight) {
  29. textarea.css('height', cloneScrollHeight + extraHeight);
  30. } else if (originClientHeight === cloneScrollHeight) {
  31. textarea.css('height', originHeight);
  32. }
  33. }, 100);
  34.  
  35. });
  36.  
  37. textarea.blur(function() {
  38. clearInterval(timer);
  39. });
  40.  
  41. })();
데모를 http://codefactory.kr/lab/autogrowshrink_textarea.html 에 올려놓았습니다. 필요하신 분은 한번 확인해보세요..^^