Поступила ко мне такая задача, есть сайт на Magento и заказчик желает мониторить ошибки заполнения форм на сайте в Google Analytics (GA). Как всегда на сайте есть и Prototype и jQuery ну и куча JS лапши в придачу, в общем все как обычно. Сначала я нагородил громоздкое решение, но потом в голову пришла хорошая идея, которой и хочу поделиться с хабрасообществом.Под JS лапшой я подразумеваю слабо структурированный JS код сторонних разработчиков на этом сайте. Я буду и далее использовать этот термин для краткости. Я не буду описывать лишние подробности и приводить весь код, изложу кратко мой подход, предполагая, что читатель понимает как работают события в GA, имеет базовые представления о Magento и сам сможет вставить код куда следует.
После анализа сайта я понял что мне крупно повезло, т.к. стиль отображения информации на сайте сохранялся единый. Моя идея простая: для валидации полей форм на фронтенде Magento используется библиотека js/prototype/validation.js (путь от корня сайта). Если валидатор обнаруживает ошибку — он добавляет CSS класс ‘validation-failed’ к DOM элементу поля формы. Также этот класс добавлялся всеми обработчиками из JS лапши. Бинго — этот факт можно отслеживать для отправки в GA соответствующего события. Слава богу что практически вся JS лапша использовала для этого либо метод Element.addClassName из Prototype либо addClass из jQuery и было совсем немного кода, использующего нативные методы JS, которые я заменил на Element.addClassName.
Теперь остается только перекрыть эти два метода библиотек Prototype и jQuery для вызова своей функции checkValidationFailed для отправки события в GA. Т.к. код Element.addClassName в Prototype очень простой, то можно просто заменить этот метод, с jQuery так просто не получится — пришлось использовать т.с. «промежуточный» объект.
Вот мой код (он конечно не идеален, но работает):
document.observe('dom:loaded', function () { Element.addMethods({ addClassName: function(element, className) { if (!(element = $(element))) return; if (!Element.hasClassName(element, className)) element.className += (element.className ? ' ' : '') + className; checkValidationFailed(className, element); return element; } }); var oAddClass = jQuery.fn.addClass; jQuery.fn.addClass = function() { checkValidationFailed(arguments[0], this[0]); return oAddClass.apply(this, arguments); }; function checkValidationFailed(className, element) { if (className != 'validation-failed') { return; } var label = 'undefined'; if (typeof element.name != 'undefined') { label = element.name; } if (typeof element.labels != 'undefined' && typeof element.labels[0] != 'undefined' && typeof element.labels[0].innerText != 'undefined' ) { label = label + ' : ' + element.labels[0].innerText; } dataLayer.push({ 'event': 'form_error_jsvalidator', 'error_message' : label }); } });
Т.к. на сайте используется Google Tag Manager — для отправки сообщений в GA используется стандартный dataLayer.
На основании URL страницы, с которой пришло событие и переменной label в отчете GA легко понять на какой странице и в каком поле формы произошла ошибка — этого было достаточно моему заказчику, но в принципе можно также передавать в GA таким образом еще кучу дополнительной информации.
Думаю что такой подход подойдет не только для Magento, но и для сайтов на других платформах.
ссылка на оригинал статьи http://habrahabr.ru/post/216149/
Добавить комментарий