оптимизация ряда функций JavaScript - PullRequest
0 голосов
/ 21 июля 2011

Есть ли лучший, более краткий способ сделать это:

function getTweets(){
                $.getJSON("http://search.twitter.com/search.json?callback=?&q=superfad",

                function(data){
                    tweetsLoaded = true;
                    $.each(data.results, function(i,item){
                        var textPlain = item.text;
                        var textLinked = linkify(textPlain);
                        var textHashed = hashify(textLinked);
                        var textListed = listify(textHashed);

                        function linkify(tweet){
                            return tweet.replace(/(http:\/\/[^\s]*)/g, "<a class='twtr-link' target=\"_blank\" href=\"$1\">$1</a>");
                        }

                        function hashify(tweet){
                            return tweet.replace(/(^|\s+)#(\w+)/gi, function(m, before, hash) {
                                return before + '<a target="_blank" class="twtr-hashtag" href="http://twitter.com/search?q=%23' + hash + '">#' + hash + '</a>';
                              });
                        }

                        function listify(tweet) {
                            return tweet.replace(/\B[@@]([a-zA-Z0-9_]{1,20})/g, function(m, username) {
                                return '<a target="_blank" class="twtr-atreply" href="http://twitter.com/intent/user?screen_name=' + username + '">@' + username + '</a>';
                            });
                        }

                        $("#twitter_results").append('<li class="twitter"><img class="twitter_img" src="' + item.profile_image_url + '"/>'+ textListed + '</li>');
                    });
                });
            } //end getTweets

Ответы [ 4 ]

2 голосов
/ 21 июля 2011
// define this globally
function stuffify(match, group1, group2) {
  switch (group1 || group2) {
    case 'http':
      return '<a class="twtr-link" target="_blank" href="' + match + '">' + match + '</a>';
    case '#':
      return '<a class="twtr-hashtag" target="_blank" href="http://twitter.com/search?q=' + encodeURIComponent(match) + '">#' + match + '</a>'

    case '@':
      return '<a class="twtr-atreply" target="_blank" href="http://twitter.com/intent/user?screen_name=' +  encodeURIComponent(match) + '">@' + match + '</a>';
    default: 
      return match;
  }
}

function(data){
  tweetsLoaded = true;
  var interestingParts = /(http):\/\/\S+|(#|@)[^\s.,!?;^()\[\]<>{}]+/g;

  $.each(data.results, function(i,item) {
    var newText = item.text.replace(interestingParts, stuffify);

    $("#twitter_results").append('<li class="twitter"><img class="twitter_img" src="' + item.profile_image_url + '"/>'+ newText + '</li>');
  });
}
2 голосов
/ 21 июля 2011

Я бы перестроил код таким образом, чтобы функции манипулирования текстом (linkify, hashify, listify) не находились внутри функции each и даже не находились внутри самой getTweets. Если оно в getTweets, то каждый раз, когда вы вызываете эту функцию, они должны быть переопределены. Хуже того, внутри each, где они были, эти функции переопределяются для каждого элемента в возвращенном наборе твитов.

Кроме того, нет необходимости хранить возврат каждой из этих функций в своем собственном var, так как вы используете их только один раз после и не выполняете никаких проверок перед их использованием. Просто вложите вызовы функций.

Наконец, поскольку вы вызываете метод добавления снова и снова к одному и тому же элементу (внутри each), я предварительно запрашивал этот элемент вместо того, чтобы запрашивать его каждый раз при выполнении функции each

Эти изменения, а также некоторые вещи, которые я делаю для своих собственных настроек производительности, представлены в примере кода, вставленном ниже.

Есть и другие вещи, которые я бы сделал, однако я не буду их здесь показывать - вы можете увидеть это в моем опубликованном ответе на Проблемы с преобразованием скрипта jQuery в плагин - вопрос о создании jQuery плагин, который делает то же самое, что и ваш код). Вы должны хранить отформатированные твиты в массиве, а не добавлять их по мере их поступления. Построив этот массив, вы должны объединить его в одну строку и вызвать addnd с этой строкой. Создание этого плагина jQuery также было бы хорошо для вас, поскольку не требовало бы изменения кода для изменения целевого элемента DOM. Также было бы полезно изучить String.prototype.link.

(демо: http://jsfiddle.net/JAAulde/fQ3Lp/2/)

var getTweets = ( function()
{
    /* Privatized text manipulation functions */
    var linkify = function( tweet )
    {
        return tweet.replace( /(http:\/\/[^\s]*)/g, "<a class='twtr-link' target=\"_blank\" href=\"$1\">$1</a>" );
    };

    var hashify = function( tweet )
    {
        return tweet.replace( /(^|\s+)#(\w+)/gi, function(m, before, hash)
        {
            return before + '<a target="_blank" class="twtr-hashtag" href="http://twitter.com/search?q=%23' + hash + '">#' + hash + '</a>';
        } );
    };

    var listify = function( tweet )
    {
        return tweet.replace(/\B[@@]([a-zA-Z0-9_]{1,20})/g, function(m, username)
        {
            return '<a target="_blank" class="twtr-atreply" href="http://twitter.com/intent/user?screen_name=' + username + '">@' + username + '</a>';
        } );
    };

    var $twitterResultTarget = $( "#twitter_results" );

    /* The actual function which is stored in `getTweets`   */
    return function()
    {
        $.getJSON( "http://search.twitter.com/search.json?callback=?&q=superfad", function( data )
        {        
            tweetsLoaded = true;
            $.each( data.results, function( i, item )
            {
                $twitterResultTarget
                    .append( [
                        '<li class="twitter"><img class="twitter_img" src="',
                        item.profile_image_url,
                        '"/>',
                        listify( hashify( linkify( item.text ) ) ),
                        '</li>'
                    ].join( '' ) );
            } );
        } );
    }
}() );
0 голосов
/ 21 июля 2011

Я бы, вероятно, написал в стиле плагина jQuery и использовал бы split вместо replace с HTML в обратных вызовах:

(function($){

  function getTweets(q) {

    var

      $set = this,

      prefixes = {
        'h': 'h',
        '#': 'http://twitter.com/search?q=%23',
        '@': 'http://twitter.com/intent/user?screen_name='
      },

      classes = {
        'h': 'twtr-link',
        '#': 'twtr-hashtag',
        '@': 'twtr-atreply'
      };

    $.getJSON(
      "http://search.twitter.com/search.json?callback=?&q=" + encodeURIComponent(q),
      function(data){
        $.each(data.results, function(i, item){

          var
            $li = $('<li class="twitter"></li>')
              .append('<img class="twitter_img" src="' + item.profile_image_url + '"/> ');

          $.each(
            item.text.split(
              /(\s+)|(https?:\/\/[^\s]*)|(#\w+)|(@[a-zA-Z0-9_]{1,20})/g
            ),
            function(i, chunk) {
              if (/^(https?:\/\/|@|#)/.test(chunk)) {
                $('<a target="_blank"></a>')
                  .addClass(classes[chunk[0]])
                  .attr('href', prefixes[chunk[0]] + chunk.substr(1))
                  .text(chunk)
                  .appendTo($li);
              } else if (chunk) {
                $li.append(document.createTextNode(chunk));
              }
            }
          );

          $li.appendTo($set);

        });
      }
    );

  }

  $.fn.getTweets = getTweets;

})(jQuery);

Затем назвал бы это так:

$('#twitter_results').getTweets('superfad');

Мои $ 0,02

0 голосов
/ 21 июля 2011

Старайтесь избегать использования анонимных функций, это всегда менее запутанно, если все они имеют имена и объявлены вне каких-либо других функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...