Установка целей - сразу для Метрики и Analytics универсальный и простой скрипт целей для Яндекс Метрика и Google Analytics

  • 06.12.2016
  • 1149
  • 3.8
  • 0
  • Константин Винниченко
Я в своих и клиентских проектах на продающих страницах часто использую 2 цели для Директ и AdWords:
  • SEND – любая отправка данных через форму, конверсионная цель.
  • TIME – человек активно провел 40 секунд на сайте, цель для ретаргетинга и измерения качества трафика.
Для этого разработал простой скрипт, который облегчает установку и теперь делюсь с посетителями моего блога. Данный скрипт будет еще дорабатываться и все изменения будут доступны в этой же статье. Так же жду ваших комментариев для улучшения данного скрипта.

Поясню подробнее о данных целях

Цель SEND вешается каждые 5 секунд на формы заявок в которых присутствует тег FORM, такая частота необходима для таких случаев, когда форма генерируется автоматически. Например: всплывающие окна обратных звонков или онлайн-чат. Но не будет работать, если на форме отправки данных отсутствует тег FORM или/и данные формы отправляются методом JavaSctript.
Цель TIME срабатывает после 40 секунд (это значение можно поменять) активного посещения, то есть счетчик начнет срабатывать после того, как человек выполнил клик или прокрутку на сайте и отключается, если человек ушел со страницы и продолжает отчет, когда, не закрывая вкладу вернулся к вам и продолжает изучать вашу страницу. Можно сказать, эта цель имитирует «отказ», если она не была достигнута.

Установка скрипта на цели TIME и SEND

