Имитация нативного клика

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

Это то, что у меня есть до сих пор:

var $el = $('a#my_special_link');
var onClick = $el.attr('onclick');

// Hack to capture the event object
var ev_reference;
var ev_capture = function(ev) { ev_reference = ev; }
$el.bind('click', ev_capture);

// Don't leave out the onClick handler
if ( typeof onClick == 'function' )
    $el.bind('click', onClick);

$el.trigger('click');

// Clean up
$el.unbind('click', ev_capture);
if ( typeof onClick == 'function' )
    $el.unbind('click', onClick);

// Redirect if necessary
if ( ! ev_reference.isDefaultPrevented() )
  window.location = $el.attr('href');

Любые предложения по улучшению приветствуются.

PS: Да, это то же самое, что и обычная ссылка, за исключением того, что вы можете выполнять некоторые другие промежуточные действия.

PPS: Нет, просто $el.trigger('click'); не изменит местоположение.


person scribu    schedule 23.11.2009    source источник


Ответы (4)


enter code hereЧтобы извлечь мои заметки к другим сообщениям: (другой способ сказать те же основные вещи)

      <a href="somewhere" id="mylink">MyLink</a> 
        <script>jQuery('#mylink').click(function(){
            // do whatever I want here, then redirect
             window.location.href = "http://stackoverflow.com";
        });
        function doClick(){
            jQuery('#mylink').trigger('click'); 
        };
        // trigger the redirect now
        doClick();
        </script>

РЕДАКТИРОВАТЬ1: @ комментарии:

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

Для того, чтобы поставить свой логин, вы ставите его там, где у меня есть мой

 "// do whatever I want here, then redirect"

комментарий Чтобы удалить другое событие, привяжите его только к этому:

   <a href="somewhere" id="mylink">MyLink</a> 
        <script>jQuery('#mylink').unbind('click').bind('click', function(){
            // do whatever I want here, then redirect
             window.location.href = "http://stackoverflow.com";
        });
        function doClick(){
            jQuery('#mylink').trigger('click'); 
        };
        // trigger the redirect now
        doClick();
person Mark Schultheiss    schedule 23.11.2009
comment
Это не будет работать с другим обработчиком. Например: jQuery('#mylink').click(function(){ console.log('другой обработчик'); return false; }); - person scribu; 24.11.2009
comment
Проблема в том, что у меня нет контроля над другими обработчиками. Мне просто нужно убедиться, что они выполняются, а затем решить, следует ли мне перенаправлять или нет. - person scribu; 24.11.2009
comment
Отмена привязки может дать вам контроль до того, как произойдет другая, но, конечно, если ссылка будет выполнена на другой сайт, у вас НЕ будет выбора, поскольку поезд покинет станцию, и страница будет заменена. - person Mark Schultheiss; 24.11.2009

http://docs.jquery.com/Events/trigger#eventdata

$('a#my_special_link').trigger("click");
person ChaosPandion    schedule 23.11.2009
comment
Это не будет перенаправлять или что-то еще. Он выполняет только обработчик события. - person Josh Stodola; 24.11.2009
comment
Точно. Я уже запускаю обработчики событий. Мне нужна часть перенаправления. - person scribu; 24.11.2009

"если никто из слушателей не помешал по умолчанию, изменить местоположение."

Звучит так, как ведет себя обычная ссылка...?

В любом случае, если вы пытаетесь найти «return false», он не будет найден с использованием isDefaultPrevented(), который вернет true только в том случае, если preventDefault() вызывается из того же объекта события. В этом примере я отправляю объект события в whatever(), и если эта функция устанавливает preventDefault(), окно все равно перемещается (это то, что вам нужно...?)

$('a#my_special_link').bind('click', function(e) {
  whatever(e);
  if (e.isDefaultPrevented()) {
    window.location = $(e.target).attr('href');
  }
});
person David Hellsing    schedule 23.11.2009
comment
Любой обработчик, кроме onClick=, который либо возвращает false, либо вызывает ev.preventDefault(), приведет к тому, что isDefaultPrevented() вернет true, так что это не проблема. Проблема в том, что я не пишу атрибут onClick=. Я просто должен справиться с этим. - person scribu; 24.11.2009
comment
Хорошо, так как ты хочешь справиться с этим? похоже, что вы можете просто инициировать щелчок с помощью триггера («щелчок»), а затем позволить браузеру перенаправляться естественным образом, если ни один обработчик событий не предотвратил значение по умолчанию. - person David Hellsing; 24.11.2009
comment
Я предполагаю, что из соображений безопасности браузер не будет перенаправлять, если вы просто инициируете событие click. - person scribu; 24.11.2009
comment
вызвать щелчок, если вы находитесь на ТОЙ ЖЕ странице (* или на том же сайте), будет перенаправлено на значение по умолчанию, если это то, на что вы инициируете щелчок по ссылке - точно так же, как если бы вы имели ссылку на другой сайт и щелкнули ее вручную. - person Mark Schultheiss; 24.11.2009
comment
Попробуйте это: ‹a href=etc›link‹/a› ‹script›jQuery('a').click();‹/script› и посмотрите, что произойдет. (Подсказка: ничего) - person scribu; 24.11.2009
comment
Ваш добавляет ОБРАБОТЧИК СОБЫТИЯ (СДЕЛАЙТЕ ЭТО, КОГДА Я НАЖИМАЮ), а не ТРИГГЕР события (СДЕЛАЙТЕ событие сейчас), сделайте его ‹a href=somewhere id=mylink›MyLink‹/a› ‹script› jQuery('#mylink').trigger ("щелчок"); ‹/скрипт› - person Mark Schultheiss; 24.11.2009
comment
ПРИМЕЧАНИЕ: мое где-то должно быть действительной http-ссылкой на то место, куда вы хотите перейти, например > stackoverflow.com/questions/1786377/ - person Mark Schultheiss; 24.11.2009
comment
.click() — без аргументов — это сокращение от .trigger('click'). Попробуйте оба варианта, если не уверены. - person scribu; 24.11.2009

Если я правильно понял ваш вопрос, у вас есть элемент a, которым вы не управляете, который имеет атрибут onclick, который возвращает false. Возврат false из обработчика onclick предотвращает переход по ссылке на связанную страницу. А ты этого не хочешь.

Вы можете сохранить функцию обработчика onclick, а затем удалить ее из элемента ссылки:

var $a = $('#my_special_link'); 
var onclickHandler = $a.attr('onclick');
$a.removeAttr('onclick');

Затем вызовите хранимую функцию обработчика в вашем пользовательском обработчике кликов:

$a.click(function() {
    // ...
    onclickHandler();
    // ...
});
person mtyaka    schedule 23.11.2009
comment
Да, я уже делаю это с помощью $el.bind('click', onClick); Не знаю, следует ли мне удалить атрибут onclick. - person scribu; 24.11.2009