2010-10-03 2 views
3

Bonjour les gourous JavaScript et Jquery, je reçois, puis afficher la liste d'amis d'un utilisateur facebook en utilisant ce qui suit Code:Filtrer la liste des amis extraits par Facebook graphique api (plus d'une question JavaScript/Jquery que question API Facebook)

<script> 
function getFriends(){ 
var theword = '/me/friends'; 
FB.api(theword, function(response) { 
    var divInfo = document.getElementById("divInfo"); 
    var friends = response.data; 
    divInfo.innerHTML += '<h1 id="header">Friends/h1><ul id="list">'; 
    for (var i = 0; i < friends.length; i++) { 
    divInfo.innerHTML += '<li>'+friends[i].name +'</li>'; 
    } 
    divInfo.innerHTML += '</ul></div>'; 
}); 
} 

</script> 

<a href="#" onclick="getFriends(); return false;">graph friends</a> 
<div id = divInfo></div> 

maintenant, dans mon Facebook site intégré, je finirais que mes utilisateurs de choisir leurs amis et leur envoyer des cadeaux/facebook-punch them..or tout. Par conséquent, je suis en train de mettre en œuvre un Jquery filter simple en utilisant ce morceau de code qui manipule avec le DOM

 <script> 

(function ($) { 
    // custom css expression for a case-insensitive contains() 
    jQuery.expr[':'].Contains = function(a,i,m){ 
     return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0; 
    }; 


    function listFilter(header, list) { // header is any element, list is an unordered list 
    // create and add the filter form to the header 
    var form = $("<form>").attr({"class":"filterform","action":"#"}), 
     input = $("<input>").attr({"class":"filterinput","type":"text"}); 
    $(form).append(input).appendTo(header); 

    $(input) 
     .change(function() { 
     var filter = $(this).val(); 
     if(filter) { 
      // this finds all links in a list that contain the input, 
      // and hide the ones not containing the input while showing the ones that do 
      $(list).find("a:not(:Contains(" + filter + "))").parent().slideUp(); 
      $(list).find("a:Contains(" + filter + ")").parent().slideDown(); 
     } else { 
      $(list).find("li").slideDown(); 
     } 
     return false; 
     }) 
    .keyup(function() { 
     // fire the above change event after every letter 
     $(this).change(); 
    }); 
    } 


    //ondomready 
    $(function() { 
    listFilter($("#header"), $("#list")); 
    }); 
}(jQuery)); 

    </script> 

Maintenant, ce morceau de code fonctionne sur la liste non ordonnée normale, mais quand la liste est rendu par JavaScript, il ne ne pas. J'ai l'impression qu'il doit faire quelque chose avec la méthode innerHTML. Aussi, j'ai essayé de mettre le code du filtre JQuery à l'intérieur et aussi juste avant le tag. Ni l'un ni l'autre ne semblait fonctionner.

Si quelqu'un sait comment résoudre ce problème, aidez-moi s'il vous plaît. De même, existe-t-il un meilleur moyen d'afficher la liste d'amis parmi laquelle les utilisateurs peuvent choisir?

Répondre

1

Le problème est ici:

$(list).find("a:not(:Contains(" + filter + "))").parent().slideUp(); 
$(list).find("a:Contains(" + filter + ")").parent().slideDown(); 

Puisque vous rendant ceci:

divInfo.innerHTML += '<li>'+friends[i].name +'</li>'; 

Il n'y a pas wrapper d'ancrage, le texte est directement dans le <li> donc modifier les deux premières lignes à regarder dans ces éléments en conséquence, comme ceci:

$(list).find("li:not(:Contains(" + filter + "))").slideUp(); 
$(list).find("li:Contains(" + filter + ")").slideDown(); 

Vous pouvez aussi faire toute cette partie un peu plus vite en exécutant votre code Contains() une seule fois, ce qui rend un grand pacte pour les listes longues, comme ceci:

$(input).bind("change keyup", function() { 
    var filter = $(this).val(); 
    if(filter) { 
    var matches = $(list).find("li:Contains(" + filter + ")").slideDown(); 
    $(list).find("li").not(matches).slideUp(); 
    } else { 
    $(list).find("li").slideDown(); 
    } 
}); 

Et pour résoudre les potentiels (probablement vraiment) les questions de innerHTML, construire votre structure à l'aide du DOM, comme ceci:

function getFriends(){ 
    var theword = '/me/friends'; 
    FB.api(theword, function(response) { 
    var divInfo = $("#divInfo"), friends = response.data; 
    divInfo.append('<h1 id="header">Friends/h1>'); 
    var list = $('<ul id="list" />'); 
    for (var i = 0; i < friends.length; i++) { 
     $('<li />', { text: friends[i].name }).appendTo(list); 
    } 
    divInfo.append(list); 
}); 
} 

en ce faisant de cette façon que vous construisez votre contenu tout à la fois, le <ul> étant un fragment de document, puis une insertion. ... c'est aussi mieux pour la performance pour 2 raisons. 1) Vous êtes actuellement en ajoutant un HTML invalide avec les appels .innerHTML ... vous ne devriez jamais avoir un élément non fermé à tout moment, et 2) vous faites 2 manipulations DOM (1 pour l'en-tête, 1 pour la liste) après le beaucoup création de fragments de document plus rapide, pas répété .innerHTML changements.