Щелкните Ведение журнала с помощью JavaScript.

Я хочу регистрировать все клики по ссылке.

Я написал небольшой регистратор, который можно вызвать по URL-адресу (возвращает пустую страницу). Этот URL-адрес вызывается методом jquery-ajax. Но, к сожалению, не каждый клик регистрируется, если пользователь использует firefox (в IE все выглядит нормально).

Я пробовал много вещей, но не нашел решения этой проблемы, у кого-нибудь есть клей?

HTML-код:

<a href="http://google.com" onclick="return loggClick();">Click</a>

JS-jQuery-скрипт:

function loggClick(){
   $.ajax({
        type: "POST",
        url: "Logger.ff", //dynamic url to logging action
        data: {
            sid: 'abc123' //random data
        },
        contentType: "application/x-www-form-urlencoded; charset=UTF-8",
        cache: false
    });
    return true;
}

РЕДАКТИРОВАТЬ: в примере я пропустил, что мне нужно передать динамические параметры в js-вызове, поэтому «невозможно» удалить событие onclick :(


person gamue    schedule 19.03.2009    source источник


Ответы (5)


Я бы начал избавляться от встроенного кода 'onclick' и привязывать событие позже:

  <a href="http://google.com" rel="outbound" >Click</a>


   $("a[rel=outbound]").click(function(){ 
        var url = this.href; 
        $.ajax({
        async: false,
        type: "POST",
        url: "Logger.ff", //dynamic url to logging action
        data: {
                sid: 'abc123' //random data
                clicked: url
        },
        contentType: "application/x-www-form-urlencoded; charset=UTF-8",
        cache: false
     });
     return true; 
  }); 

Кроме того, у вас может возникнуть "состояние гонки". В моем примере я установил для async значение false.

Это остановит возврат функции и переход по ссылке до того, как запрос будет выполнен.

Об асинхронном

Причина, по которой я использую здесь async: false, заключается в том, что по умолчанию aync имеет значение true, что означает, что запрос AJAX может быть передан только частично к тому времени, когда браузер увидит return: true и уйдет со страницы.

Это то самое «состояние гонки», о котором я упоминал. Здесь это дешевый трюк, который позволяет избежать этого, заставляя браузер фактически останавливаться до тех пор, пока запрос не будет завершен, а затем позволяя браузеру щелкнуть ссылку.

Более изощренным ответом было бы вернуть "false" (что убьет встроенное в браузер поведение "follow link"), а затем выполнить настоящее перенаправление в функции complete.

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

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

(И, следовательно, сложность этого решения на порядок сложнее реализовать на простом примере, чем async: false )

person Kent Fredric    schedule 19.03.2009
comment
+1 Мне это нравится, хотя OP должен иметь контроль над кодом на стороне сервера, чтобы выполнить перенаправление местоположения, верно? - person bendewey; 19.03.2009
comment
@бендеви что? ваша последняя часть не имела смысла. - person Kent Fredric; 19.03.2009
comment
Почему это лучше? Что-то не так с кликом? Как вы думаете, это решит проблему или вы предлагаете это только потому, что оно лучше? - person Josef Sábl; 19.03.2009
comment
это лучше, здесь есть решение из двух частей. Но делать код правильно, а также работать — это всегда хорошая сделка 2-к-одному. - person Kent Fredric; 19.03.2009
comment
Кроме того, я видел странности со встроенным способом, которые не имели смысла, поэтому я обычно избегаю их, как чумы. - person Kent Fredric; 19.03.2009
comment
моя вина, я не заметил часть async=false, я думал, что вы передаете URL-адрес logger.ff для перенаправления. полностью неправильно прочитал ваш пост - person bendewey; 19.03.2009
comment
@kent fredric, быстрый вопрос, почему вы используете исходящий трафик, а не nofollow? - person bendewey; 19.03.2009
comment
потому что nofollow не делает того, что вы думаете. SEO-специалисты злоупотребляют nofollow за неправильные вещи. rel — атрибут, описывающий отношение ссылок к странице. таким образом, nofollow сематически бессмысленно. - person Kent Fredric; 20.03.2009
comment
Добавление async false, по-видимому, заставляет Chrome 41 блокировать открытие ссылки (цель пустая), как если бы это было всплывающее окно. - person NLemay; 01.04.2015
comment
Вы действительно не должны использовать async:false в производстве. Это был просто удобный способ облегчить диагностику проблемы. то есть: если браузер перенаправляется до завершения фонового асинхронного соединения, код может сломаться, и ваш сервер может потерять передачу. Следовательно, я заблокировал до тех пор, пока не было получено «ОК», а затем сообщил браузеру «ОК», перенаправление теперь в порядке. Но, вероятно, есть лучшие способы. - person Kent Fredric; 06.04.2015
comment
@NLemay Я не сильно расширил использование асинхронных элементов управления, надеюсь, это будет информативно. - person Kent Fredric; 07.04.2015

Я думаю, что причина, по которой FF дает вам плохие результаты, заключается в том, что вы покидаете страницу до того, как действие требует времени для выполнения. Как упоминается в ссылке mhartman, если вы используете цель для своей внешней ссылки, она должна работать нормально. Если вы не можете этого сделать, вам, возможно, придется дождаться завершения журнала, хотя вы можете увидеть задержки в навигации.

HTML-код

<a href="http://google.com" onclick="return loggClick(event);">Click</a>

в

function loggClick(e) {
  if (!e) e = window.event;

  e.preventDefault();  // cancels the link

  var theLink = this.href;  // stores the link for later

  $.ajax({
     async: false,
     type: "POST",
        url: "Logger.ff", //dynamic url to logging action
        data: {
            sid: 'abc123' //random data
        },
        contentType: "application/x-www-form-urlencoded; charset=UTF-8",
        cache: false,
         complete: function() {
           // navigate when the log completes
           this.location.href = theLink;
         }
    });
    return true;
  }
}
person bendewey    schedule 19.03.2009
comment
спасибо за ваш ответ, отлично работал в Firefox, но не в IE. Но async:true было достаточно. - person gamue; 19.03.2009
comment
Осторожно, e.preventDefault() несовместим с IE8. - person mbokil; 23.07.2013

