Насколько хорошо вы знаете prototype (часть II)

1) Легкое определение нажатия клавиш

Как мы определяем, какая клавиша была нажата? Prototype предоставляет множество синонимов для событиый нажатия клавиш, так что мы не должны запоминать, что return -это "13", а escape - "27". Почти все основные клавиши определены: KEY_RETURN, KEY_ESC, KEY_TAB, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN. Смотри полный список в API документации

$('myInput').observe('keyup', function(e){
  if (e.keyCode == Event.KEY_TAB)
    doSomethingCoolWhenTabIsPressed();
})

2) Предотвращать события скорее всего не понадобится

Иногда я вижу, что параметр capturing (захват события) устанавливается явно в методе Event#observe в false. Хорошо то, что по умолчанию этот параметр установлен в false и вам редко когда понадобится задавать его значение явно. Следующие 2 строки полностью идентичны, так что мы можем пропустить последний аргумент:

Event.observe('productInfo', 'click', displayProductInfo, false); // 'false' может быть опущено
Event.observe('productInfo', 'click', displayProductInfo);

или более короткий способ:

$('productInfo').observe('click', displayProductInfo, false); // 'false' может быть опущено
$('productInfo').observe('click', displayProductInfo);

3) Вставляй грамотно

Один из других случаев значения по умолчанию (“it’s-there-by-default”) - аргумент position метода Element#insert. Как ни странно это нигде не упоминается в документации - я на днях случайно это обнаружил в исходниках. insert принимает одно из четырёх значений position: top, bottom, before, и after. Если мы пропустим этот аргумент, то по умолчанию он будет bottom (и к счастью оно необходимо в большинстве общих случаев). Следующие строки ведут себя одинаково:

new Insertion.Bottom('blogEntry',
  new Template('<div><h2>#{name}</h2><p>#{content}</p></div>')
    .evaluate({
      name: blogEntry.name,
      content: blogEntry.content
    }));
 
// Insertion класс устарел - рекомендуется использоать метод Element#insert:
 
$('blogEntry').insert(new Template('<div><h2>#{name}</h2><p>#{content}</p></div>')
    .evaluate({
      name: blogEntry.name,
      content: blogEntry.content
    }), 'bottom' ); // "bottom" может быть опущено
 
$('blogEntry').insert(new Template('<div><h2>#{name}</h2><p>#{content}</p></div>')
    .evaluate({
      name: blogEntry.name,
      content: blogEntry.content
    }));

4) Безбашенные формы

Простая отправка форм реально проста, но что если мы захотим предотвратить сериализацию определённых элементов перед отправкой по ajax? Давайте расмотрим несколько способов решить эту проблему:

Простая отправка формы с помощью .request

$('register').observe('submit', function(e){
  Event.stop(e);
  $(this).request();
})

С помощью .getInputs можно легко отфильровать элементы атрибутам "type" и "name". В этом примере мы сериализуем элементы с именем ‘email’ и отправляем результат по URI, лежащему в атрибуте формы “action”.

$('register').observe('submit', function(e){
  Event.stop(e);
  new Ajax.Request($(this).readAttribute('action'), {
    parameters: Form.serializeElements($(this).getInputs('', 'email'))
  })
})

Применение .getInputs может помочь в большинстве случаев, но что если мы хотим исключить элементы, имеющие атрибут “multiple”? Можно поступить так:

$('register').observe('submit', function(e){
  Event.stop(e);
  new Ajax.Request(this.readAttribute('action'), {
    parameters: Form.serializeElements($(this).getElements()
      .reject(function(el){return el.hasAttribute('multiple')})
    );
  })
})

Етить, что за хрень тут происходит?!

Когда возникает событие посыла, мы отменяем дефолтное действие отсылки Event.stop(e), получаем все элементы формы this.getElements(), перебираем их, обрасывая элемты с атрибутом “multiple” .reject(function(el){return el.hasAttribute('multiple')}). Потом сериализуем Form.serializeElements() отфильтрованную коллекцию и отправляем через ajax new Ajax.Request()

Это всё очень хорошо, но есть один ньюанс почему стоит учить CSS3 селекторы нужно (фильтрация через отбрасываение(reject-based) и по селектору (selector-based) именют идентичный результат):

$('register').observe('submit', function(e){
  Event.stop(e);
  new Ajax.Request($(this).readAttribute('action'), {
    parameters: Form.serializeElements($$('#register input:not([multiple])'))
  })
})

Enjoy prototyping!

Created by kangax
translated by vectoroc
Вопросы? Предложения? Найди меня на #prototype [kangax] или пошли мне email [ kangax@gmail.com ]