2010-07-13 4 views
2

이 코드의 전반부는 완벽하게 작동합니다. 그러나 두 번째. 클릭하면 항목이 제거되는 위치에서 실행되지 않습니다. .click() 함수의 코드 만이 먼저 평가되는 시간 (onReady)의 적절한 요소에 결합 때문에 일어나고jquery. 발언하지 않는 앞에 붙인 아이템에 대한 클릭().

$(document).ready(function() 
{ 
    $('#contact').click(function() 
    { 

     $('#contact_box').remove(); 

     $('.menu_item_content').prepend('<div class="menu_box" id="contact_box">Contact INFO goes in this box.</div>'); 

    }); 

    $('#about').click(function() 
    { 

     $('#about_box').remove(); 

     $('.menu_item_content').prepend('<div class="menu_box" id="about_box">About info goes in this box.</div>'); 

    }); 

    $('#twitter').click(function() 
    { 

     $('#twitter_box').remove(); 

     $('.menu_item_content').prepend('<div class="menu_box" id="twitter_box">Twitter</div>'); 

    }); 


    // 
    //remove single items 
    // 
    //nothing below this fires for some reason? 

    $('#contact_box').click(function() 
    { 
     $('#contact_box').remove(); 
    }); 

    $('#about_box').click(function() 
    { 
     $('#about_box').remove(); 
    }); 

    $('#twitter_box').click(function() 
    { 
     $('#twitter_box').remove(); 
    }); 
}); 

<style> 

.menu_item 
{ 
    display:inline; 
    font-family:Tahoma; 
    font-size:20px; 
} 
.menu_spacer 
{ 
    display:inline; 
    font-family:Tahoma; 
    font-size:45px; 
} 

</style> 

<div class="menu"> 
    <div class="menu_items"> 
     <div class="menu_item" id="contact">CONTACT</div> 
     <div class="menu_spacer">/</div> 
     <div class="menu_item" id="about">ABOUT</div> 
     <div class="menu_spacer">/</div> 
     <div class="menu_item" id="twitter">TWITTER</div> 
    </div> 

    <div class="menu_item_content"> 
    </div> 
</div> 
+0

당신이 HTML을 게시 할 수주십시오? – airmanx86

+0

확실히 그것을 – ian

+1

에 추가했습니다. 약간의 작은 틱이지만, 대신'$ (this) .remove()'를 사용합니다. jQuery는 두 번째 요소에 대해 DOM을 검색 할 필요가 없다. – mpen

답변

1

당신의 첫 번째 부분에서 이러한 요소, 당신은 이벤트 아래 사람들을 바인딩 .live() 또는 .delegate()을 사용할 필요가 '추가'.

예 : 당신이 즉시 항목을 만들고 그들에게 직접 바인드 이벤트를 놓칠 경우

$('#contact_box').live('click', function() 
{ 
    $('#contact_box').remove(); 
}); 

, 그들이 당신의 이벤트 핸들러에 대해 알고하지 않습니다. 이는 이벤트 핸들러를 묶는 코드의 실행이 이 발생하기 전에이 발생하기 때문에 완전히 이해가됩니다.

.live().delegate() 종류의 "대안"이 동작입니다. 요소 자체에 이벤트 처리기를 바인딩하는 대신 이벤트 처리기를 부모 노드에 바인딩합니다. Javascript 이벤트는 각 노드를 "버블 업 (bubble up)"시키므로 (차단되지 않은 경우) .live()click eventsdocument.body을 "감시"합니다. 이벤트를 잡으면 target id을 확인하고 일치하는 경우 코드를 실행합니다.

이제 오바마 같은 소년이 말하기를 오버 헤드가 너무 큽니다. 그러면 옳을 것입니다. .live()은 본문 인 문서 트리의 맨 위에 표시됩니다. 즉, .live()을 통해 연결된 모든 이벤트는 버블을 발생시켜 노드를 던져야합니다. 따라서 jQuery의 영리한 사람들은 잠깐 기다리십시오. 을 알고있는 경우을 작성하면 새로운 요소를위한 루트 노드가 있다는 것을 알 수 있습니다. 바로 그곳에서 버블 링 이벤트를 볼 수있을만큼 충분해야하며 .delegate()이 태어났습니다. 더 이상 오버 헤드를 관찰하지 않고 .delegate() 부모 노드를 말할 수 있습니다!

