Как остановить распространение события из атрибута href привязки без использования onclick или onmousedown

Из-за ограничений, хотя я вообще этого избегаю, в определенной ситуации мне приходится использовать синтаксис javascript: в атрибуте href тега achor.

(ОБЪЯСНЕНИЕ: В моей CMS я использую редактор форматированного текста, чтобы позволить пользователю вносить изменения в текстовые элементы, включая ссылки. В некоторых случаях требуются специальные вызовы javascript:, и я полностью запретил onclick в функциях редактирования ссылок (чтобы упростить процесс для пользователя). Однако, когда одна из ссылок появляется в блоке, который реагирует на событие onclick, происходит двойное срабатывание)

Как это:

<a href="javascript:doSomething()"></a>

Моя проблема в том, что эта ссылка находится внутри контейнера, который уже реагирует на событие onclick. Поэтому я хотел передать объект события методу doSomething(), чтобы затем использовать jQuery.

event.stopPropagation()

метод.

Однако, к сожалению, кажется, что передача объекта события вдоль

<a href="javascript:doSomething(event)"></a>

вообще не работает. Safari ничего не скажет, в то время как Firefox сообщит ReferenceError: событие не определено

Я предполагаю, что это так, потому что href="" не является атрибутом, инициирующим сценарий (например, onclick). Проблема в том, что в этой ситуации я не смогу получить доступ к тегу, кроме того, что я уже делаю.

Поэтому мне либо нужно

1.) Способ передать объект события функции doSomething() из атрибута href.

or

2.) Способ остановить распространение события прямо в этом якоре (после его нажатия) другими способами.

Спасибо за любой конструктивный вклад!


person SquareCat    schedule 12.10.2012    source источник
comment
Почему бы просто не использовать jQuery для присоединения doSomething к обработчику событий click?   -  person ultranaut    schedule 12.10.2012
comment
Ситуация требует, чтобы это обрабатывалось исключительно тем, что возможно с использованием атрибута href.   -  person SquareCat    schedule 12.10.2012
comment
Если бы вы могли рассказать, почему вы должны использовать атрибут href, это может предложить возможные обходные пути.   -  person Programming Guy    schedule 12.10.2012
comment
Ты прав. Я отредактирую вопрос.   -  person SquareCat    schedule 12.10.2012
comment
Измените теги ‹a› с атрибутами href на теги ‹span› с атрибутами onclick, и ваша проблема будет решена.   -  person gmustudent    schedule 16.03.2013


Ответы (4)


Вы не можете остановить распространение события из атрибута href, потому что:

  1. Когда код href выполняется, это не событие. Он просто выполняет этот код, похожий на «взлом местоположения». Например, ввести javascript:doSomething() в адресную строку браузера.

  2. Код href выполняется после событий, возникающих в ссылке, включая всплывающие подсказки.

    Вы можете увидеть это поведение в этом jsFiddle. Обратите внимание, что все mouseup, mousedown и click срабатывают как для ссылки, так и для контейнера при нажатии на ссылку до выполнения кода href.

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


Но, если вы можете добавить к документу javascript, вы можете заблокировать href с помощью preventDefault().

Например:

  • jQuery до версии 1.7:

    $("#container a").bind ("mousedown mouseup click", function (e) {
        e.preventDefault();
    } );
    
  • jQuery 1.7 и более поздние версии:

    $("#container a").on ("mousedown mouseup click", function (e) {
        e.preventDefault();
    } );
    

    или лучше):

    $("#container").on ("mousedown mouseup click", "a", function (e) {
        e.preventDefault();
    } );
    


Вы можете увидеть эту последнюю версию в реальном времени на jsFiddle.

person Brock Adams    schedule 12.10.2012
comment
Спасибо тебе большое за это! У меня была такая же проблема. Превращение всех моих тегов ‹a› в теги ‹span› с кликами решило проблему! Спасибо еще раз! - person gmustudent; 16.03.2013
comment
@SgtPooki, вы правы, но, пожалуйста, прочитайте вопрос и комментарии к нему. В ОП конкретно указано: "The situation requires it to be handled purely by what is possible using the href attribute.". Но поскольку метод post-jQuery может помочь другим, я добавил его в этот ответ. - person Brock Adams; 04.09.2014

Если вы не можете изменить саму ссылку (использовать onclick), то ваш единственный вариант — изменить обработчик onclick контейнера.

Можете ли вы сделать что-то вроде

function containerClickHandler(e) {
  e = e || event;
  var el = e.target || e.srcElement;
  if (el.nodeName === 'A' && someOtherMatchChecks) {
       // eat event
  }
  else {
       // process event
  }
}
person Programming Guy    schedule 12.10.2012
comment
Это был бы вариант, но я не могу этого сделать, потому что мне пришлось бы адаптировать некоторый основной код из моей CMS только так, чтобы он подходил для одного случая. Но ваш подход вполне верный. Проголосовать. - person SquareCat; 12.10.2012

Ну, это старый вопрос, но в моем конкретном случае я нашел обходной путь, но он может применяться только к подмножеству ситуаций. У меня есть div с onclick. Но если щелкнуть внутри этого div, я не хочу, чтобы этот div onclick срабатывал. Вот что я делаю:

function myOnClick () {

  // loop over all <a>'s, and test if they are hovered over right now.
  var allLinks = document.links;
  var dont = 0;
  for (var i = 0, n = allLinks.length; i < n; i++) {
    // pure javascript test to see if element is hovered.
    if(allLinks[i].parentElement.querySelector(":hover") === allLinks[i]) {dont = 1; }
  };

  if(dont)return;

  // your stuff here, only fires when dont is false.

}

Я узнал о трюке с селектором запросов здесь: https://stackoverflow.com/a/14800287/2295722

person wessel    schedule 26.11.2013

Я не знаю, есть ли способ получить аргументы, если вы напишете свой javascript в атрибуте href. Но вы можете получить это следующим образом в onclick, но, как вы говорите, это не лучшая практика:

<a onclick="console.log(arguments)">your link</a>

в массиве аргументов вы получите свой объект события.

вот демо для вас:

http://jsfiddle.net/tEw5J/1/

person Sinan    schedule 12.10.2012
comment
Спасибо, но я не могу использовать onclick. К сожалению. - person SquareCat; 12.10.2012