2017-09-26 22 views
0
(function() { 
    var tasks = /* Some awesome content stored here */ 
    var render = ''; 
    for(var x = 0; x < questions.length; x+= 1) { 
    render += '<p onclick="changeText(' + x +')">question[i]</p>' 
} 
    function changeText(x) { 
     // some fancy stuff happens here with a certain x 
    } 
})(); 

IIFE를 사용하려고 할 때 아래 오류가 발생하지만 IIFE가 제거되면 정상적으로 작동하는 이유는 무엇입니까? 내 다른 사람과 같은 범위에 changeText() 아닌가요?즉시 호출되는 함수식이 내 onclick을 방해합니까?

어떻게 수정합니까?

Uncaught ReferenceError: changeText is not defined 
    at HTMLElement.onclick 
+0

상위 속성에서 호출하는 것이 좋습니다. HTML에'p'가 어디 있는지 알려주십시오.? –

답변

0

함수 선언 현재 범위에(즉 함수 인 값) 변수를 생성한다.

onclick 속성은 자체 범위와 전역 범위에만 액세스 할 수 있습니다.

IIFE 내부 기능이 범위를 벗어납니다.


신속하고 더러운 해결책은 changeText을 글로벌하게 만드는 것입니다.


깨끗한 솔루션은 OTOH :

이것은 당신이 온 클릭 속성을 사용하지 않도록해야합니다 또 하나의 이유입니다.

문자열을 함께 스매싱하여 HTML을 생성하지 마십시오. DOM을 직접 생성하고 addEventListener을 사용하십시오.

for(var x = 0; x < questions.length; x+= 1) { 
    var p = document.createElement("p"); 
    p.appendChild(document.createTextNode("question[i]"); 
    p.setAttribute("data-x", x); 
    p.addEventListener("click", function() { changeText(this.dataset.x); }); 
    something.appendChild(p); 
} 

NB : 단락은 상호 작용을 제어 할 수 있도록 설계되어 있지 않습니다. 클릭 이벤트를 추가하면 포인팅 장치를 사용하지 않거나 사용할 수없는 사람들이 클릭 이벤트에 액세스 할 수 없게됩니다. 대신 클릭하도록 설계된 것을 사용해야합니다 (예 : <button>).

+0

_ "깨끗한 해결책"_ : 동의하지 않습니다. 루프에서 클릭 핸들러를 생성하면 안됩니다. – Cerbrus

+0

@Cerbrus 루프에서 클릭 핸들러를 다시 사용하는 것이 잘못된 이유를 설명해 주시겠습니까? 이것은 미학의 문제입니까, 아니면 어쨌든 이런 식으로 일하는 당신의 코드에 영향을 줍니까? – user19380947

+0

@ user19380947 : 50 개의 질문이있는 경우 해당 기능을 50 복제본으로 만듭니다. 그냥 루프 외부에서 _once_ 함수를 만들고, 그것을 'addEventListener'에 전달하십시오. – Cerbrus