2016-10-24 2 views
3

Ich erstelle DOM-Elemente und erstelle dann ein Array von JQuery-Objekten mit diesen DOM-Elementen. Nach dem Sortieren der JQuery-Objekte und dem erneuten Anhängen dieser Objekte ist der Klickereignis-Listener verschwunden. Gibt es eine Möglichkeit, den Klick-Listener zu erhalten?Wie behalte ich Ereignislistener nach dem Sortieren?

for(var i=0; i<5; i++){ 
    var div = $('<div>',{ 
    id: i+"div", 
    class: 'list-item '+i, 
    html: "Item #"+i 
    }); 
    div.data('i',i); 
    $('.news-layout-1').append(div); 
    div.on('click',function(){ 
    alert($(this).data('i')); 
    }); 
} 

$('.button').on('click',function(){ 
    var items = []; 
    $('.news-layout-1').find('.list-item').each(function(index, item){ 
    items.push(item); 
    }); 

    items = items.sort(function(a,b){ 
    var textA = $(a).html().toUpperCase(); 
    var textB = $(b).html().toUpperCase(); 
    return (textA > textB) ? -1 : (textA < textB) ? 1 : 0; 
    }); 

    $('.news-layout-1').html(''); 

    for(var i=0; i<items.length; i++){ 
    $('.news-layout-1').append(items[i]); 
    } 
}); 

http://jsfiddle.net/bhav4co6/5/

+1

Verwenden Sie Stack Snippets (die '<>' Symbolleistenschaltfläche), um runnable Demos ** hier ** vor Ort zu platzieren. Ihre Frage sollte in sich geschlossen sein, einschließlich Ihres HTML, das gerade verlinkt ist. Snippets vermeiden dies. –

+0

Sie können versuchen, die Listener an den '$ ('body') zu delegieren. ('Click', 'button,' ...)' siehe: http://api.jquery.com/delegate/ – ochi

+0

statt $ ('. button'). on ('click', function() {benutze $ (document) .on ('click', '. button', function() { – Araz

Antwort

4

Sie das Löschen des HTML, effektiv die Elemente aus dem DOM zu entfernen, und sie sind nur im Speicher gehalten, wo sie alle damit verbundenen Daten und Ereignisse verlieren.

jQuery verwendet intern auch .empty(), wenn Sie .html("") tun, um absolut sicherzustellen, dass die Elemente, die Daten und die Ereignislistener entfernt werden.

Wenn Sie nur entfernen Sie die Zeile

$('.news-layout-1').html(''); 

du bist in Ordnung, da die Elemente nur bewegt werden, und hält die Ereignis-Listener

for (var i = 0; i < 5; i++) { 
 
    var div = $('<div>', { 
 
     id: i + "div", 
 
     class: 'list-item ' + i, 
 
     html: "Item #" + i 
 
    }); 
 
    div.data('i', i); 
 
    $('.news-layout-1').append(div); 
 
    div.on('click', function() { 
 
     alert($(this).data('i')); 
 
    }); 
 
} 
 

 
$('.button').on('click', function() { 
 
    var items = []; 
 
    $('.news-layout-1').find('.list-item').each(function(index, item) { 
 
     items.push(item); 
 
    }); 
 

 
    items = items.sort(function(a, b) { 
 
     var textA = $(a).html().toUpperCase(); 
 
     var textB = $(b).html().toUpperCase(); 
 
     return (textA > textB) ? -1 : (textA < textB) ? 1 : 0; 
 
    }); 
 

 
    for (var i = 0; i < items.length; i++) { 
 
     $('.news-layout-1').append(items[i]); 
 
    } 
 
});
.list-item { cursor: pointer }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="news-layout-1"> 
 
</div> 
 
<a href="#" class="button btn"> 
 
    Sort 
 
</a>

Als sidenote, es gibt keine Notwendigkeit für ein Array oder eine Schleife anzuhängen, können Sie einfach tun

$('.button').on('click', function() { 
    $('.news-layout-1 .list-item').sort(function(a, b) { 
     var textA = $(a).html().toUpperCase(); 
     var textB = $(b).html().toUpperCase(); 
     return (textA > textB) ? -1 : (textA < textB) ? 1 : 0; 
    }).appendTo('.news-layout-1'); 
}); 
+0

Oder sortiere die Daten zuerst, dann erstelle sie "tomayto"/"tomahto"). –

+0

sehr schön. ... – Mahi

+0

Wenn append Elemente bewegt, ist es einer dieser JQuery-Vorbehalte, die mir jedes Mal in den Hintern beißen. Danke! – trinathon

2

Sie können delegieren die Ereignisse, anstatt sie in der for-Schleife anzuhängen.

Wenn die Klickaktion ausgelöst wird, wird das Ereignis an das übergeordnete Element (in diesem Fall body-Element) weitergeleitet, dem der Click-Handler zugeordnet ist. Sie können dann e.target verwenden, um die genaue li, wo das Klicken passiert ist.

$('body').on('click', '.list-item', function(e) { 
     alert($(e.target).data('i')); 
    }); 

    for (var i = 0; i < 5; i++) { 
     var div = $('<div>', { 
      id: i + "div", 
      class: 'list-item ' + i, 
      html: "Item #" + i 
     }); 
     div.data('i', i); 
     $('.news-layout-1').append(div); 

     // move the click event out of the for loop 
    } 
Verwandte Themen