[Javascript] Хитрый onClick ссылки
Конечно можно запоминать в обработчике onClick параметры нажимаемой ссылки - URL и target - и потом сэмулировать щелчок в onLoadHandler при помощи document.location или window.open, но это не совсем то.
К тому же, если у ссылки target="_blank", то при сработавшем позже window.open браузер может заблокировать новое окно как поп-ап.
на jQuery не хочешь?
без всяких ссылок
Нет гарантий, что jQuery будет подгружаться для каждой страницы, где это решение используется.
как реализовать вот это вот ожидание внутри самого обработчика onClickзачем тебе это?
Можно сделать так:
— Повесили на загрузку картинки обработчик onload,который по ссылке переходит
— settimeout функцию через 5 секунд перейти по ссылке
Какая раньше сработает, та и перейдет. Так?
<a href="something" onClick="return onClickHandler(this);">x</a>
var freeClick = false;
function onClickHandler(a) {
if (freeClick) {
return !(freeClick = false);
}
var img = new Image;
img.onLoad = function { onLoadHandler(a); }
img.src = 'someurl';
setTimeout(function { onLoadHandler(a); }, 5000);
return false;
}
function onLoadHandler(a) {
freeClick = true;
a.click;
}
ещё хорошо бы таймаут чистить и отменять загрузку если не успел
a.click;Вот это место поподробнее.
Вот это место поподробнее.да, действительно в ФФ не работает
в ФФ нельзя зафайрить нажатие на ссылку?
Более того, я бы забил на исходную задачу и уже давно бы сваял скрипт для скликивания ссылок контекстной рекламы. И, надо думать, не только я.
Очевидно, почему вообще клик ссылки не должен быть доступен из джаваскрипта, и я вообще удивлен, что где-то a.click может работать.
Можно сделать так:Вообще говоря, задачу решили и тема неактуальна, но подискутировать можно.
— Повесили на загрузку картинки обработчик onload,который по ссылке переходит
— settimeout функцию через 5 секунд перейти по ссылке
Проблема, из-за которой я так упорно цеплялся за то, чтобы сам факт перехода по ссылке был результатом именно _сработавшего_ клика по ссылке (а не отмененного обработчиком клика и осуществленного позже обработчиком onload изобржания или функцией, вызванной по таймауту) появляется для ссылок с target="_new" или target="_blank".
Для таких ссылок нужно было бы открывать новое окно при помощи windows.open. В ФФ все попапы делятся на requested и unrequested. Попапы, открывающиеся в результате клика по ссылке - желательные, в том числе те, которые открываются по windows.open в обработчике клика. Остальные - то есть те, которые открываются по windows.open, вызванной, например, из функции, сработавшей по таймеру - ФФ считает нежелательными, по-умолчанию блокирует, и обойти это никак нельзя.
Именно поэтому я так упорно пытался все сделать в пределах обработчика, чтобы саму реакцию на клик ссылки - переход или открытие окна с переходом - осуществил сам браузер и не было проблем с блокировкой попапа.
Вообще говоря, задачу решили и тема неактуальна, но подискутировать можно.А расскажи, пожалуйста, как.
В src картинки - ссылка на внутрикорпоративный веб-сервис статистики. В ответ он генерирует картинку 1х1. Обычно картинка добавляется при загрузке страницы, чтобы сервис зафиксировал просмотр страницы, но вот решили еще отслеживать просмотры недекорированных страниц (в которых этот js-файл не подгружается) и всякие там файлы для загрузки. А очевидный вариант в этом случае - фиксировать обращение в момент клика по ссылке.
Встал вопрос - как убедиться, что обращение к веб-сервису было (запрос ушел прежде чем переходить по ссылке? Если новая страница открывается в новом окне, то проблем нет - в старом окне картинка, вероятно, успеет подгрузиться. А если в текущем?
onreadystatechange для картинки не подошел - он фигово работает в ФФ. onload же будет ждать, пока картинка подгрузится - это надежно, но дольше, чем просто отправить запрос и забыть, да еще встала вот эта вот проблема с ожиданием и отложенной реакцией на клик браузером.
В итоге все оказалось очень просто.
Когда присваивается значение атрибуту src - браузер делает запрос сразу же. Я отслеживал запросы на стороне сервера, они приходят всегда, вне зависимости от того, как быстро потом произошел переход на новую страницу (т.е. даже если новая страница является соседней в локальной директории).
Я до этого не был уверен, что запрос будет послан всегда - например, что браузер не разорвет соединение, если переход на новую страницу уже был, а сервер с ответом затупил. Оказалось - дождется и картинку загрузит, даже если ответ вернулся через 10 секунд после перехода (лично для меня это было неожиданностью). А запрос так и подавно точно будет послан - так что необходимость чего-то ждать отпала, можно было просто разрешать переход по ссылке сразу после установки значения в src картинки.
Одна про то, как реально устроены таймеры в однопоточном Javascript - http://ejohn.org/blog/how-javascript-timers-work/
Вторая про то, как открывать попапы - http://www.gtalbot.org/FirefoxSection/Popup/PopupAndFirefox....
Requested popups are windows created as a result of clicking a link or clicking a button. One mouse click, only one popup.
Unrequested popups are windows created automatically without any user interaction. Often, such unrequested popups have advertisement content. They often "pop up" as you arrive at a site or as you close a window. One mouse click, more than one popup.
Еще хорошая статья по специфике windows.open в ФФ есть здесь - http://developer.mozilla.org/en/DOM/window.open
Это не кроссбраузерно?
Я уже забываю тонкости js, но вроде как можно на ссылку повесить обработчик, который при клике будет ее переписывать и соотв.отправлять запрос на сервер [Гугла], сервер уже редиректит в нормальное место.
Лог через редирект был вообще первым решением, но по ряду причин от него пришлось отказаться.
Я собственно про причины и спрашиваю, то что многие это делают через редирект — общее место, а вам-то почему не подошло?
В случае, если используется то решение, описанное выше, то, если сервер не отвечает - просто не загрузится картинка в фоне, но переход по нужному адресу будет.
Если же сервис лежит - то пользователь не попадет на нужную страницу, потому что не будет редиректа. Это плохо.
Ок, что случится, если редиректящий сервис лежит?Это главная проблема? Если да, то она решается элементарно. Тем более у вас корпоративная сеть.
Весь этот "редиректящий сервис" — кусок конфига вебсервера, задача вашей системы в этом случае — парсить логи.
А для вебсерверов есть куча решений для обеспечения отказоустойчивости.
И потом, да, я согласен, что вариант с редиректом - тоже хороший вариант, но мне неочевидно, что это решение прямо вот настолько лучше. Плюс само ожидание пользователем перехода на требуемую страницу потенциально дольше, если сервер статистики тупит с ответом.
Как элементарно решается вопрос лежащего веб-сервера (именно самого сервера, а не приложения статистики стоящего не за балансировщиком нагрузки и без дублера?Дублером.
Плюс само ожидание пользователем перехода на требуемую страницу потенциально дольше, если сервер статистики тупит с ответом.
Там нечему тупить. Голый вебсервер отвечает.
Как элементарно решается вопрос лежащего веб-сервера .. стоящего не за балансировщиком нагрузки и без дублера?
Дублером.
Там нечему тупить. Голый вебсервер отвечает.
Да, это все чудесно, но - так и не последовало ответа, почему это решение принципиально лучше того с изображением, если у того:
а) быстрее осуществляется переход по ссылке - запаздывающий ответ сервера ввиду нагруженности никто не отменял
б) решение защищено от падения сервиса статистики
Аргумент "а вон гугл сделал так" - не аргумент, может у гугла есть возможность под обслуживание редиректов отдать 6 серверов с балансировщиком.
Для резервирования, как это ни удивительно, достаточно всего 2 машины. Причем они могут быть еще чем-то заняты.
Да, это все чудесно, но - так и не последовало ответа, почему это решение принципиально лучше того с изображением
В твоем решении есть слабое место, "проверил вроде так и есть":
Когда присваивается значение атрибуту src - браузер делает запрос сразу же. Я отслеживал запросы на стороне сервера, они приходят всегда, вне зависимости от того, как быстро потом произошел переход на новую страницу (т.е. даже если новая страница является соседней в локальной директории).
Ну и кстати ты напрасно думаешь что я пытаюсь сказать что твое решение хуже. По-моему (плохо помню) и то и другое вроде много раз описывалось в инете, наверно тут нет большой проблемы.
Так что для меня вопрос исчерпан, спасибо.
Для резервирования, как это ни удивительно, достаточно всего 2 машины. Причем они могут быть еще чем-то заняты.Ну, я с этим не спорю. Но не всегда же есть контроль над инфраструктурой.
Ладно, вопрос действительно исчерпан, оба решения подходят.
Оставить комментарий
2354570
Наткнулся на такую ситуацию.Есть ссылка, открывающая окно, что-то типа
<a href="someurl" onClick="return handler;">x</a>
В обработчике onClick ссылки должно произойти следущее:
1. Надо создать Image.
2. Нужно запустить Image загружаться (назначить src) и выставить таймаут при помощи setTimeout.
3. Либо дождаться, пока картинка загрузится, либо дождаться сработавшего таймаута и выйти из обработчика.
То есть, для юзера эффект такой - он жмет ссылку, но она открывается с небольшим запаздыванием (время запаздывания - минимум время загрузки картинки, максимум таймаут в 5 секунд).
Так вот, непонятно, как реализовать вот это вот ожидание внутри самого обработчика onClick. Бесконечный цикл по переменной-флагу не вариант, конечно.
То есть получается как-то так, условно:
Как бы такое можно реализовать? Должно быть кроссбраузерное решение, ко всему прочему.