Возобновить исходное событие щелчка привязки после вызова Google Analytics

Для набора якорных тегов на наших сайтах мы отправляем событие в Google Analytics, чтобы отслеживать поведение пользователей, сейчас я использую следующий код (срабатывает при нажатии):

event.preventDefault();
ga(tracker, 'event', category, action, label, value, { 'hitCallback':
    function(){
        window.location = url;
    }
}); 

Это работает нормально, но есть одна проблема, некоторые пользователи (включая меня), как правило, щелкают средней кнопкой мыши / командой + щелкают по большинству ссылок, чтобы открыть их в новой вкладке. Это очевидно не будет работать с приведенным выше сценарием.

Мне было интересно, если есть что-то вроде event.triggerDefault() это вернет контроль над событием браузеру, или, если мне действительно нужно будет создать что-то, что будет определять щелчки средней мыши / команды от пользователя.

Sidenote: мы используем нативный javascript

2 ответа

С помощью Как вызвать событие после использования event.preventDefault() и Как клонировать или повторно отправить события DOM? Я придумал следующее решение:

<script>
var anchor = document.getElementById('anchor');
anchor.addEventListener('click', function(e){
    if(e.eventHandled) return;
    e.preventDefault();

    window.alert('Javascripts');

    var clonedEvent = new e.constructor(e.type, e);
    clonedEvent.initEvent(e.type, true, false);
    clonedEvent.eventHandled = true;
    anchor.dispatchEvent(clonedEvent);
});
</script>
<a href="http://www.google.com/" id="anchor">Google</a>

Теперь при нажатии клавиши + ссылка сначала вы получаете оповещение, а после отправляются на новую вкладку.

Jsfiddle: http://jsfiddle.net/8NRJY/1/ (обратите внимание, что jsfiddle не будет изменять URL-адреса, если вы делаете обычный клик, но это прекрасно работает вне jsfiddle)

Теперь осталось только сделать этот кросс-браузер совместимым и, конечно же, вставить отслеживание Google (dispatchEvent будет внутри обратного вызова).

Изменить: Вот кросс-браузер (по крайней мере IE8+) совместимая версия.

Первые функции должны быть частью вашей библиотеки, если вы работаете в нативном JavaScript.

<script>
var addEventListener = function(elem, eventName, handler, useCapture) {
    if (elem!=null) {
        if (elem.addEventListener) {
            if (useCapture===true||useCapture===false) {
                elem.addEventListener(eventName, handler, useCapture);
            }
            else {
                elem.addEventListener(eventName, handler);
            }
        } else {
            elem.attachEvent('on' + eventName, function(evt) {              
                evt = evt || window.event;
                evt.target = evt.target || evt.srcElement;
                handler(evt);
            });
        }
    }
};

var onReady = function (fn) {
    if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', fn);
    } else {
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState === 'interactive' || document.readyState === 'complete'){
                fn();
            }
        });
    }
};

var fireEvent = function(el, event){
    if(document.createEvent){
        var clonedEvent = new event.constructor(event.type, event);
        clonedEvent.initEvent(event.type, true, false);
        el.dispatchEvent(clonedEvent);
    }else if(document.createEventObject){
        var clonedEvent = document.createEventObject();
        el.fireEvent('on'+event.type, clonedEvent);
    }
};

onReady(function(){
    var anchor = document.getElementById('anchor');
    addEventListener(anchor, 'click', function(e){
        if(!anchor.eventDispatched){
            e.preventDefault ? e.preventDefault() : e.returnValue = false;
            anchor.eventDispatched = true;
            fireEvent(anchor, e);
        }else{
            anchor.eventDispatched = false;
            e.returnValue = true;
        }
    });
});
</script>
<a id="anchor" href="http://www.google.com">Test</a>  

Изменить 2: Исправить это для работы с Google Analytics оказывается гораздо сложнее, чем я думал.

В современных браузерах он отлично работает сразу. В IE8 только одно событие за один раз (хранится в window.event), что означает, что обратный вызов Google переопределяет это, что означает, что я не могу повторно запустить исходное событие. Я пробую различные способы клонирования события, чтобы оно заработало, но пока безуспешно.

Я ненавижу тебя, IE8.

Редактировать 3: Я разочаровался в попытке сделать эту работу в IE8.

Редактировать 4: Оказывается, Chrome блокирует новое окно как всплывающее окно, потому что событие вызывается после обратного вызова (даже если это исходное событие пользовательского щелчка).

Если вы хотите отслеживать навигацию пользователя по внутренним ссылкам на вашем сайте с помощью Google Analytics, может помочь следующее.

  1. Сохраните данные события Google Analytics (GA) в файле cookie, но пока не отправляйте событие GA.
  2. Позвольте выполнению поведения по умолчанию события DOM.
  3. На следующей странице прочитайте файл cookie, найдите события GA в очереди и отправьте их в аналитику.

Из того, что я испытал, куки-файлы устанавливаются мгновенно перед тем, как покинуть страницу.

Чтобы убедиться, что события GA соответствуют нужной странице в ваших отчетах, вы должны отправить события в GA следующим образом:

var currentPage = window.location.pathname;
var previousPage = document.referrer.replace(/^[^:]+:\/\/[^/]+/, '').replace(/#.*/, '');

ga('set', 'page', previousPage);
ga(tracker, 'event', category, action, label, value, { 
    'hitCallback': function(){
        ga('set', 'page', currentPage);
    },
    'nonInteraction': 1
});

Обратный вызов восстанавливает значение страницы для последующих запросов аналитики. Отсутствие взаимодействия гарантирует, что событие не повлияет на ваш показатель отказов.

Другие вопросы по тегам