绑定到自定义jquery事件的所有命名空间

时间:2012-09-25 20:02:56

标签: jquery

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

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

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

我希望能够这样做的原因是因为我有多个ui插件可以在隐藏/显示事件时触发事件。这些事件主要在内部使用,但是命名空间,因此它们不会相互冲突。但是,我还想知道隐藏特定ui元素的时间,与其源无关,以执行其他清理逻辑。

在上面的示例中,由于触发器事件是命名空间,因此不会发生任何事情。我是否可以使用custom.*

的效果来监听所有名称空间

Fiddle demonstrating the problem

由于

修改

即便是类似的东西也是可取的,但仍无法让它发挥作用

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

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

Fiddle

3 个答案:

答案 0 :(得分: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处理触发命名空间的方式,触发“root”事件实际上会触发命名空间版本,所以要获得你期望的,你需要使用另一个字符作为分隔符,如/,然后声明你的事件:

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], '/');
});

示例in this fiddle

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

你可以随意扩展它。注册窗口小部件时,让它自己注册并将其附加到列表中。使用数组,然后执行myEvents.join(" ")生成所有数组。在app bootstrap上,执行下面的操作,将对象中的所有键添加到“all”事件中。无论你想做什么都很好。

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>