12

親はどのようにしてカスタムイベントを起動して子供/兄弟に通知できますか?例えば:

<div id="div1">
   <div id="div2"></div>
</div>

div2にはaddEventListener('customEvent2'、doSth)があり、div1はカスタムイベント(customEvnet2)を起動します。ただし、これによってdiv2の「doSth」関数がトリガーされることはありません。

サンプルコード: http: //jsfiddle.net/r4tcT/2/

「div1triggercustomEvent2」ボタンは機能しません

そのため、親がカスタムイベント(dispatchEvent [IE9] / fireEvent [IE9-] / trigger [jQuery])を起動すると、子はイベントをキャプチャできません。

回避策はありますか?

4

4 に答える 4

6

あなたが話している違いは、「キャプチャ」イベントモデルと「バブリング」イベントモデルのどちらかです。jQueryのトリガーはBubbleモデルで動作します。これはおそらく、これがよりサポートされているイベントモデルであるためです。主にInternetExplorerのおかげです。div2バブルモデルは、要素の親を介して後方に移動するだけです...これが、から発生したときにイベントがトリガーされない理由です。これは、div1常にバブルが発生し、ダウンしないためです。

これまでネイティブ関数でカスタムイベントを試したことはありませんが、最近のほとんどのブラウザーでは、イベントリスナーを設定するときに使用するモデルのタイプを決定できます。

addEventListener (type, listener[, useCapture])

https://developer.mozilla.org/en-US/docs/DOM/element.addEventListener

基本的trueに、最後の引数として使用する場合、イベントリスナーはキャプチャフェーズ(イベントがDOMツリーを下るとき)でトリガーする必要があります。falseに設定すると、イベントは、DOMツリーを上に移動するときに発生するバブリングフェーズでトリガーされます。

これはここで議論されています:

イベントキャプチャとイベントバブリング

これが特注のイベントで機能するかどうかを言ったように、私にはわかりません。おそらく古いブラウザではサポートが不足しているため、jQueryではこれを実行できないと確信しています(現時点では) 。

修正

上で推測したものが機能しないようです。「キャプチャ」という用語のおかげで、ユーザー入力のキャプチャについて考えるようになりました。特注のイベントが含まれる場合、新しい種類のユーザー入力を定義する方法はありません。それを念頭に置いて、このクイックjQueryプラグインをまとめました...大まかにテストされただけですが、ロジックは健全である必要があります-それが役立つことを願っています:

/**
 * unbubble v0.2
 *
 * trigger an event down through the children of a collection, 
 * rather than up through it's parents
 *
 *  @update 2013/03/18 - fixed the problem of triggering bubble phase each
 *    step down the element tree as pointed out by @vine.
 */
$.fn.unbubble = function( eventNames ){
  var names = eventNames.split(' '), 
      non = names.length, 
      args = Array.prototype.slice.call(arguments);
  /// our own trigger function designed to bubble down... not up!
  var trigger = function(){
    var i, events, elm = $(this);
    /// make sure we can read the events array
    if ( $._data ) {
      /// make sure events is defined
      if ( (events = $._data(this, 'events')) ) {
        /// do a quick check, saves firing trigger on every element found
        for ( i=0; i<non; i++ ) {
          /// make sure our eventName appears in the event list
          if ( names[i] && ( names[i] in events ) ) {
            /// trigger the standard jQuery trigger function
            elm.triggerHandler.apply(elm, args);
            /// escape as trigger should fire for multiple names
            break;
          }
        }
      }
    }
    /// if we can't access the events array, just trigger and hope
    else {
      /// trigger the standard jQuery trigger function
      elm.triggerHandler.apply(elm, args);
    }
    /// trigger for all the children, and on, and on...
    elm.children().each(trigger);
  };
  /// foreach element trigger now...
  this.each(trigger);
}

/**
 * Example usage
 */
$(function(){
  /// bind our event as usual
  $('.div2').bind('customEvent', function(){
    alert('I should trigger!');
  });
  /// rather than use trigger, fire with unbubble
  $('#div1').unbubble( 'customEvent' );
});
于 2012-09-19T22:57:02.040 に答える
1

pebblの答えは良いですが、欠点があります。キャプチャフェーズは、ドキュメントから関連する要素までのイ​​ベントの通常のトリガーによって何らかの形でシミュレートされます。ただし、問題は、任意の要素で標準のjQueryトリガー関数を呼び出すと、その直後にその要素から始まるバブリングフェーズが続くことです。したがって、彼は要素のコレクションから直接イベントデータにアクセスし、標準のトリガー関数を使用せずに直接呼び出すことができると信じています。

var JQ_LT_17 = parseFloat($.fn.jquery) < 1.7;

function getEventsData(element) {
        return JQ_LT_17 ? $(element).data('events') : $._data(element).events;
}

jQuery.bindから借用したコードスニペット-最初のライブラリv0.1VladimirZhuravlev

于 2012-09-24T07:25:21.037 に答える
0

私はコードで少し遊んだことがあります、そしてこれが私が今持っているものです。それはハックですが、おそらくそれはあなたの問題を解決するのに役立つかもしれませんか?

于 2012-09-19T23:01:12.540 に答える
0

customEvent2にバインドされているだけdiv2です。でトリガーしようとしてdiv1も、そのイベントはに存在しないため、何も起こりませんdiv1

起動する場合customEvent2は、実際にバインドされている要素(またはその子)でトリガーする必要があります。

于 2012-09-19T22:52:14.773 に答える