7

我正在尝试侦听自定义事件,但我想有效地“忽略”它是命名空间的事实,或者以某种方式侦听所有命名空间而不单独定义它们。

$('#test').on('custom', ...);

$('#test').trigger('custom.namespace1');
$('#test').trigger('custom.namespace2');

我希望能够做到这一点的原因是因为我有多个 ui 插件,当它们被隐藏/显示时会触发事件。这些事件主要在内部使用,但具有命名空间,因此它们不会相互冲突。但是,我也想知道何时隐藏特定的 ui 元素,独立于执行其他清理逻辑的源。

在上面的例子中,什么都不会发生,因为触发事件是命名空间的。我可以收听所有具有以下效果的名称空间custom.*吗?

小提琴演示了这个问题

谢谢

编辑

即使是这样的事情也是可取的,但仍然无法让它发挥作用

$('#test').on('custom.global', log);

$('#test').trigger('custom.global.namespace1');
$('#test').trigger('custom.global.namespace2');

小提琴

4

3 回答 3

1

尝试triggerAll代替trigger

(function($) {
    $.fn.triggerAll = function(topics, data, delimiter) {
        return this.each(function() {
            var $this = $(this), chain = [], t = '';
            delimiter = (delimiter || '.');
            // rebuild chain
            $.each(topics.split(delimiter), function(i,n) {
                t += (i == 0 ? '' : delimiter) + n;
                chain.push(t);
            });

            // append/prepend original topic?
            data = (data || []);
            data.push(topics);
            $.each(chain, function(i,t) {
                $this.trigger(t, data);
            });
        });
    };
})(jQuery);

当然,由于 jQuery 如何处理触发命名空间,触发“根”事件实际上会触发命名空间版本,因此要获得您期望的内容,您需要使用另一个字符作为分隔符,例如/,然后声明您的事件,例如:

var $o = $('#whatever');
// this will be triggered for all events starting with 'root'
$o.on('root', function () { console.log(Array.prototype.slice.call(arguments, 0)); });
// some arbitrary way to fire custom events
$o.on('click', function () {
    $o.triggerAll('root/custom1/subA', ['1st', '2nd'], '/');
    $o.triggerAll('root/custom2', [3, 4, 5], '/');
});

这个小提琴的例子

于 2013-02-20T22:36:43.643 回答
0

我担心唯一的方法是将它们全部列为 on 方法的第一个参数......

$('#test').on('custom.ns1 custom.ns2 ...', function(evt){});

这意味着插件更新时烦人的代码审查......

于 2012-09-25T20:17:47.313 回答
0

我刚遇到这个,这是我的解决方案。Javascript 是一种有趣的语言,事件只是字符串。为什么不事先定义您的事件,然后将它们动态添加到“全部”事件中?无需担心不同步。

你可以随心所欲地扩展它。注册小部件时,让它注册自己并将其附加到列表中。使用一个数组,然后myEvents.join(" ")生成所有这些。在应用程序引导上,执行我在下面执行的操作并将对象中的所有键添加到“全部”事件中。你想做什么都好。

PS。我使用的“Vent”示例来自:https ://github.com/reedspool/jquery-event-aggregator/blob/master/eventAggregator.jquery.js

var stand_in = {},
    $stan = $(stand_in),
    // Don't give Stan to anyone else, he's precious
    $empty = $(),
    trigger = function(name, ...args) {
      $stan.trigger.apply($stan, arguments);
      return $empty;
    },
    on = function(name, fn) {
      $stan.on(name, function(evt, obj) {
        // Shed the event object, who needs it?
        fn(obj);
      });

      return $empty;
    };
    
var Vent = {
  trigger: trigger,
  on: on
};
    
var events = {
  All: "",
  Custom1: "my1.event",
  Custom2: "my2.event"
}

for (var evt in events) {
	if (events.hasOwnProperty(evt) && evt !== 'All') {
    events.All += events[evt] + " ";
  }
}

Vent.on(events.Custom1, function () { alert(events.Custom1 + " trigger")});
Vent.on(events.All, function () { alert(events.All + " trigger")});

$("#btn").on('click', function () {
	Vent.trigger(events.Custom1);
});
$("#btn2").on('click', function () {
	Vent.trigger(events.Custom2);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id="btn">
Press Me
</button>
<button id="btn2">
Press Me 2
</button>

于 2016-08-26T19:48:30.233 回答