Насколько хорошо вы знаете Prototype

или разговор о преимуществе этих дополнительных 100 KB на вашей странице

Давайте будем честными - Я пытался отвечать на похожие вопросы снова и снова. Prototype.js - широко используемая js библиотека с не очень удачной online-документацией. Я лично считаю справочник API превосходным ресурсом (хоть и не без погрешностей), но он далёк от того, чтобы быть понятным новичкам. Я работал с prototyp-ом почти уже год и проводил уйму времени на IRC канале. Сложно объяснить насколько абсурдные вопросы порой задают люди. Мне кажется, что в большинстве случаев используется prototype на 15%, не больше. Я не удивлюсь, если увижу Ajax.Request использованную с document.getElementById в одной строке.

Дополнение: Насколько хорошо вы знаете Prototype :: часть II (перевод будет позже)

Здесь я собрал наиболее частые примеры, НЕ использующие всех возможностей prototyp-а. Я надеюсь эо будет базовой точкой отсчета для разработок в ваших следующих проектах. Ну... начнём:

1
Неправильно:
document.getElementById('foo')
Правильно:
$('foo')

К удивлению некоторые люди фактически не знают об этом (подключают ~100KB файл лишь для использования вещей типа Ajax.Request)

2
Неправильно:
var woot = document.getElementById('bar').value
var woot = $('bar').value
Правильно:
var woot = $F('bar')

Удобный способ чтения значений контролов формы

3
Неправильно:
$('footer').style.height = '100px';
$('footer').style.background = '#ffc';
Правильно:
$('footer').setStyle({
	height: '100px',
	background: '#ffc'
})

Мечтаете о том что IE будет соответствовать W3C стандартам? Не надейтесь! (но прототайп позволит вам забыть о проблемах кросс-браузерности)

4
Неправильно:
$('coolestWidgetEver').innerHTML = 'какой-то полезный контент'
Правильно:
$('coolestWidgetEver').update('какой-то полезный контент')

Это один из тех простых довольно часто забываемых случаев. Да, я знаю, что это почти тоже самое, но я хочу видеть как вы сделаете тоже самое в первом варианте (ну разве chaining не крут?)

$('coolestWidgetEver').update('some nifty content').addClassName('highlight').next().hide()

5
Неправильно:
new Ajax.Request('ninja.php?weapon1=foo&weapon2=bar')
Правильно:
new Ajax.Request('ninja.php', {
	parameters: {
		weapon1: 'foo',
		weapon2: 'bar'
	}
})

Более чистое и лучше структурированное определение параметров

6
Неправильно:
new Ajax.Request('blah.php', {
	method: 'POST',
	asynchronous: true,
	contentType: 'application/x-www-form-urlencoded',
	encoding: 'UTF-8',
})
Правильно:
new Ajax.Request('blah.php')

Все это опции в Ajax.Request выставляются по умолчанию! "method: 'POST'" присутствует на каждой второй выложенной для проверки странице, которую я вижу
(Всё ещё не веришь в наследование в JS? Не получается реализовать это? Просто используй преимущества Prototyp-а)

7
Неправильно:
Event.observe('myContainer', 'click', doSomeMagic)
Правильно:
$('myContainer').observe('click', doSomeMagic)

Этот случай спорный, но второй вариант более Обьектно Ориентированный (ну... или того рода) и легче для усвоения (Так что решайте за себя сами)

8
Неправильно:
$$('div.hidden').each(function(el){
	el.show();
})
Правильно:
$$('div.hidden').invoke('show')

Вот типичный случай "злоупотребления each". Существует invoke для подобных целей! Досадно, что немногие люди знают о ней.

9
Неправильно:
$$('div.collapsed').each(function(el){
	el.observe('click', expand);
})
Правильно:
$$('div.collapsed').invoke('observe', 'click', expand)

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

10
Неправильно:
$$('input.date').invoke('observe', 'focus', onFocus);
$$('input.date').invoke('observe', 'blur', onBlur);
Правильно:
$$('input.date')
	.invoke('observe', 'focus', onFocus)
		.invoke('observe', 'blur', onBlur)

Некоторые люди склонны забывать о "нирване chaining-а". Не нравится, как оно выглядит? Думай о сохранении некоторого времени, не вызывая $$ дважды!

11
Неправильно:
$('productTable').innerHTML = 
	$('productTable').innerHTML + 
	'<tr><td>' + productId + ' '
	+ productName + '</td></tr><tr><td>' 
	+ productId + ' ' + productPrice + 
	'</td></tr>'
Правильно: 1
var rowTemplate = new Template('<tr><td>#{id} #{name}</td></tr><tr><td>#{id} #{price}</td></tr>');
$('productTable').insert(
	rowTemplate.evaluate({
		id: productId,
		name: productName,
		price: productPrice
	}))
)

Нет, я не шучу. Это было выложено на #prototype и там было кое-что неправильно (хмм... Интересно что же...)
Templates - отличное решения для этих отвратительных HTML строк. Меня тошнит от этих огромных конкатенаций строк. evaluate решает проблемму организации структурированного подхода.

На этом всё. Оставайся на волне!

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

1. Читайте изменения в Prototype 1.6 rc_0. Вместо такой записи теперь можно писать
$('productTable').insert(
	'<tr><td>#{id} #{name}</td></tr><tr><td>#{id} #{price}</td></tr>'.interpolate({
		id: productId,
		name: productName,
		price: productPrice
	}))
)