Захват всех событий клика ‹a›

Я думаю добавить функцию javascript для захвата всех событий кликов <a> внутри html-страницы.

Поэтому я добавляю глобальную функцию, которая управляет всеми событиями кликов <a>, но не добавляю onclick к каждому (ни используя .onclick=, ни attachEvent(onclick...), ни встроенный onclick=). Я оставлю каждый <a> таким же простым, как <a href="someurl"> в HTML, не касаясь их.

Я попробовал window.onclick = function (e) {...}, но он фиксирует только все клики. Как мне указать только клики на <a> и извлечь ссылки внутри <a>, которые нажимаются?

Ограничение: я не хочу использовать какие-либо дополнительные библиотеки, такие как jQuery, только ванильный javascript.


person user1589188    schedule 23.09.2012    source источник
comment
Извините, что отредактировал. Отсутствовали все теги html...   -  person user1589188    schedule 23.09.2012
comment
Ограничение: я не хочу использовать какие-либо дополнительные библиотеки, такие как jQuery, только ванильный javascript. - Я люблю тебя официально.   -  person Gogol    schedule 13.11.2018


Ответы (10)


Вы можете обрабатывать все клики, используя window.onclick, а затем фильтровать, используя event.target.

Пример, как вы просили:

<html>
<head>
<script type="text/javascript">
window.onclick = function(e) { alert(e.target);};
</script>
</head>
<body>
<a href="http://google.com">google</a>
<a href="http://yahoo.com">yahoo</a>
<a href="http://facebook.com">facebook</a>
</body>
</html>
person Artur Udod    schedule 23.09.2012
comment
Да, пожалуйста. Я выберу вас, если у вас есть пример кода, как фильтровать и извлекать href - person user1589188; 23.09.2012
comment
Спасибо! Ну, в итоге это комбинация вашего e.target и xdazz e.target.localName. Но так как ты опередил xdazz на несколько минут, я выберу тебя - person user1589188; 23.09.2012
comment
! это будет обрабатывать и клики по текстовому полю - person Vasil Valchev; 22.02.2016
comment
Это позволит получить больше, чем просто ‹a› кликов. Подход @Kooilnc ограничивает количество кликов ссылками. - person William; 16.02.2021
comment
@William, как я уже сказал, вам придется фильтровать event.target. - person Artur Udod; 02.07.2021
comment
@ArturUdod ОП спрашивает; «Как мне указать только клики на ‹a›», представленный код этого не делает, и люди могут не знать, как фильтровать event.target, поэтому выделение ответа Kooilnc помогает проиллюстрировать это. - person William; 02.07.2021

Используйте делегирование событий:

document.addEventListener(`click`, e => {
  const origin = e.target.closest("a");
  
  if (origin) {
    console.clear();
    console.log(`You clicked ${origin.href}`);
  }
});
<div>
  <a href="#l1">some link</a>
  <div><a href="#l2"><div><i>some other (nested) link</i></div></a></div>
</div>

[редактировать 20.08.2020] Модернизировано

person KooiInc    schedule 23.09.2012
comment
Спасибо! Кажется, все хорошо, за исключением того, что я не могу найти nodeName. from не имеет свойства с именем nodeName - person user1589188; 23.09.2012
comment
В этом случае используйте /^a$/i.test(from.tagName) или [см. отредактированный ответ] - person KooiInc; 23.09.2012
comment
Благодарю вас! Это сработало! Но извините, мне пришлось выбрать другого пользователя. Надеюсь, ваш код будет полезен и другим! - person user1589188; 23.09.2012

​window.onclick = function (e) {
    if (e.target.localName == 'a') {
        console.log('a tag clicked!');
    }
}​

Рабочая демонстрация.

person xdazz    schedule 23.09.2012
comment
Спасибо! e.target.localName отлично работает! Я могу использовать это с e.target, чтобы получить ссылку! - person user1589188; 23.09.2012

ваша идея делегировать событие окну, а затем проверить, является ли «event.target» ссылкой, является одним из способов (лучше будет document.body). Проблема здесь в том, что это не сработает, если вы нажмете на дочерний узел вашего элемента. Считать:

<a href="#"><b>I am bold</b></a>

target будет элементом <b>, а не ссылкой. Это означает, что проверка e.target не будет работать. Таким образом, вам придется просмотреть все дерево dom, чтобы проверить, является ли выбранный элемент потомком элемента <a>.

