25

私はjQueryプラグインを作成し、pub/subシステムとして使用.onしています。.triggerただし、さまざまなシナリオで複数のイベントをトリガーしたいと思います。

.onこれは、メソッドのように1つの文字列として実行できますか?

ゴール:

$this.trigger("success next etc");    // doesn't work

現在の解決策:

$this
    .trigger("success")
    .trigger("next")
    .trigger("etc");                  // works, triggers all three events

助言がありますか?

4

4 に答える 4

34

JQuery自体は複数のイベントのトリガーをサポートしていませんが、カスタム拡張メソッドを作成できますtriggerAll

(function($) {
    $.fn.extend({
        triggerAll: function (events, params) {
            var el = this, i, evts = events.split(' ');
            for (i = 0; i < evts.length; i += 1) {
                el.trigger(evts[i], params);
            }
            return el;
        }
    });
})(jQuery);

そしてそれを次のように呼びます:

$this.triggerAll("success next etc");
于 2012-08-07T17:18:21.187 に答える
6

持っているものは問題ありません...コンマ区切りのリストを使用して複数のイベントをトリガーすることはできません。trigger()コンストラクターは、イベント名とオプションの追加パラメーターのみを受け取り、イベントハンドラーに渡します。

別の方法は、要素に関連付けられたすべてのイベントをトリガーすることですが、異なるシナリオで特定のイベントをトリガーする必要がある場合、これはニーズを満たさない可能性があります。

$.each($this.data('events'), function(k, v) {
    $this.trigger(k);
});​
于 2012-08-07T17:04:15.510 に答える
6

誰かが後でこの質問に遭遇した場合に備えて、カスタムjQuery関数を作成することでこれを解決しました。

$.fn.triggerMultiple    =   function(list){
    return this.each(function(){
        var $this = $(this); // cache target

        $.each(list.split(" "), function(k, v){ // split string and loop through params
            $this.trigger(v); // trigger each passed param
        });
    });
};

$this.triggerMultiple("success next etc"); // triggers each event
于 2012-08-07T17:15:39.857 に答える
0

元の.trigger()メソッドのプロトタイプを拡張できます。

(function($) {
  const _trigger = $.fn.trigger;
  $.fn.trigger = function(evtNames, data) {
    evtNames = evtNames.trim();
    if (/ /.test(evtNames)) {
      evtNames.split(/ +/).forEach(n => _trigger.call(this, n, data));
      return this;
    }
    return _trigger.apply(this, arguments);
  };
}(jQuery));


$("body").on({
  foo(e, data) { console.log(e, data); },
  bar(e, data) { console.log(e, data); },
  baz(e, data) { console.log(e, data); },
});


$("body").off("bar"); // Test: stop listening to "bar" EventName
$("body").trigger(" foo    bar baz ", [{data: "lorem"}]); // foo, baz
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

コードの説明


// Keep a reference to the original prototype
const _trigger = $.fn.trigger;

$.fn.trigger = function(evtNames, data) {

  // Remove leading and ending whitespaces 
  evtNames = evtNames.trim();

  // If the string has at least one whitespace
  if (/ /.test(evtNames)) {

    // Split names into Array (Treats multiple spaces as one)
    evtNames.split(/ +/)
    // Call the original .trigger() method for one eventName (and pass data)
      .forEach(n => _trigger.call(this, n, data));

    // End here.
    // Return this (Element) to maintain jQuery methods chainability for this override.
    return this;
  }

  // No whitespaces detected
  // Pass all arguments to the original .trigger() Method immediately.
  // The original method already returns this (Element), so we also need to 
  // return it here to maintain methods chainability when using this override. 
  return _trigger.apply(this, arguments);
};
于 2020-08-25T14:29:25.370 に答える