Вход | Регистрация
Xevian.CMS: База знаний
Шаблоны
Терминология
Руководство разработчика
Вопросы
- Системные константы
- Системные переменные
- Локализации
- Типы статических блоков
Типы контейнеров статических блоков
- Типы параметров
- Плэйсхолдеры
- Шаблоны
CSS классы
- Паттерны


ГлавнаяВопросыВеб-инженеруЦентрализация небольших JS-разработок ...

Централизация небольших JS-разработок

Содержание

  1. Структура
  2. Паттерны
  3. Примеры

Существуют определенные преимущества централизованной, однотипной организации небольших JS-разработок и заплаток в одном файле:

  • Легкость добавления
  • Легкость изменения и удаления
  • Бо́льшая предсказуемость поведения
  • Возможность простого переноса между проектами

В настоящей статье предлагается к использованию простой, легковесный метод организации на основе библиотеки libhack.js.

Структура

Библиотека libhack.js предоставляет функцию execFunctionsByTable(), принимающую в качестве аргумента объект следующего формата:

{
    'где запускать':[
        function(){
            что выполнять
        }
    ],

    'где запускать2':[
        function(){
            что выполнять2
        }
    ]
}

Например:

{
    '.*':[
        function(){
            allPageAction();
            allPageAction2();
        }
    ],

    '[/]sitename.ru[/][\w]*$':[
        function(){
            mainPageAction();
            mainPageAction2();
        },

        function(){
            mainPageAction3();
        }
    ],

    '[/]blogs[/]':[
        function(){
            blogsAction();
            blogsAction2();
        }
    ]
}

где строки '.*', '[/]sitename.ru[/][\w]*$' и '[/]blogs[/]'содержат регулярные выражения, при совпадении которых с текущим адресом страницы (а именно с document.URL) срабатывают соответствующие блоки кода. В приведенном примере настроены три блока кода: один срабатывает на всех страницах (и содержит allPageAction();...), другой — только на главной (содержит mainPageAction();...), третий — только на страницах модуля blogs (содержит blogsAction();...).

Внутри каждого блока функции выполняются в том порядке, в котором они приведены в файле. Функции выполняются сразу после загрузки HTML-страницы до полной загрузки дополнительных материалов (CSS, картинок, шрифтов и т.п.). Каждое регулярное выражение проверяется на соответствие текущему адресу, и соответствующий блок кода выполняется или не выполняется.

Пары 'выражение':[блок кода] и отдельные функции разделяются запятыми. После последнего блока кода/функции запятая не ставится.

 

Содержимое каждой анонимной функции function(){} выполняется в отдельном try..catch и ошибки в нем (кроме синтаксических) не влияют на выполнение других таких функций. Обнаруженные ошибки вместе с номером строки выводятся в консоль функцией debugLog() внутри библиотеки если установлена глобальная переменная DEBUG. Функция debugLog() также доступна пользователю.

 

Для использования библиотеки libhack.js необходимо включить ее в шаблоны страниц после основных скриптов Ксевиана:


Библиотека libhack.js зависит от библиотеки prototype.js и должна загружаться после нее.

Паттерны

С целью упрощения понимания мелких скриптов другими разработчиками предлагается следующая организация кода с примерами использования некоторых функций libhack.js:

/* 
 * Локальный JS, версия 0.1
 * Зависимости: prototype.js, libhack.js
 */

(function(){

    /* Список действий */
    var toDo = {

        // На всех страницах
        '.*':[

            // настроить вывод ошибок
            function(){
                DEBUG = 1;
                noConsoleNoErrors();
                interceptErrors('behaviour.js');
            },

            // определить возможности браузера
            function(){
                detectFeatures();
            },

            // привязать действие к кнопкам Назад
            function(){
                var elements = $$('.backButton');
                elements.each(function(e,i){
                    e.onclick = function(){ history.back(); return false; };
                });
            }
        ],
        
        // На страницах нескольких модулей
        '[/](products|articles|blogs)[/]':[

            // заменить по таблице
            function(){
                var replacementTable = [
                    {target:'.listing > h1',
                    search:'замени_меня',
                    replacement:'замени_мной'},

                    {target:'.message',
                    search:'удали_меня|и_меня',
                    replacement:''},

                    {target:'.more',
                    search:'^0 Ответов',
                    replacement:'Ответить'},
                
                    {target:'.more',
                    search:'(([^1]|^)1) Ответов',
                    replacement:'$1 Ответ'},
                
                    {target:'.more',
                    search:'(([^1]|^)[234]) Ответов',
                    replacement:'$1 Ответа'}
                ];
                replaceDomByTable(replacementTable);
            }
        ],

        // На страницах одного модуля
        '[/]forum[/]':[

            // настроить JS-табы без AJAX с поддержкой хэш-ссылок
            function(){
                handleStaticTabs();
            }
        ],

        // В личном кабинете
        '[/]profile[/]':[

            // добавить возможность автоматической AJAX-навигации в личный кабинет
            // например /profile/?add=products или /profile/?list=products
            function(){
                var navTable = {
                    add:'/index.php?app=front&xml=content&structure=items&show=form&mod=',
                    list:'index.php?app=front&xml=content&structure=items&show=listing&mod='
                }
                postNavigation(navTable);
            }
        ],

        // На конечных страницах нескольких модулей
        '[/](news|companies)[/].+[/]':[

            // для пар типа 
Телефон:
+7 123123

// удалить все dt, после которых стоят пустые dd function(){ var elements = $$('dd:empty'); elements.each(function(e,i){ e.previous('dt').remove(); e.remove(); }); }, // сделать что-то function(){ doSomething(); deleteSomething(); }, // (1) настроить переключение видимости по щелчку function(){ var elements = $$('a.toggle'); elements.each(function(e,i){ e.observe('click', (function(E){ // (2) собственно полезная функция return function() { E.next('.togglable').toggle(); } })(e)); }); } ] } /* Локальные функции */ // сделать что-то function doSomething(){ console.log('something done'); } // удалить что-то function deleteSomething(){ var element = $$('article ul')[0]; element.remove(); console.log('something removed'); } /* Начало работы */ execFunctionsByTable(toDo); })();

  1. Использование отдельных функций для отдельных задач ограничивает пространство поиска ошибок и позволяет использовать одни и те же названия переменных в разных функциях.
  2. Заключение всей конструкции в (function(){})(); отделяет ее пространство имен переменных и функций от глобального, минимизируя возможные проблемы в этой области (т.н. модульный паттерн). Объявленные внутри этой конструкции функции недоступны вне скрипта.
  3. Унификация кода для распространенных задач помогает быстрее читать структуру функций и избегать ошибок.
  4. Для часто используемых переменных предлагаются простые имена, отражающие их содержимое: element (elem если уже занято; e, E локально), elements (elems), container, form, box, url и т.п.
  5. Предлагаемый метод привязки событий [(1) в листинге] позволяет ставить в соответствие одному элементу произвольное количество событий одного типа и делать это для любого количества элементов. При этом создается столько копий возвращаемой функции [(2) в листинге], сколько найдено элементов на странице, и для каждого переменные внутри функции задаются в момент привязки независимо. В результате копии функций элементов не зависят друг от друга и от действий других скриптов.

Любые часто используемые функции предлагается оформлять в достаточно общей форме и добавлять в библиотеку libhack.js.

Примеры

uoowuo

Комментарии

Вы не авторизованы. При отправке сообщения, в качестве автора будет указан "Гость". Вход | Регистрация

Руководство разработчика