Другой метод, который требует меньше вычислений для каждого клика, но требует больше затрат на инициализацию, — это получить все теги <a> и прикрепить ваше событие в цикле:

var links = Array.prototype.slice.call(
    document.getElementsByTagName('a')
);

var count = links.length;
for(var i = 0; i < count; i++) {
    links[i].addEventListener('click', function(e) {
        //your code here
    });
}

(PS: почему я преобразовываю HTMLCollection в массив? вот ответ.< /а>)

person Roman    schedule 23.09.2012
comment
Очень информативно! Это показывает ваши подробные знания по этому вопросу! Но это больше, чем я могу проглотить. Я проверил видео, это действительно заранее для меня. Но наверняка ваши знания пригодятся еще кому-нибудь! - person user1589188; 23.09.2012

Вы должны принять во внимание, что ссылка может быть вложена в другие элементы, и вы хотите пройти по дереву обратно к элементу «a». Это работает для меня:

window.onclick = function(e) {
  var node = e.target;
  while (node != undefined && node.localName != 'a') {
    node = node.parentNode;
  }
  if (node != undefined) {
    console.log(node.href);
    /* Your link handler here */
    return false;  // stop handling the click
  } else {
    return true;  // handle other clicks
  }
}

См., например. https://jsfiddle.net/hnmdijkema/nn5akf3b/6/

person Hans Dijkema    schedule 30.09.2016

Вы также можете попробовать использовать это:

var forEach = Array.prototype.forEach;
var links = document.getElementsByTagName('a');
forEach.call(links, function (link) {
    link.onclick = function () {
        console.log('Clicked');
    }

});

Работает, только что проверил!

Рабочая демонстрация: http://jsfiddle.net/CR7Sz/

Где-то в комментариях вы упомянули, что хотите получить значение «href», которое вы можете сделать с помощью этого:

var forEach = Array.prototype.forEach;
var links = document.getElementsByTagName('a');
forEach.call(links, function (link) {
    link.onclick = function () {
        console.log(link.href); //use link.href for the value
    }

});

Демонстрация: http://jsfiddle.net/CR7Sz/1/

person Akshat Mittal    schedule 23.09.2012

Попробуйте jQuery и

$('a').click(function(event) { *your code here* });

В этой функции вы можете извлечь значение href следующим образом:

$(this).attr('href')
person FLCL    schedule 23.09.2012
comment
извините, нет, никакой дополнительной библиотеки, только IE9 или Firefox 15 - person user1589188; 23.09.2012

Некоторые принятые ответы не работают с вложенными элементами, такими как: <a href="..."><font><u>link</u></font></a>

Для большинства случаев есть базовое решение: ```

var links = document.getElementsByTagName('a');
for(var i in links)
{
    links[i].onclick = function(e){
        e.preventDefault();
        var href = this.href;
        // ... do what you need here.
    }
}
person MichałKraków    schedule 07.01.2019

Я думаю, этот простой код будет работать с jquery.

 $("a").click(function(){
    alert($(this).attr('href'));
});

Без JQuery:

window.onclick = function(e) { 
if(e.target.localName=='a')
    alert(e.target);
};

Вышеприведенное даст тот же результат.

person Vishal Srinivasan    schedule 06.03.2017
comment
Автор вопроса говорит в комментариях, что не хочет использовать никакие библиотеки, только ванильный javascript. Я добавлю эти комментарии к вопросу, чтобы он был более ясным. - person morten.c; 06.03.2017
comment
Привет, Мортен. Как вы и просили, я отредактировал код для простого javascript. :) - person Vishal Srinivasan; 15.03.2017

Очень простой :

document.getElementById("YOUR_ID").onclick = function (e) {...} 

Селектор — это то, что вы хотите выбрать, поэтому, скажем, у вас есть кнопка с именем

<a href="#" id="button1">Button1</a>

Код для захвата:

document.getElementById("button1").onclick = function (e) { alert('button1 clicked'); }

Надеюсь, это поможет.

person Kivylius    schedule 23.09.2012
comment
Спасибо, но извините, я не хочу вручную добавлять onclick к каждому отдельному идентификатору. Мне нужна глобальная функция, которая уже фиксирует все, а затем я делаю фильтрацию внутри - person user1589188; 23.09.2012