Еще один подход на стороне сервера, о котором вы, возможно, не подумали, — это иметь страницу, которая обрабатывает ваши перенаправления и затем регистрирует данные.

Например:

<a href="LoggerRedirect.ff?url=http://google.com">Click</a>
person bendewey    schedule 19.03.2009
comment
Я реализовал что-то подобное на одном из своих сайтов, проблема в том, что очень сложно отделить шум от журналов кликов. Я обнаружил, что отношение кликов пауков к кликам людей составляет примерно 50:1. Насколько я знаю, большинство пауков не загружают интерпретатор JS для каждой посещаемой ими страницы, поэтому использование JS для регистрации исходящих кликов кажется достаточно разумным. - person prairiedogg; 23.10.2009

Приведенный выше постер верен, он ненадежен, потому что вы покидаете страницу до того, как она успевает ее зарегистрировать.

Вы можете сделать это:

1) вернуть false, поэтому href не активен. 2) зарегистрируйте клик 3) используйте location.href для перенаправления на URL-адрес, на который он был бы перенаправлен

вы можете увидеть небольшую задержку, если для выполнения обработчика onclick требуется много времени.

person Community    schedule 19.03.2009

В этом примере сообщение ajax будет запущено до обработки клика по ссылке. Я обнаружил, что мне нужно синхронно вызывать ajax, иначе POST не будет выполнен. В этом примере мой пост ajax относится к странице PHP, которая добавляет файл журнала. Этот пример эффективен, поскольку он прикрепляет к окну только событие клика. Это также не помешает пользователю щелкнуть ссылку.

//attach click event to window
attachClickEvent = function() {
    $(document).on('click', function(e) { //document for IE8 compatibility
        var element = $(e.target);
        var tag = element.prop('tagName');

        if (tag === 'A') {
            var data = {'title':document.title, 'URL':element.attr('href'), 'origin':location.href};
            logData(data);
        }
    });
}

logData = function(data) {
    $.ajax({
        async: false,
        cache: false,
        type: "POST",
        data: data,
        url: 'logger.php',
        success: function(msg) { 
            //debugging
        },
        error: function() {
            //debugging
        }
    });
}
person mbokil    schedule 22.07.2013