Устанавливаем код перед закрывающем тегом </BODY> после установки счетчиков:
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<!-- Универсально от SeoUp.su цели TIME и SEND -->
<script type="text/javascript">
    /* включить цели для Yandex Metrika true/false */
    var ymc = true;
    /* включить цели для Google Analytics true/false */
    var gac = true;
    /* указать Analytics, если его на сайте нет или подключен через GTM, тогда убрать там и указать здесь UA-111... */
    var gaObj = "";
    /* количество секунд для достижения цели TIME */
    var secMax = 40;
    /* стартовое количество секунд до достижения цели */
    var secCur = 0;
    /* var fForm = "FORM:not(#uptocall-form, #uptocall-form-email, #search, .search, #subscribe, .subscribe, #smartfilter, .smartfilter, #login, .login)"; */
    /*var fForm = "FORM:has(.seoup, .feedback)";*/
    var fForm = "FORM";
    /* aRequired - способ поиска обязательного поля по атрибуту: type/name/class/serialize */
    var aRequired = "type";
    /* vRequired -  сделать обязательным иначе цель не достигнута, либо оставить пустым или указать через запятую "tel,email" */
    var vRequired = "tel,email";
    /* bRequired - делать обязательным к заполнению, не рекомендуется когда емейл и телефон на одной форме */
    var bRequired = false;
    /* указать кнопку submit у fForm, если данные идут через AJAX, пример ".bsend, button, .submit", "[type~='submit']" */
    var fBut = "";
    /* целевая страница URL содержит ORDER_ID=  , либо оставить пустым*/
    var tUrl = "";
    /* захват цели SEND */
    var recSEND = true;
    /* ценность целей для электронной коммерции */
    var priceTIME = 0;
    var priceSEND = 0;
    /* задать маску для обязательного поля, не рекомендуется для массива разных данных */
    var maskInput = false;
    var viewInput = "+9999-999-9999";
    /* далее переменные не менять */
    var sAlert = false;
    var sMen = false;
    var sFocus = false;
    var sConsole = '';
    var sBuf = '';
    var sTimId = '';
    var arrReq = vRequired.split(',');
    if ((priceTIME > 0) || (priceSEND > 0)) {
        window.dataLayer = window.dataLayer || [];
    }
    function eventGoal(eg, ec) {
        if (ymc) {
            try {
                /*Указать номер Яндекс.Метрики*/
                yaCounter43800000.reachGoal(eg);
                consoleAlert("Сработал " + eg + " для YM");
            } catch (e) {
                consoleAlert("ОШИБКА отправки " + eg + " для YM.\n" + e);
            }
        }
        if (gac) {
            try {
                gtag('event', 'event_name', {'event_category': 'SEOUP', 'event_action': eg});
                consoleAlert("Сработал " + eg + " для GA");
            } catch (e) {
                consoleAlert("ОШИБКА отправки " + eg + " для GA через gtag().\n" + e);
                try {
                    ga("send", "event", "SEOUP", eg);
                    consoleAlert("Сработал " + eg + " для GA");
                } catch (e) {
                    consoleAlert("ОШИБКА отправки " + eg + " для GA через ga().\n" + e);
                }
            }
        }
        if (ec > 0) {
            window.dataLayer.push({
                "ecommerce": {
                    "currencyCode": "RUB",
                    "purchase": {
                        "actionField": {
                            "id": "auto"
                        },
                        "products": [
                            {
                                "id": 1,
                                "name": eg,
                                "price": ec,
                                "category": "SEOUP/" + eg
                            }
                        ]
                    }
                }
            });
            console.log("ЦЕНА " + eg + "=" + ec);
        }
        return true;
    }
    function consoleAlert(text) {
        console.log(text);
        if (sAlert) {
            alert(text);
        }
        return true;
    }
    function formCheck(form) {
        var vOk = false;
        var i = 0;
        if ((aRequired != "") && (vRequired != "")) {
            if (sAlert) {
                console.log("Захвачен контейнер для поиска INPUT " + aRequired + "=\"" + vRequired + "\":");
                console.log(form);
                if(jQuery.isArray(form)) {
                    console.log("Элементы ввода для поиска ("+form.length+" шт.):");
                    for (i = 0; i < form.length; i++){
                        console.log(form[i]);
                    }
                } else {
                    form = jQuery("INPUT", form);
                    console.log("Элементы ввода были переопределены для не FORM контейнеров (нашли "+form.length+" шт.):");
                    for (i = 0; i < form.length; i++){
                        console.log(form[i]);
                    }
                }
            }
            for (var j = 0; j < arrReq.length; j++) {
                switch (aRequired) {
                    case "name":
                        for (i = 0; i < form.length; i++)
                            if (form[i].name == arrReq[j])
                                if (form[i].value != '') {
                                    vOk = true;
                                    break;
                                }
                        break;
                    case "type":
                        for (i = 0; i < form.length; i++)
                            if (form[i].type == arrReq[j])
                                if (form[i].value != '') {
                                    vOk = true;
                                    break;
                                }
                        break;
                    case "class":
                        for (i = 0; i < form.length; i++)
                            if (form[i].classList.contains(arrReq[j]))
                                if (form[i].value != '') {
                                    vOk = true;
                                    break;
                                }
                        break;
                    case "serialize":
                        vSer = jQuery(form).serialize();
                        if (vSer.indexOf(arrReq[j]) + 1) {
                            vOk = true;
                            break;
                        }
                        break;
                    default:
                        alert("Ошибка в настройках цели, не указан aRequired");
                }
            }
        } else vOk = true;
        if (sAlert) {
            console.log(fForm+' serialize ' + jQuery(form).serialize());
        }
        if (vOk) {
            eventGoal('SEND', priceSEND);
        }
        else consoleAlert("Не сработал SEND, не указано обязательное поле для INPUT " + aRequired + "=\"" + vRequired + "\"");
        return true;
    }
    if (gaObj != "") {
        var scGA1 = document.createElement("script");
        scGA1.setAttribute("type", "text/javascript");
        scGA1.setAttribute("src", "https://www.googletagmanager.com/gtag/js?id=" + gaObj);
        document.head.appendChild(scGA1);
        var scGA2 = document.createElement("script");
        scGA2.setAttribute("type", "text/javascript");
        scGA2.innerHTML = "window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', '" + gaObj + "');";
        document.head.appendChild(scGA2);
    }
    if (maskInput) {
        var scMI = document.createElement("script");
        scMI.setAttribute("src", "https://seoup.su/api/jquery.maskedinput.min.js");
        scMI.setAttribute("type", "text/javascript");
        document.head.appendChild(scMI);
    }
    jQuery(document).ready(function () {
        if (ymc) sConsole = " YM";
        if (gac) sConsole = sConsole + " GA";
        sBuf = "Библиотека jQuery " + jQuery.fn.jquery + " - Цели работают для" + sConsole + ", где TIME=" + secMax;
        if (recSEND) {
            if (vRequired == "") sBuf = sBuf + " и SEND срабатывает при любой отправке " + fForm;
            else sBuf = sBuf + " и SEND срабатывает только в \"" + fForm + "\" с данными INPUT " + aRequired + "=\"" + vRequired + "\"";
        }
        if (recSEND && ((aRequired != "") && (vRequired != ""))) {
            if (bRequired) {
                for (var i = 0; i < arrReq.length; i++) {
                    jQuery("INPUT[" + aRequired + "='" + arrReq[i] + "']").attr("required", true);
                }
                sBuf = sBuf + " обязательное";
                if (fBut != "") {
                    sBuf = sBuf + " с AJAX кнопкой \"" + fBut + "\"";
                }
            }
            if (maskInput) {
                sBuf = sBuf + " и маска " + viewInput;
            }
        }
        console.log(sBuf);
        if (document.cookie.indexOf('_ym_debug=1') + 1) {
            sAlert = true;
        }
        if (sAlert) {
            sBuf = "Включен режим alert() для TIME";
            if (recSEND) sBuf = sBuf + " и SEND";
            console.log(sBuf);
        }
        sTimId = setInterval(function () {
            if ((sMen == true) && (sFocus == true)) {
                if (secCur == secMax) {
                    secCur = secCur + 1;
                    clearTimeout(sTimId);
                    eventGoal('TIME', priceTIME);
                }
                else if (secCur <= secMax) {
                    secCur = secCur + 1;
                    console.log('TIME = ' + secCur + ' из ' + secMax);
                }
            }
        }, 1000);
        if ((fForm != "") && (recSEND)) {
            var attr = aRequired + "-" + vRequired;
            var fFormNew = fForm + "[fsend!='" + attr + "']";
            setInterval(function () {
                if (fBut != "") {
                    jQuery(fBut, fFormNew).attr("bsend", "ajax");
                }
                if (fBut != "") {
                    jQuery(fBut, fFormNew).click(function (e) {
                        formCheck(this.closest(fForm));
                        return true;
                    });
                }
                jQuery(fFormNew).submit(function (e) {
                    formCheck(this);
                    return true;
                });
                if (maskInput) {
                    for (var i = 0; i < arrReq.length; i++) {
                        jQuery(fFormNew + " INPUT[" + aRequired + "='" + arrReq[i] + "']").mask(viewInput);
                    }
                }
                jQuery(fFormNew).attr("fsend", attr);
            }, 3000);
        }
        jQuery(window).focus();
        if (tUrl != "") {
            if (window.location.href.indexOf(tUrl) + 1) {
                setTimeout(function () {
                    eventGoal('SEND', priceSEND);
                }, 100);
            }
        }
    });
    jQuery("body").click(function () {
        sMen = true;
        sFocus = true;
    });
    jQuery(window).scroll(function () {
        sMen = true;
        sFocus = true;
    });
    jQuery(window).bind("focus", function () {
        sFocus = true;
    });
    jQuery(window).bind("blur", function () {
        sFocus = false;
    });
