2010-08-04 2 views
5

일부 DOM 요소를 조작하는 Javascript가 있습니다. 문제는, 이해가 안 돼요 이 작동하는지는 결코 좋은 점이 아닙니다. 나는 객체 지향 자바 스크립트와 자바 스크립트 베스트 프랙티스에 대해 더 많은 것을 배우려고 노력 중이므로 조직이 좀 이상하게 보일 수있다.

기본적으로 CSContent 개체 내에서 DOM을 조작하는 두 가지 방법을 래핑합니다. 나는 해당 객체의 인스턴스 인 content$(document).ready에 만들고 일부 이벤트는 content의 함수에 바인딩합니다. 그러나, 나는이 기능들이 $(document).ready 종료 후에도 어떻게 호출 될 수 있는지에 대해 혼란 스럽다. 그렇다면 content이 범위를 벗어 났으며 그 기능을 사용할 수 없습니까?

function CSContent() { 
    var tweetTextArea = document.getElementById('cscontent-tweet'), 
     tweetTextElement = document.getElementById('edit-cscontent-cs-content-tweet'), 
     charCountElement = document.getElementById('cscontent-tweet-charactercount'); 

    this.toggleTweetTextarea = function() { 
     $(tweetTextArea).slideToggle(); 
    }; 

    this.updateTweetCharacterCount = function() { 
     var numOfCharsLeft = 140 - tweetTextElement.value.length; 
     if (numOfCharsLeft < 0) { 
      $(charCountElement).addClass('cscontent-negative-chars-left'); 
     } 
     else { 
      $(charCountElement).removeClass('cscontent-negative-chars-left'); 
     } 
     charCountElement.innerHTML = '' + numOfCharsLeft + ' characters left.'; 
    }; 
} 



$(document).ready(function() { 
    var content = new CSContent(); 
    //If the twitter box starts out unchecked, then hide the text area 
    if ($('#edit-cscontent-cs-content-twitter:checked').val() === undefined) { 
     $('#cscontent-tweet').hide(); 
    } 

    $('#edit-cscontent-cs-content-twitter').change(content.toggleTweetTextarea); 
    //Seems wasteful, but we bind to keyup and keypress to fix some weird miscounting behavior when deleting characters. 
    $('#edit-cscontent-cs-content-tweet').keypress(content.updateTweetCharacterCount); 
    $('#edit-cscontent-cs-content-tweet').keyup(content.updateTweetCharacterCount); 
    content.updateTweetCharacterCount(); 
}); 
+0

'콘텐츠'에 대한 액세스 권한이없는 위치의 예를 보여줄 수 있습니까? –

+0

@Pekka : id가 'edit-cscontent-cs-content-tweet' 인 요소에서 키를 누르거나 누를 때? –

+0

@Marcel ahh, 그가 의미하는 바입니다! 그것은 종결이다. 그러나 당신은 이미 당신의 대답에 그것을 설명하고 있습니다. +1 하겠지만 오늘은 투표에서 벗어났습니다. –

답변

2

난 당신이 궁금해지지 이유를

$('#edit-cscontent-cs-content-twitter').change(content.toggleTweetTextarea); 

작업과 같은 이벤트 핸들러?

그럼 이벤트 처리기로 content을 전달하지 않고 content.toggleTweetTextarea에 포함 된 기능을 전달합니다. 그리고이 참조는 존재하지 않습니다. content이 더 이상 존재하지 않습니다. 특별한 것은 없습니다. 방금 객체 (함수)를 다른 변수에 할당했습니다. 객체에 대한 하나 이상의 참조가 존재하는 한 객체는 가비지 수집되지 않습니다.

이제 이러한 기능이 왜 계속해서 액세스 할 수 있는지 물어볼 수 있습니다. tweetTextArea? 이것은 실제로 폐쇄입니다. 함수가 new CSContent()을 통해 생성되면이 함수의 활성화 컨텍스트가 내부 함수 CSContent.toggleTweetTextareaCSContent.updateTweetCharacterCount의 범위 체인에 추가됩니다. 따라서 더 이상 content에 대한 참조가 없더라도이 함수의 범위는 다른 함수의 범위 체인에 여전히 포함되어 있습니다.

ready()이 완료된 후에 content에 포함 된 개체에 더 이상 액세스 할 수 없으며 이는 실제로 범위를 벗어납니다.

5

이, m'lord, 폐쇄라고 : 어쨌든, 여기에 코드 로컬 변수 content$(document).ready 종료 후 메모리에 남아있게됩니다. 이것은 메모리 누수의 알려진 원인이기도합니다. 즉,이 함수를 DOM 요소의 이벤트 리스너에 바인딩 한 다음 JavaScript 가비지 수집기가 로컬 변수를 그대로 유지해야한다는 것을 알고 있습니다. 이벤트가 트리거되지 않는 한 직접 (함수 외부에서) 호출 할 수 없습니다. 이후에 실제로 함수를 호출하려는 경우 (예 : element.click()을 사용하여 클릭을 시뮬레이트하는 경우) 일부는 '수동으로'이 작업을 수행 할 수 있습니다.

+0

하지만 그 외에도, 그들은 위대합니다! :) 일부 추가 읽기 : https : //developer.mozilla.org/ko/JavaScript/Guide/Closures –

+0

클로저이기 때문에 CSContent 생성자에서 선언 된 지역 변수에 액세스 할 수 있으며 이벤트 리스너에 바인딩되어 있으므로 범위를 벗어나지 않습니까? 아니면 전체 closure가 어떻게 든 이벤트 리스너에 복사됩니까? – jergason

+0

@Jergason : 첫 번째. –

1

오늘 내 머리가 꺼졌지만이 상황에서 클로저를 사용해서는 안됩니까?

$('#edit-cscontent-cs-content-twitter').change( 
    function(){ 
     content.toggleTweetTextarea(); 
    } 
); 
+0

오늘 ....? :) 안녕하세요 에릭이 적 코멘트를 보셨나요? http://stackoverflow.com/questions/3274044/best-book-on-ajax/3306936#3306936 –

+0

흠, 좋은 생각, 종결. 하지만 OP는 이미 하나를 사용하고 있습니다 ... : P –

관련 문제