Как я могу смоделировать щелчок по тегу привязки? - PullRequest
45 голосов
/ 14 сентября 2009

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

Кажется, есть метод "[click ()] [3]" для DOM-объекта привязки, но не все браузеры поддерживают это. Firefox выдает эту ошибку:

Ошибка: anchorObj.click не является функцией

Это также странно работает в Opera 10 и Konqueror, вызывая бесконечные щелчки, когда он вызывается внутри обработчика onclick окружающего div. Я думаю, что только IE8 работает с ним нормально. Во всяком случае, я не хочу, потому что основные браузеры имеют проблемы с этим.

Я нашел это альтернативное решение для Firefox на форумах Mozilla:

var evt = document.createEvent("MouseEvents"); 
evt.initMouseEvent("click", true, true, window, 
    0, 0, 0, 0, 0, false, false, false, false, 0, null); 
anchorObj.dispatchEvent(evt); 

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

Я не могу использовать location.href = anchorObj.href; потому что он не обрабатывает «целевой» атрибут. Я могу сделать жесткое кодирование, основываясь на значении цели, но я бы тоже хотел этого избежать.

Есть предложение перейти на JQuery, но я не уверен, насколько хорошо он обрабатывает целевое свойство, так как раньше я с ним не работал.

Ответы [ 5 ]

63 голосов
/ 14 сентября 2009

Вот полный тестовый пример, который имитирует событие click, вызывает все подключенные обработчики (как бы они ни были присоединены), поддерживает атрибут "target" ("srcElement" в IE), пузыри, как обычное событие, и подражает IE в предотвращении рекурсии. Протестировано в FF 2, Chrome 2.0, Opera 9.10 и, конечно, IE (6):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function fakeClick(event, anchorObj) {
  if (anchorObj.click) {
    anchorObj.click()
  } else if(document.createEvent) {
    if(event.target !== anchorObj) {
      var evt = document.createEvent("MouseEvents"); 
      evt.initMouseEvent("click", true, true, window, 
          0, 0, 0, 0, 0, false, false, false, false, 0, null); 
      var allowDefault = anchorObj.dispatchEvent(evt);
      // you can check allowDefault for false to see if
      // any handler called evt.preventDefault().
      // Firefox will *not* redirect to anchorObj.href
      // for you. However every other browser will.
    }
  }
}
</script>
</head>
<body>

<div onclick="alert('Container clicked')">
  <a id="link" href="#" onclick="alert((event.target || event.srcElement).innerHTML)">Normal link</a>
</div>

<button type="button" onclick="fakeClick(event, document.getElementById('link'))">
  Fake Click on Normal Link
</button>

<br /><br />

<div onclick="alert('Container clicked')">
    <div onclick="fakeClick(event, this.getElementsByTagName('a')[0])"><a id="link2" href="#" onclick="alert('foo')">Embedded Link</a></div>
</div>

<button type="button" onclick="fakeClick(event, document.getElementById('link2'))">Fake Click on Embedded Link</button>

</body>
</html>

Демо здесь.

Он позволяет избежать рекурсии в браузерах, отличных от IE, путем проверки объекта события, инициирующего симулированный щелчок, путем проверки атрибута события target (который остается неизменным при распространении ).

Очевидно, что IE делает это внутренне, удерживая ссылку на свой глобальный event объект . Уровень DOM 2 не определяет такую ​​глобальную переменную, поэтому симулятор должен передать свою локальную копию event.

11 голосов
/ 14 сентября 2009

Цитируется из https://developer.mozilla.org/en/DOM/element.click

Метод click предназначен для использования с элементами INPUT типа button, checkbox, radio, reset или submit. Gecko не реализует метод click для других элементов, которые могут реагировать на щелчки мышью, такие как ссылки (элементы A), и не обязательно запускает событие click других элементов.

Не-Gecko DOM могут вести себя по-разному.

К сожалению, похоже, что вы уже нашли лучшее решение своей проблемы.

В качестве примечания, я согласен, что ваше решение кажется не идеальным, но если вы инкапсулируете функциональность в методе (во многом как в JQuery), это не так уж плохо.

11 голосов
/ 14 сентября 2009

хорошо, вы можете очень быстро протестировать отправку кликов через jQuery, вот так

$('#link-id').click();

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

$('#link-id').click( function( event, anchor )
{
  window.open( anchor.href, anchor.target, '' );
  event.preventDefault();
  return false;
});
6 голосов
/ 11 апреля 2017

Существует более простой способ добиться этого,

HTML

<a href="https://getbootstrap.com/" id="fooLinkID" target="_blank">Bootstrap is life !</a>

JavaScript

// Simulating click after 3 seconds
setTimeout(function(){
  document.getElementById('fooLinkID').click();
}, 3 * 1000);

Использование простого javascript для имитации клика и адресации целевого свойства.

Вы можете проверить рабочий пример здесь jsFiddle .

0 голосов
/ 12 июня 2018

Ни одно из приведенных выше решений не направлено на общее намерение первоначального запроса. Что если мы не знаем идентификатор якоря? Что если у него нет идентификатора? Что если у него даже нет параметра href (например, значок «предыдущий / следующий» в карусели)? Что если мы хотим применить действие к нескольким якорям с разными моделями в независимой манере? Вот пример, который делает что-то вместо щелчка, а затем имитирует щелчок (для любого якоря или другого тега):

var clicker = null;
$('a').click(function(e){ 
    clicker=$(this); // capture the clicked dom object
    /* ... do something ... */
    e.preventDefault(); // prevent original click action
});
clicker[0].click(); // this repeats the original click. [0] is necessary.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...