</script>
Новый способ, когда не требуется много правок
 

<script charset="utf-8" type="text/javascript" src="https://seoup.su/api/eventgoal.php?id=9999"></script>

Комментарии

yaCounter9999 – заменяем на свой номер счетчика, например yaCounter39725635
secMax = 40 – можно поставить другое значение отличное от 40 секунд, для длинных продающих страниц данный показатель в целом нормальный, если интернет-магазин, то возможно разумно поставить для карточек товара 25 секунд.
begin/end Целевая страница – желательно убрать, если у вас такой страницы нет
var t_url = "=checkout.complete"; - поставить свое значение, если у вас такая целевая страница есть, она дополнительно обеспечивает гарантию срабатывания цели SEND. Например, SEND будет срабатывать на формах заявка обратного звонка, покупка в 1 клик и страница подтверждения заказа в интернет магазине. Итого цель SEND собрала все заявки, это нам и нужно для Директа, где можно указать лишь одну цель в отчете, и мы получим отчет по всем конверсионным действиям.

Тестируем цели и исправляем ошибки

1. После установки открываем сайт и смотрим лог консоли, если надпись "Установлены цели TIME и SEND" появилась, то скорее всего цели работают.
2. Надо быть осторожным универсальный скрипт все же не лишен недостатка. Скрипт может не работать, если не подключена библиотека jQuery
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
3. В Яндекс.Метрика есть специальный тег, с которым открываешь страницу и смотришь логи отчета и Метрика отобразит свои действия по конверсиям
site.ru?_ym_debug=1
Подсказка: кстати так можно определить достигаемые цели от сервисов обратного звонка и онлайн-консультантов. Выполняете заявку, пишите сообщение и смотрите какая цель отобразилась, данное имя можете добавить в счетчик и буде собирать по данной цели конверсии и статистику.
4. Если скрипт установили, а счетчики не поставили, цели работать не будут.
5. Желательно скрипт ставить после вызова счетчиков, если цель универсального скрипта сработает раньше, чем загрузиться счётчик то будет ошибка.
6. Если JavaScript отключен в браузере, скрипт работать не будет. Крайне редкий случай.
7. Если счетчики слежения блокируют антивирусы, то скрипт так же работать не будет.

Все корректно, а целей в отчете нет?

В Яндекс.Метрика обычно требуется 15-40 минут, чтобы она отобразила достижение цели в своих отчетах
В Яндекс.Директ обычно требуется 1-2 дня, чтобы из отчета «Все цели» появились уже имена конкретных целей SEND и TIME. Яндекс.Директ предварительно надо связать с Яндекс.Метрика.
В Google Analytics в режиме реального времени может отобразить цель, задержка 3-15 секунд
В Google AdWords обычно требуется 2-3 для показа целей. Google AdWords предварительно надо связать с Google Analytics.


Полезно прочесть


Полезно сделать

Рейтинг:
(3.75 из 5 - 5 голосов)
Сохранить страницу себе: