15.03.2009

Передача параметров из HTML в JavaScript

Часто при инициализации JS-компонента нужно найти определенный DOM-элемент с которым компонент будет работать, а также достать из HTML параметры (настройки). О способах хранения и передачи в JS этих параметров я и хотел бы поговорить.

Раньше я решал эту задачу так: простые параметры передавал через классы, сложные — через дополнительные (не всегда валидные) атрибуты или дочерние элементы.

Предположим, у нас есть DOM-элемент:

<span id="test">тест</span>

При клике на этот элемент мы хотим показывать некий попап. Для показа попапа нужно задать следующие параметры: ширина, высота, таскаемость попапа и текст. Раньше я написал бы примерно следующее:

<span id="test" class="width_250 height_150 draggable"><span class="text">Трам-парам!</span>тест</span>

Потом я бы долго и муторно получал значения этих параметров путем выпарсивания их из классов и доставания из дочерних элементов.

Так бы и мучился дальше, если бы мой коллега Дима Филатов не подсказал гораздо более элегантное решение — прописать атрибут onclick в котором возвращать объект с настройками.

<span id="test" onclick="return {width: 250, height: 150, draggable: true, text: 'Трам-парам!'};">тест</span>

Как достать этот объект:

var element = document.getElementById('test');

// Забираем параметры
var options = element.onclick instanceof Function ? element.onclick() : {};

// Заметаем следы - обнуляем onclick
element.onclick = null;
element.removeAttribute('onclick');

// Навешиваем обработчик onclick для показа попапа
element.onclick = function () {
    showPopup(options);
};

По сути, для передачи настроек используется формат JSON в котором есть шесть типов значений: объект, массив, строка, число, булевское значение и null. Используя эти типы, можно передавать довольно сложную структуру данных, немыслимую для передачи через классы.

По-моему, очень круто. Блин, почему я сам не додумался до этого? :)

4 комментария:

Leonya комментирует...

А еще лучше - не заметать следы, удаляя атрибут onclick - инициализация будет быстрее. А "настоящие" обработчики навешивать с помощью addEventListener/attachEvent.

alpha комментирует...

Насколько быстрее? На каких объемах это становится заметным? Я думаю на тысячах объектах будет тормозить совсем не это.

Vladimir комментирует...

для кастомных свойств/атрибутов в драфте html5 ввели разширяемый атибут data-* , (data-params="{width: 250, height: 150, draggable: true, text: 'Трам-парам!'}" или data-width="250" ...).
На мой взгляд не самая красивая задумка w3c-ешников (или whatwg-шников?), однако скорее всего это когда-нибудь станет стандартом. Если использовать "<!doctype html>", то даже валидатор не ругается :)

Алекс комментирует...

Да, чертовски круто. Спасибо. Очень просто и гениально.