«js-core» — JavaScript framework

Octane, 29.09.2008

Не так давно я начал заниматься разработкой JavaScript framework’а «js-core» для применения в небольших проектах, в которых использование таких готовых универсальных решений, как «Prototype», «MooTools» или «jQuery» является не оправданным, в связи с достаточно большим объемом кода, большая часть которого не используется. Framework получился легкий (в несжатом виде версия 2.5.1 занимает около 15кб), но в тоже время достаточно функциональным.

При разработке «js-core» я ориентировался на опытных программистов, поэтому постарался исключить как можно больше лишних проверок. Например, «jQuery» может автоматически подставить вместо переданного параметра «class» значение «className», либо позволить ввести сразу «className», в связи с чем, каждый раз при использовании метода «attr» идет проверка и подстановка соответствующего значения. Так же в «js-core» активно применяется расширение стандартных прототипов встроеных объектов, поэтому не забывайте делать проверку «hasOwnProperty» в конструкиции «for(…in…)». Чтобы не делать такую проверку в framework’е предумотрены методы «object.each(fn, [arg])», «$.foreach(object, fn)», а также реализован метод «array.forEach(fn, context)» для старых браузеров, не поддерживающих его.

Для начала, рассмотрим пример, демонстрирующий упрощенный принцип работы JavaScript framework’а.

// Глобальный объект с набором частоиспользуемых
// функций, на основе которых построено большинство
// методов framework'а.
var core = {
  // Определение версии «Internet Explorer»
  ie: 0 /*@cc_on + @_jscript_version * 10 % 10 @*/,
  // …
  // и другие атрибуты и методы.
  // …
};

// Главная функция-конструктор.
function _$(arg) {
  // В атрибут «node» нового объекта запоминаем ссылку на DOM-узел
  this.node = typeof arg == 'string' ? document.getElementById(arg) : arg;
}

// Методы работы с DOM-узлами,
// доступные через прототип функции «_$».
_$.prototype = {
  parent: function() {
    // Возвращаем новую копию объекта «_$»
    // с сылкой на родительский узел
    // текущего элемента.
    return new _$(this.node.parentNode);
  },
  html: function(html) {
    // Если указан входной параметр «html»,
    // то заменяем «innerHTML» текущего узла
    // на переданный во входном параметре.
    if(typeof html != 'undefined') {
      this.node.innerHTML = html;
      return this;
    }
    // Иначе возвращаем «innerHTML» текущего узла.
    else return this.node.innerHTML;
  },
  // …
  // здесь же и все остальные методы.
  // …
};

// Функция, сокращающа запись создания
// новой копии объекта «_$».
function $(arg) {
	return new _$(arg);
}

// Дополнительные методы
$.n = function(tag) {
	// Возвращаем новую копию объекта «_$»
	// с сылкой на новый узел с именем тега,
	// указанным в параметре «tag».
	return new _$(document.createElement(tag));
};

Как видим, каждый раз во время выполнения функции «$» происходит конструирование нового объекта, который содержит всего одну ссылку «node» на DOM-узел, но через прототип функции-конструктора «_$» для него доступен набор методов, работающих с текущим узлом по этой ссылке.

В «js-core» реализовано кэширование для ссылок на DOM-узлы, полученных по идентификатору. То есть метод «document.getElementById» выполняется всего один раз для каждого запрашиваемого узла с идентификатором. Это позволяет повысить производительность в некоторых ситуациях.

В весрии 2.5.1 реализовано более 50-и методов, позволяющих JavaScript-программисту сразу приступить к написанию веб-приложения, не затрачивая время на подготовку основы для его работы. Рассмотрим некоторые из них.

Функция $(…)

Для получения новой копии объекта «_$» используется функция «$(…)», которая может принимать строку, содержащую идентификатор или ссылку на DOM-узел. Допустим, у нас есть узел <DIV> с идентификатором «test», тогда мы можем выполнить следующее:

var obj = $('test');
// или
var node = document.getElementById('test');
var obj = $(node);

Далее, чтобы сократить запись, запомним, что все функции, возвращающие один узел, возвращают его в обертке — новой копии объекта «_$» c атрибутом «node», содержащим ссылку на этот DOM-узел. А функции, возвращающие набор значений, отдают нумерованный массив или «DOMNodeList» ссылок на узлы. Некоторые функции (css, attr) могут возвращать как одиночные значения, так и массивы, в зависимости от количества входящих параметров.

