This jsFiddle演示了我在说什么。基本上,我将一些元素绑定到自定义事件,然后使用
调用触发器$('*').trigger('myevent', args)
我这样做是因为我将有一些绑定到此事件的元素,但我不知道它们将会是什么,我想尽可能地解耦这些代码。调用$('*').trigger
或者不是那么昂贵,这是非常昂贵的,因为它只会触发绑定到该事件的元素吗?
换句话说,这段代码是否遍历页面上的每个元素,以查看它是否附加到此事件,或者它是否知道哪些元素只是触发它们?如果是前者,是否有更好的解决方案?
答案 0 :(得分:6)
更好的解决方案是绑定和触发文档中的事件,因为它只是一个DOM元素:
$(document).bind('myevent', function(e) {});
$(document).trigger('myevent');
现在最终听起来更好的解决方案就是使用事件委派:
$(document).delegate('.my-delegation-selector', 'myevent', function(e) {
});
从http://api.jquery.com/delegate/
看一下这个例子<!DOCTYPE html>
<html>
<head>
<style>
p { color:red; }
span { color:blue; }
</style>
<script src="http://code.jquery.com/jquery-1.5.js"></script>
</head>
<body>
<p>Has an attached custom event.</p>
<button>Trigger custom event</button>
<span style="display:none;"></span>
<script>
$("body").delegate("p", "myCustomEvent", function(e, myName, myValue){
$(this).text("Hi there!");
$("span").stop().css("opacity", 1)
.text("myName = " + myName)
.fadeIn(30).fadeOut(1000);
});
$("button").click(function () {
$("p").trigger("myCustomEvent");
});
</script>
</body>
</html>
答案 1 :(得分:2)
你有没有想过pubsub?简单的东西。
(function() {
var $obj = $(window);
window.pub = function(ev, data) {
$obj.trigger(ev, data);
};
window.sub = function(ev, f) {
$obj.bind(ev, f);
};
})();
或删除jQuery依赖
(function() {
var $obj = {},
undefined;
window.pub = function(ev, data) {
if ($obj[ev] === undefined) {
return false;
}
for (var i = 0, len = $obj[ev].length; i < len; i++) {
$obj[ev][i](data);
}
};
window.sub = function(ev, f) {
if ($obj[ev] === undefined) {
$obj[ev] = [];
}
$obj[ev].push(f);
};
})();
amplify.subscribe和Backbone.Events都有特定的对象。您甚至可以找到具有类似对象的其他库。甚至还有库PubSub.js。
示例:
$("table.sort th").click(function(e) {
...
window.pub("click.sortHeader", e);
});
...
$.fn.pagify = function(json) {
var table = $(this);
...
//enter code here
window.sub("click.sortHeader", function() {
// handle table sorting.
// adjust table pagifying plugin accordingly.
});
};
一般来说,pub
为trigger
而sub
为bind
。在这个特定的例子中,我们有两个独立的插件。他们不知道他们是在同一页面还是在说话。但是由于排序“打破”了我们表上的分页插件,我们对排序“事件”进行了订阅以修复我们的分页。
其他人可以提出一个更好的例子。它基本上只是一种消息传递方式,而不对消息提供者或接收者是否存在做出任何假设。
答案 2 :(得分:0)
查看jquery源代码。当您在jQuery上触发事件时,它会检查有效的节点
// don't do events on text and comment nodes
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
return undefined;
}
稍后检查实际dom对象上的有效处理程序
// Trigger the event, it is assumed that "handle" is a function
var handle = jQuery._data( elem, "handle" );
if ( handle ) {
handle.apply( elem, data );
}
我认为真正的问题是使用$('*')选择器。尝试另一种建议的问题解决方案