본문으로 바로가기

티스토리의 댓글 및 방명록을 디자인할때 겪을 수 있는 유의사항을 살펴봅니다.

댓글 및 방명록 스크립트

티스토리에서 댓글과 방명록 폼에 입력된 내용을 처리하는 스크립트는 아래와 같다.

function addComment(caller, entryId) {
    var oForm = findFormObject(caller);
    if (!oForm)
    return false;
    var request = new HTTPRequest("POST", oForm.action);
    request.onSuccess = function () {
        if(entryId == 0)
            window.location = blogURL + "/guestbook";
        else {
            document.getElementById("entry" + entryId + "Comment").innerHTML = this.getText("/response/commentBlock");
            if(document.getElementById("recentComments"))
                document.getElementById("recentComments").innerHTML = this.getText("/response/recentCommentBlock");
            if(document.getElementById("commentCount" + entryId))
                document.getElementById("commentCount" + entryId).innerHTML = this.getText("/response/commentView");
            if(document.getElementById("commentCountOnRecentEntries" + entryId))
                document.getElementById("commentCountOnRecentEntries" + entryId).innerHTML = "(" + this.getText("/response/commentCount") + ")";
        }
        if(typeof window.needCommentCaptcha !== "undefined"){
            captchaPlugin.init('complete');
        }
    }
    request.onError = function() {
        var description = this.getText("/response/description");
        if (description) { alert(description); }
    }
    var queryString = "key=tistory";
    var captchaInput = document.getElementById('inputCaptcha');
    if (oForm["name"])
        queryString += "&name=" + encodeURIComponent(oForm["name"].value);
    if (oForm["password"])
        queryString += "&password=" + encodeURIComponent(oForm["password"].value);
    if (oForm["homepage"])
        queryString += "&homepage=" + encodeURIComponent(oForm["homepage"].value);
    if (oForm["secret"] && oForm["secret"].checked)
        queryString += "&secret=1";
    if (oForm["comment"])
        queryString += "&comment=" + encodeURIComponent(oForm["comment"].value);
    if (captchaInput) {
        if (!captchaInput.value) {
            alert('그림문자가 입력되지 않았습니다.');
            return false;
        }
        queryString += "&captcha=" + encodeURIComponent(captchaInput.value);
    }
    request.send(queryString);
}
.....

폼에 입력된 내용을 전송하고 내용을 갱신시키기 위해 페이지를 새로고침시키는 일반적인 방식과는 달리 서버측과 통신하기 위해 AJAX를 사용하고 페이지 전체를 새로고침하지 않고 입력된 댓글들을 갱신시키고 있다.

AJAX 요청으로 응답받는 내용은 아래 그림과 같이 XML문서이고 이 곳에 정의된 <commentBlock> 은 스킨제작시 삽입되는 댓글영역 치환자 <s_rp> 가 정의하고 있는 영역이다.

댓글 및 방명록 이벤트연결

다시말하자면 댓글을 입력하고 전송버튼을 누르면 위의 스크립트들이 실행되고 AJAX로 응답받은 내용들로 댓글 및 방명록 영역이 교체된다. 일반적인 디자인을 염두에 두고 있다면 문제발생 소지가 적지만 스크립트를 이용해 이벤트를 연결하고 어떤 행동을 부여하는 등의 디자인을 구상하고 있다면 이는 원하는데로 작동하지 않아 당황스러울지도 모른다. 어떠한 추가적인 에러메세지도 노출되지 않을테니.....

사실 동적으로 생성된 구조에는 동적인 이벤트연결을 부여해야한다. jQuery를 사용하고 있다면 .on() 의 사용에 익숙할 것이다.

on( events [, selector] [, data], handler(eventObject))
  • events : 공백으로 구분된 하나 이상의 이벤트 형식으로 click, keydown, focus 등이 있다.
  • selector : 이벤트가 발생할 자식요소들을 찾을 선택자로 일반적인 경우에 이를 생략하여 선택된 요소에만 이벤트를 적용하지만 동적 이벤트연결엔 필요하다.
  • data : 이벤트가 발생할 때 핸들러에 전달할 데이터
  • handler(eventObject) : 이벤트가 발생하면 실행될 함수

일반적인 경우라면 전자와 같이 이벤트를 연결하겠지만 동적인 연결은 후자와 같다.

$('.focus-target').on('focus', function(){
    $(this).closest('.focus-wrap').addClass('focus');
});

$(document).on('focus', '.focus-target', function(){
    $(this).closest('.focus-wrap').addClass('focus');
});
스킨을 제작하면서 댓글폼을 전송시 동적으로 생성되는 구조를 모르고 있다가 당황스러웠다. 그런분들이 또 있을까 싶어 기록을 남겼다.