Часто при инициализации 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 комментария:
А еще лучше - не заметать следы, удаляя атрибут onclick - инициализация будет быстрее. А "настоящие" обработчики навешивать с помощью addEventListener/attachEvent.
Насколько быстрее? На каких объемах это становится заметным? Я думаю на тысячах объектах будет тормозить совсем не это.
для кастомных свойств/атрибутов в драфте html5 ввели разширяемый атибут data-* , (data-params="{width: 250, height: 150, draggable: true, text: 'Трам-парам!'}" или data-width="250" ...).
На мой взгляд не самая красивая задумка w3c-ешников (или whatwg-шников?), однако скорее всего это когда-нибудь станет стандартом. Если использовать "<!doctype html>", то даже валидатор не ругается :)
Да, чертовски круто. Спасибо. Очень просто и гениально.
Отправить комментарий