2012-03-13 15 views
0

addEventListener() 기능과 관련된 문제가 있습니다. 배열의 변수를 기반으로 메뉴를 만들려고합니다. 왜 이런 식으로 설정했는지 설명하지 않을 것입니다.이벤트 리스너가 루프에서 작동하지 않습니다.

다음
var _Dirt = document.getElementById("dirt"); 

_Dirt.addEventListener('mouseover', function() { menuOver(true, this, _dirtY); }, false); 
_Dirt.addEventListener('mouseout', function() { menuOver(false, this, _dirtY); }, true); 

var _DirtDiv = _Dirt.getElementsByTagName('div')[0]; 

for (nLink in Men["dirt"]) { 

    var _lnk = document.createElement('p'); 
    _lnk.className = 'menu'; 
    _lnk.innerHTML = Men["dirt"][nLink][0]; 
    _lnk.addEventListener('click', menuLoop(Men["dirt"][nLink][1]), false); 

    _DirtDiv.appendChild(_lnk); 
    _DirtDiv.innerHTML+= '<br />'; 

} 

경우에 대비합니다 (menuLoop 기능 당신이 내가 제대로 변수를 잘 결합 아니에요 우려 : : 이제

function menuLoop (n) { 

    return function() { 

     menuLink (n); 

    } 

} 

을, 성가신 부분 여기

코드입니다 이 이벤트 리스너가 _Dirt 요소에서 정상적으로 작동하지만, _lnk 요소에서는 전혀 작동하지 않는다는 것입니다. 심지어 _lnk.onclick = function() { //something }으로 변경하더라도 작동하지 않습니다 (사실 onclick 특성은 작동하지 않습니다). 에스 어떻게 DOM에서).

나는 이벤트 리스너를 요소에 붙이는 또 다른 루프 기능을 가지고 있으며 완벽하게 작동합니다 ... 코드는 매우 유사합니다. 좌절감에 추가되는 것은이 코드가 완벽하게 작동하는 데 사용된다는 것입니다. 실제로이 코드를 전혀 변경하지 않은 것을 기억합니다. 코드에서이 함수를 분리하여 스크립트에 중단 점이 있는지 확인하려고했지만 문제가 남아 있습니다.

내 코드의 다른 부분이 필요한 경우 알려주십시오.

+0

당신이 이벤트 핸들러에 menuLoop (Men [ "dirt"] [nLink] [1]) 대신 하드 코딩 된'function() {alert ('boom!');}' 해고? – Yaniro

+1

* "onclick' 속성은 표시되지 않습니다."* 속성을 추가하지 않았기 때문입니다. 당신은 DOM과 그 이벤트 시스템으로 직접 작업하고 있습니다. –

+0

@Yaniro : 예, 시도했습니다. 아무 소용이 없습니다. 나는 아닙니다 : 저는 onclick 이벤트를 추가 할 때 언급했습니다. 이벤트 리스너를 추가하면 DOM에 표시되지 않는다는 것을 알고 있습니다. –

답변

3

귀하의 문제가이 기본적으로 문자열로 직렬화, _DirtDiv의 자식 노드를 취

_DirtDiv.innerHTML += '<br />'; 

입니다 (이것은 당신의 데이터 구조가 모두 올바른 가정하에) (HTML) '<br />'을 연결하고 innerHTML에 다시 할당합니다. 브라우저는 문자열을 구문 분석하고 해당 DOM 노드를 만듭니다.

이전에 생성 한 DOM 노드의 ID가 손실되고 이벤트 처리기도 손실됩니다. 이 프로세스는 이전에 생성 한 것보다 다른 DOM 노드를 파괴하고 만듭니다. 당신이 br 노드를 추가하려면

뿐만 아니라, DOM 조작을 사용

_DirtDiv.appendChild(document.createElement('br')); 

예를 노드가 다르다는 것을 보여줍니다 크롬 콘솔에서 :

> var node = document.createElement('div'); 
    undefined 
> node.id = 'foo'; 
    "foo" 
> document.body.appendChild(node); 
    <div id=​"foo">​</div>​ 
> node === document.getElementById('foo'); 
    true          // nodes are the same 
> document.body.innerHTML += '<br />'; 
    "... long HTML string ..." 
> node === document.getElementById('foo'); 
    false          // nodes are different 
+0

+1 뛰어난 잡기.줄 바꿈이 필요한 경우 innerHTML 수정보다는 DOM 삽입을 통해 줄 바꿈을 추가해야합니다. – jfriend00

+1

그건 코드 형식 문제였습니다. 문제의 '
'은 SO 페이지에서 HTML로 해석되고있었습니다. –

+0

@ amnotiam : 감사합니다. 답변을 업데이트했습니다. –

관련 문제