Фильтрация списка друзей, извлеченных с помощью API Graph Facebook (скорее вопрос JavaScript / Jquery, чем вопрос API Facebook) - PullRequest
3 голосов
/ 04 октября 2010

Привет, гуру JavaScript и Jquery. Я получаю, а затем отображаю список друзей в 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>

Теперь, на моем интегрированном веб-сайте в Facebook, я бы в конечном итоге хотел, чтобы мои пользователи выбирали своих друзей и отправляли им подарки / фейсбук - били их ... или что угодно. Поэтому я пытаюсь реализовать простой фильтр Jquery , используя этот фрагмент кода, который манипулирует 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> 

Теперь этот фрагмент кода работает с обычным неупорядоченным списком, но когда список отображается с помощью JavaScript, это не так. У меня есть догадка, что он должен что-то делать с методом innerHTML. Кроме того, я попытался поместить код фильтра JQuery внутри, а также прямо перед тегом. Ни один, казалось, не работал.

Если кто-нибудь знает, как решить эту проблему, пожалуйста, помогите мне. Кроме того, есть ли лучший способ отобразить список друзей, из которых пользователи могут выбирать?

1 Ответ

1 голос
/ 04 октября 2010

Проблема здесь:

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

Поскольку вы визуализируете это:

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

Оболочка привязки отсутствует, текст находится непосредственно в <li>, поэтому изменитепервые две строки, которые будут соответствующим образом выглядеть в этих элементах, например:

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

Вы также можете сделать весь этот раздел немного быстрее, выполнив код Contains() только один раз, заключив большой договордля длинных списков, таких как:

$(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();
   }
});

И для решения этих потенциальных (вероятно, действительно) проблем с innerHTML создайте свою структуру с использованием DOM, например:

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);   
 });
} 

Делая это таким образом, вы создаете свой контент все сразу, <ul> - это фрагмент документа, а затем одна вставка ... это также лучше для производительности по двум причинам.1) вы в настоящее время добавляете недопустимый HTML с помощью вызовов .innerHTML ... у вас никогда не должно быть незамкнутого элемента в любой точке, и 2) вы делаете 2 манипуляции с DOM (1 для заголовка), 1 для списка) после намного более быстрого создания фрагмента документа, не повторяется .innerHTML изменения.

...