참조 : .live(), .delegate()

+0

나는 이것을 시험해 보았지만 행운은 없었다. $ ("#의 contact_box") 위임 ("#의 contact_box", "클릭", 기능() { \t \t $은 ('#의 contact_box이')) (제거;. \t \t}).; – ian

+0

@ian : 작동하지 않습니다.'.delegate()'를'# contact_box'의 ** 부모 ** 노드에 바인드해야합니다. 텍스트를 업데이트하고 다시 읽었습니다. 덕분에 – jAndy

+0

. 그것은이와 함께 가고있어 :. $를 (". menu_item_content") 위임 ("#의 contact_box", "클릭",() 함수를 \t {. \t \t $ ('#의 contact_box') (제거) \t}) ; – ian

2

이유이다. 앞에 추가 된 항목이 아직 DOM에 없기 때문에 이러한 요소는 click() 이벤트가 바인딩되지 않습니다. .prepend() 함수 호출 후에 .click() 바인딩 호출을 넣을 수 있지만 이후에 DOM에 어떤 다른 변경 사항을 적용할지 알 수 있습니다. .live()를 사용하면 CSS 선택 패턴 '#contact_box'과 일치하는 모든 요소가 요소가 DOM에 추가 될 때마다 onClick() 이벤트에 바인딩 된 함수를 가져옵니다.

휴. 희망이었습니다. 이제 이러한 변경을 고려 : 이후

// The below line was changed to a shorthand notation which means the same as $(document).ready(function(){}); 
$(function() 
{ 
    $('#contact').click(function() 
    { 

     $('#contact_box').remove(); 

     $('.menu_item_content').prepend('<div class="menu_box" id="contact_box">Contact INFO goes in this box.</div>'); 

    }); 

    $('#about').click(function() 
    { 

     $('#about_box').remove(); 

     $('.menu_item_content').prepend('<div class="menu_box" id="about_box">About info goes in this box.</div>'); 

    }); 

    $('#twitter').click(function() 
    { 

     $('#twitter_box').remove(); 

     $('.menu_item_content').prepend('<div class="menu_box" id="twitter_box">Twitter</div>'); 

    }); 


    // 
    //remove single items 
    // 
    //nothing below this fires for some reason? 

    // Changes here. 
    $('#contact_box').live('click',function() 
    { 
     $('#contact_box').remove(); 
    }); 

    // And changes here.  
    $('#about_box').live('click',function() 
    { 
     $('#about_box').remove(); 
    }); 

    // And changes here. 
    $('#twitter_box').live('click',function() 
    { 
     $('#twitter_box').remove(); 
    }); 
}); 

<style> 

.menu_item 
{ 
    display:inline; 
    font-family:Tahoma; 
    font-size:20px; 
} 
.menu_spacer 
{ 
    display:inline; 
    font-family:Tahoma; 
    font-size:45px; 
} 

</style> 

<div class="menu"> 
    <div class="menu_items"> 
     <div class="menu_item" id="contact">CONTACT</div> 
     <div class="menu_spacer">/</div> 
     <div class="menu_item" id="about">ABOUT</div> 
     <div class="menu_spacer">/</div> 
     <div class="menu_item" id="twitter">TWITTER</div> 
    </div> 

    <div class="menu_item_content"> 
    </div> 
</div> 
+0

코드의 첫 번째 절반이 실행되는 것을 방지합니다 ... 메뉴 항목. – ian

+0

나는 당신의 말을 본다. 그러나 요소가 생성되기 전까지는 요소가 존재하지 않지만 코드의 전반부가 어떻게 작동 할까? – ian

+0

어느 쪽 이요? 수정 한 방법을 보여줄 수 있습니까? – mikegreenberg

관련 문제