Туторіал - Prototype: Як Prototype Розширює DOM

Як Prototype Розширює DOM

Більшою частиною framework-у Prototype є його DOM розширення. Prototype надає безліч зручних методів для елементів, які вертаються функцією $(): наприклад, можна написати $('comments').addClassName('active').show() та отримати елемент з ID 'comments', потім додати до нього назву класу і показати цей елемент (якщо раніше він був прихований). Елемент 'comments' не містить цих методів у власному JavaScript-і; як це можливо? Даний документ демонструє деякі розумні забавки в Prototype.

Метод Element.extend()

Більшість DOM методів інкапсулюються об'єктом Element.Methods, а потім копіюються вище об'єкта Element (для зручності). Всі вони отримують елемент для роботи в якості першого параметра:

Element.hide('comments');
var div_height = Element.getHeight(my_div);
Element.addClassName('contactform', 'pending');

Ці приклади є стислими та читабельними, проте можна досягнути і кращого. Якщо

елемент, з яким працюємо, передати через Element.extend() і скопіювати всі ці методи безпосередньо до елементу. Наприклад, для створення та маніпулювання елементом:

var my_div = document.createElement('div');

Element.extend(my_div);
my_div.addClassName('pending').hide();

// insert it in the document
document.body.appendChild(my_div);

Виклики нашого методу стають все коротшими і зрозумілішими! Як згадувалося раніше, Element.extend() копіює всі методи з Element.Methods до нашого елементу, який автоматично стає першим аргументом для всіх цих функцій. Метод extend() не є достатньо розумним, щоб спробувати діяти двічі на тому ж елементі. Що ще краще, **функція долар $() розширює кожен елемент, який попадає в неї** за цим механізмом.

Крім того, Element.extend() також застосовує Form.Methods до FORM елементів та Form.Element.Methods до INPUT, TEXTAREA і SELECT елементів:

var contact_data = $('contactform').serialize();
var search_terms = $('search_input').getValue();

Слід мати на увазі, що не тільки функція долар автоматично розширює елементи! Element.extend() також викликаться в document.getElementsByClassName, Form.getElements, для елементів, які вертаються функцією $$() (елементи ототожнювані з CSS дешифратором) та в інших місцях — в кінці кінців, можливо взагалі буде необхідно рідко викликати Element.extend() явно.

Додавання Власних Методів з Element.addMethods()

Якщо є деякі власні DOM методи, які хотілось би додати до решти з Prototype — без проблем! Для реалізації цього Prototype також забезпечує свій механізм. Припустимо, що є купа функцій, прихованих в об'єкті, тоді слід просто передати об'єкт до Element.addMethods():

var MyUtils = {
truncate: function(element, length){
element = $(element);
return element.update(element.innerHTML.truncate(length));
},
updateAndMark: function(element, html){
return $(element).update(html).addClassName('updated');
}
}

Element.addMethods(MyUtils);

// now you can:
$('explanation').truncate(100);

Єдина річ, яку тут потрібно остерегаться, полягає в тому, щоб переконатися, що перший аргумент цих методів є елементом себе. У власних методах можна також вернути елемент в кінець для збереження послідовності (або, як це практикується зокрема, будь-який метод, який сам повертає елемент).

Власні Розширення

За цим всім прихований секрет.

У браузерах, які підтримують додавання методів до прототипу власних об'єктів, таких, як HTMLElement всі розширення DOM для елементу є доступними за замовчуванням, навіть без виклику Element.extend(), функції долар або іншої! Тоді наступне буде працювати в цих браузерах:

var my_div = document.createElement('div');
my_div.addClassName('pending').hide();
document.body.appendChild(my_div);

Оскільки прототип власного об'єкта браузера є узагальненим, то всі DOM елементи мають вбудовані розширювані Prototype методи. Це, однак, не відноситься до IE, який не дозволяйте нікому торкатися HTMLElement.prototype. Щоб запрацював перший приклад в IE доведеться розширити елемент за допомогою Element.extend(). Не слід хвилюватись, оскільки метод досить розумний, щоб не розширювати той самий елемент більше, ніж один раз.

Через браузери, що не підтримують цього, потрібно використовувати DOM розширення тільки для елементів, які були розширенні. Наприклад, наведений вище приклад працює в Firefox та Opera, проте додати Element.extend(my_div) після створення елемента, щоб сценарій став справді суцільним. Можна використовувати функцію долар у якості мітки, як у наступному прикладі:

// this will error out in IE:
$('someElement').parentNode.hide()
// to make it cross-browser:
$($('someElement').parentNode).hide()

Не слід забувати про це! Завжди провіряйте у всіх браузерах, які плануються підтримувати.

Це переклад з офіційної документації.

© 2009 - 2020, Розробка - соціальна ІТ спільнота.
Контакти: info@rozrobka.com
Правила користування