Определить фоновый щелчок в jQuery - PullRequest
5 голосов
/ 14 января 2010

Скажите, что у меня есть следующий HTML:

<div>
  <span>span text</span> div text <span>some more text</span>
</div>

Я хочу сделать так, чтобы, когда я нажимал на интервал, он вызывал какое-то событие (например, чтобы сделать текст жирным), это просто:

$('span').click( ... )

Но теперь, когда я щелкаю по элементу, я хочу, чтобы другое событие сработало (например, чтобы текст стал нормальным). Мне нужно как-то обнаружить щелчок не внутри элемента span. Это очень похоже на событие blur (), но не для элементов INPUT. Я не против, если этот щелчок обнаружен только внутри элемента DIV, а не всего тела страницы, кстати.

Я попытался получить событие для запуска в элементах, отличных от SPAN, со следующим:

$('div').click( ... ) // triggers in the span element
$('div').not('span').click( ... ) // still triggers in the span element
$('div').add('span').click( ... ) // triggers first from span, then div

Другим решением было бы прочитать цель события внутри события click. Вот пример такой реализации:

$('div').click(function(e) {
  if (e.target.nodeName != "span")
     ...
});

Мне было интересно, есть ли более элегантное решение, такое как blur ().

Ответы [ 6 ]

4 голосов
/ 29 декабря 2011

Из того, что я исследовал, я думаю, что функция stopPropagation является наиболее подходящей.Например:

$("#something_clickable a").click(function(e) {
   e.stopPropagation();
})

См. Как предотвратить запуск события onclick родителя при нажатии дочерней привязки? для аналогичного вопроса.

2 голосов
/ 14 января 2010

Ваш последний метод должен работать лучше, даже если он грязный. Вот небольшое уточнение:

$('span').click(function() {
    var span = $(this);
    // Mark the span active somehow (you could use .data() instead)
    span.addClass('span-active');

    $('div').click(function(e) {
        // If the click was not inside the active span
        if(!$(e.target).hasClass('span-active')) {
            span.removeClass('span-active');
            // Remove the bind as it will be bound again on the next span click
            $('div').unbind('click');
        }
    });
});

Это не чисто, но должно работать. Нет ненужных привязок, и это должно быть надежно (без ложных срабатываний и т. Д.)

1 голос
/ 14 января 2010

Если вы вернете false из обработчика щелчков для промежутка, вы предотвратите всплывающее событие, что не позволит обработчику div щелкать.

1 голос
/ 14 января 2010

Я нашел решение этой проблемы до выпуска jQuery ...

Определите, был ли щелкнут любой другой внешний элемент с помощью JavaScript

document.onclick = function() {
  if(clickedOutsideElement('divTest'))
    alert('Outside the element!');
  else
    alert('Inside the element!');
}

function clickedOutsideElement(elemId) {
  var theElem = getEventTarget(window.event);

  while(theElem != null) {
    if(theElem.id == elemId)
      return false;

    theElem = theElem.offsetParent;
  }

  return true;
}

function getEventTarget(evt) {
  var targ = (evt.target) ? evt.target : evt.srcElement;

  if(targ != null) {
    if(targ.nodeType == 3)
      targ = targ.parentNode;
  }

  return targ;
}
0 голосов
/ 11 октября 2010

Используя свойство tabIndex, вы можете сделать фокусируемым произвольные элементы:

var node = document.createElement("span");
node.tabIndex = -1;

node.addEventListener("focus", function () {
    // clicked the element...
}, true);

node.addEventListener("blur", function () {
    // clicked away from the element...
}, true);

К сожалению, этот пример, вероятно, не будет работать в IE.Я сам не проверял, так что это может быть!

Кроме того, tabIndex из -1 означает, что на элемент можно щелкнуть, но его нельзя сфокусировать с клавиатуры.Вы можете изменить его на 0, если хотите, чтобы он был фокусируемым с Tab или Shift+Tab.

0 голосов
/ 14 января 2010
$(':not(span)').click(function(){
    //dostuff
})
...