Функция exist(…)

В отличие от «jQuery» в «js-core» не проверяется каждый раз наличие элемента, поэтому если, попытаться выполнить некоторые методы с несуществующим узлом, произойдет ошибка. Для случаев, когда элемент может отсутствовать, предусмотрен метод «exist», который может принимать в качестве входных параметров 2 функции: 1-я выполнится, если указанный элемент существует, 2-я выполнится, если такой элемент отсутствует.

$('test').exist(
  function() {
    // По ссылке «this» доступен текущий DOM-узел
    $(this)…
  },
  function() {
    alert('Элемент отсутствует');
  }
);

Так же функцию «exist» можно вызывать без параметров. В этом случае она вернет логическое значение «true» или false».

if($('test').exist()) {…}

Функции append(…) и prepend(…)

Для добавления нового дочернего узла или перемещения уже существующего в список дочерних элементов текущего узла используются функции «append(…)» и «prepend(…)». Первая функция добавляет элемент в конец списка дочерних элементов, вторая — в начало.

$('test').append('h1');
// или
var node = document.createElement('h1');
$('test').append(node);
// а так же
var node = document.getElementById('some-id');
$('test').append(node);

Функции html(…) и text(…)

Можно продолжить предыдущую цепочку и сразу же добавить в новый дочерний узел какой-нибудь текст или HTML-код:

$('test').append('h1').text('Hello World!');
// или
$('test').append('h1').html('<span>Hello</span> World!');

Для тех, кто хорошо знает «jQuery» сразу становится видно отличие «js-core» в работе с элементами в пределах одной цепочки вызовов. В «jQuery» метод «html» заменил бы «innerHTML» DOM-элемента с идентификатором «test», а в «js-core» работа ведется с последним используемым узлом, в данном примере это заголовок первого уровня <H1>.

Функции after(…) и before(…)

Создают новый узел после (перед) текущим или переносят существующий.

$('test').after('p').text('example');
$('test').after(document.getElementById('some-id'));
$('test').before(document.createElement('span')).html('example');

Функции appendTo(…) и prependTo(…)

Переносят текущий узел в конец (начало) списка дочерних элементов узла, переданного в качестве входного параметра (ссылка на DOM-элемент или строка, содержащая идентификатор узла).

$('test').appendTo('some-id');
$('test').prependTo(document.body);

Функции insertAfter(…) и inserBefore(…)

Ставят текущий узел после (перед) указанного узла (ссылка на DOM-элемент или строка, содержащая идентификатор узла).

$('test').insertAfter(document.getElementsByTagName('div')[0]);
$('test').inserBefore('some-id');

Функции next(…) и prev(…)

Возвращают первый соседний справа или слева элемент. В качестве входного параметра может приниматься строка и именем тега. Если входной параметр не указан, то возвращается первый соседний узел с «nodeType == 1».

$('test').next('blockquote');
$('test').prev();

Если соседний элемент отсутствует, функция вернет «undefined».

Функция child(…)

Возвращает массив дочерних элементов. Для фильтрации элементов в качестве первого параметра функции можно указать строку или массив строк, содержащих имена тегов. Если указан второй параметр «true», то поиск элементов производится по всем вложенным узлам.

$('test').child('input select textarea', true);
$('test').child(['div', 'p']);

Функция parent(…)

Возвращает родительский элемент текущего узла.

$('test').parent();

Функции remove(…) и empty(…)

Удаляют и очищают текущий узел соответственно.

$('test').remove();
$('test').empty();

Заметим, что функция «empty» возвращает текущую копию объекта «_$», поэтому мы можем продолжить работу с узлом.

$('test').empty().append('h1').text('example');

Полный перечень методов «js-core» можно посмотреть на главной странице проекта. Для каждой функции указаны все возможные комбинации параметров. В ближайшее время постараюсь сделать, что-то вроде «sheatsheet» по всем функциям.

Сейчас framework используется здесь и на сайте «ЗАО КЛФЗ».

Подписаться на обновления блога

Вам понравился наш блог, хотите следить за обновлениями? Подпишитесь на RSS рассылку или рассылку по электронной почте. Так же вы можете следить за нами в Twitter.

Категории: js-core | Комментировать

Комментарии

  1. 4tg4g5 / 15.01.2010 в 17:09

    О а я тут видел хороший сайт по этой статье Хакер сайт

Оставить комментарий

480×60
480×60