2013-05-24 11 views
9

Mam <div>; zawiera on <span>. Po kliknięciu przycisku <div> usuwa on zakres i zastępuje go wartością <div> zawierającą <input> i <button>. Wszystko jest dobrze i dobrze.Dołączony element div nie jest częścią DOM

Po kliknięciu przycisk <button> ma usunąć jego rodzica <div> (dołączony) i zastąpić go ponownie <span>, ale coś jest nie tak. Wygląda na to, że rodzic <div> nie jest częścią DOM!

W każdym razie, oto krótki przykład:

<div id="myPage"> 
    <div id="clickMe" class="selectedField editMe"> 
     <span>Click Me</span> 
    </div> 
</div> 

Niektóre HTML, nic szczególnego. Chociaż, ponieważ DOM będzie się ciągle zmieniał, użyłem .on do delegowania zdarzeń. Oto JavaScript:

$(function(){ 
    $('#myPage').on('click', '.selectedField', function() { 
     if($(this).hasClass('editMe')){ 
      var $this = $(this).toggleClass('editMe editing'), 
       $input = $('<input/>', { 
        placeholder: 'type something...' 
       }), 
       $cancel = $('<button></button>', { 
        class: 'cancel', 
        type: 'button', 
        html: 'x' 
       }) 

      $this.children('span').replaceWith($('<div></div>').append($input, $cancel)); 
     } 
    }); 

    $('#myPage').on('click', '.selectedField .cancel', function() { 
     var $this = $(this).closest('.selectedField').toggleClass('editMe editing'); 

     console.log($this.children('div')[0]); 

     $this.children('div').replaceWith('<span>Click Me</span>'); 
    }); 
}); 

DEMO: http://jsfiddle.net/Z8abW/

Wygląda to dość proste, prawda? Kliknięcie tego pola zastępuje <span> za pomocą <div>, a następnie kliknięcie (nowo dodane) <button> powoduje powrót do numeru <span>.

Ale to nie działa. Pierwsze wydarzenie działa. Mogę kliknąć, aby dodać <input> i <button>, ale kliknięcie przycisku <button> nie działa.

Nie wiem jak to wytłumaczyć, ale wygląda na to, że <div> Chcę usunąć nie jest częścią DOM! Po kliknięciu przycisku <button> nic się nie dzieje na stronie. Dodałem console.log, aby upewnić się, że zdarzenie zostało uruchomione. Rzeczywiście, było, ale coś było dziwne.

Używam Chrome 27, a jego konsola ma schludną funkcję. Jeśli posiadasz elementy DOM console.log, możesz umieścić na nich wskaźnik myszy i podświetli je na stronie. Zrobiłem console.log($this[0]) i podświetliłem ten element, jakbym się spodziewał. Ale kiedy zrobiłem console.log($this.children('div')[0]);, element był nie podświetlony na stronie! Dlaczego nie? Sprawia, że ​​myślę, że element, z jakiegoś powodu, nie znajduje się w DOM. Loguje się do konsoli na <div>, ale wydaje się, że nie jest to rzeczywisty DOM.

Z tego powodu linia $this.children('div').replaceWith nic nie robi!

Co się dzieje! Dlaczego mogę zamienić <span> na <div>, ale nie na odwrót?

+1

Musisz zatrzymaćPropagację na swoim drugim programie obsługi, ponieważ powoduje on pętlę: Zdarzenie jest przekazywane do twojej pierwszej obsługi i podczas przełączania klasy editMe, uruchamia się przez to i odtwarza wejście/przycisk –

+0

Lub po prostu 'zwraca fałsz; 'w każdym zdarzeniu przycisku, łącza, etykiety itp. –

+0

@RobinLeboeuf: Oh wow, masz rację! Nawet o tym nie myślałem. Dzięki! :-D –

Odpowiedz

9

zagadnienia propagacji.Zmiana

$('#myPage').on('click', '.selectedField .cancel', function() { 

do

$('#myPage').on('click', '.selectedField .cancel', function (e) { 
     e.stopPropagation(); 

jsFiddle example

Kliknięcie na pęcherzyki znoszą się i wyzwala zdarzenie kliknij na rodzica. Zabij to ogniem.

+3

+1 za Zabij go ogniem. (i odpowiedź oczywiście) – tymeJV

+0

Ale w zdarzeniu nadrzędnym sprawdzam dla klasy 'editMe' ...., która jest dodawana z powrotem w zdarzeniu' .cancel'. Dzięki! Nie zdawałem sobie sprawy, że to wydarzenie zaczęło wracać do rodzica, co jeszcze raz dodałoby "". –

+1

Lubię zwracać fałsz na koniec więcej w tej sytuacji (ach). +1 –

6

Aktualizacja $('#myPage').on('click', '.selectedField .cancel', function() do

$('#myPage .selectedField ').on('click', '.cancel', function() 

sprawdzić ten fiddle

+2

Huh? To działa? ... To działa! Dlaczego to działa? –

+0

Domyślam się, że słuchacze na żywo nie są aktualizowani, gdy widzi, że '.selectedField' się nie zmieniło. – karthikr

Powiązane problemy