7

次のHTMLがあるとします。

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

スパンをクリックすると、何らかのイベントがトリガーされるようにしたいと思います(たとえば、テキストを太字にする)。これは簡単です。

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

しかし、要素から離れてクリックすると、別のイベントをトリガーする必要があります(たとえば、テキストを通常の太さにするため)。どういうわけか、span要素の内側ではないクリックを検出する必要があります。これはblur()イベントと非常に似ていますが、非INPUT要素の場合です。このクリックがDIV要素内でのみ検出され、ページのBODY全体では検出されないかどうかは関係ありません。

次のように、非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

別の解決策は、クリックイベント内のイベントのターゲットを読み取ることです。この方法で実装する例を次に示します。

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

しかし、blur()のようなもっとエレガントな解決策があるのだろうかと思っていました。

4

6 に答える 6

4

私が調べたところ、stopPropagation関数が最も適切だと思います。例えば:

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

子アンカーがクリックされたときに親のonclickイベントが発生しないようにするにはどうすればよいですか?を参照してください。同様の質問について。

于 2011-12-29T04:50:22.103 に答える
3

最後の方法は、面倒な場合でも最適に機能するはずです。ここに少し改良があります:

$('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');
        }
    });
});

きれいではありませんが、動作するはずです。不要なバインドはなく、これは絶対確実である必要があります(誤検知などはありません)。

于 2010-01-13T21:27:24.513 に答える
1

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;
}
于 2010-01-13T21:25:29.337 に答える
1

スパンのクリックハンドラーからfalseを返すと、イベントがバブリングするのを防ぎ、divクリックハンドラーが実行されないようにします。

于 2010-01-13T21:26:04.037 に答える
0

プロパティを使用する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では機能しません。私はそれを自分でテストしていないので、そうかもしれません!

また、atabIndex-1、要素をクリックすることはできますが、キーボードでフォーカスを合わせることができないことを意味します。または0でフォーカス可能にする場合は、に変更できます。TabShift+Tab

于 2010-10-11T05:01:09.537 に答える
0
$(':not(span)').click(function(){
    //dostuff
})
于 2010-01-13T21:24:58.107 に答える