Динамическая инициализация новых виджетов твиттера

В сентябре 2012 года Twitter анонсировал новые захватывающие «инструменты реального времени для разработчиков веб-сайтов» ©, то есть новые виджеты. Причем старые виджеты кажется должны были перестать поддерживаться как раз в мае 2013, но видимо отключат их таки в июне. Так что самое время подумать о переезде на новую версию APi и новые виджеты.

Настройки виджета Embedded Timeline можно найти на сайте для разработчиков. Интересно то, что о динамической подгрузке виджета практически нигде не сказано. А порой это бывает нужно, например, когда часть контента страницы или даже вся страница подгружается аяксом. Как же это сделать? Есть ответ!

Стандартный javascript-код подключения виджета выглядит примерно следующим образом:

!function (d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0], p = /^http:/.test(d.location) ? 'http' : 'https';
    if (!d.getElementById(id)) {
        js = d.createElement(s);
        js.id = id;
        js.src = p + "://platform.twitter.com/widgets.js";
        fjs.parentNode.insertBefore(js, fjs);
    }
}(document, "script", "twitter-wjs");

Если мы при аяксовой подгрузке страницы попробуем запускать этот код, то он сработает только в первый раз, а потом перестанет работать. Причина этого в том, что здесь динамически создается элемент script и подключается скрипт widget.js. При этом, если скрипт уже подключался, то повторно он выполняться не будет, а нам это нужно при динамической загрузке.

Исправляется это просто — при повторной загрузке виджета аяксом мы удаляем старый тег подключения скрипта и подключаем widget.js по-новой. Так код инициализации выполнится снова. При этом уже инициализированные виджеты затронуты быть не должны. А вот и версия кода для динамической загрузки (ее можно выполнять, например, после успешного выполнения ajax запроса на загрузку контента):

    var initTwitter = function () {
        !function (d, s, id) {
            var tws = d.getElementById(id);
            if (tws) {
                tws.remove();
            }
            var js, fjs = d.getElementsByTagName(s)[0], p = /^http:/.test(d.location) ? 'http' : 'https';
            js = d.createElement(s);
            js.id = id;
            js.src = p + "://platform.twitter.com/widgets.js";
            fjs.parentNode.insertBefore(js, fjs);
        }(document, "script", "twitter-wjs");
    }
    initTwitter();

Желаю приятного использования, надеюсь работать будет гладко.

Дополнение: для Ruby on Rails 4 и небезызвестной библиотеки turbolinks, которая реализует аяксовую загрузку страниц, есть несколько решений, которые могут быть полезны для изучения в дополнение к приведенному в данной статье решению.