为什么在我的骨干应用中多次触发点击事件
Why is the click event triggered several times in my Backbone app?
我正在制作一个Backbone.js应用程序,它包括一个索引视图和几个基于id的子视图。所有视图都绑定了鼠标按下和鼠标向上事件。但是每次我从一个子视图转到索引视图,然后再次转到任何一个子视图时,当前子视图中的鼠标按下和鼠标向上事件都会再次触发,这意味着当我单击子视图时,会触发几个连续的鼠标按下事件,然后触发几个连续的鼠标向上事件。
在查看了我的代码后,我终于发现是路由器导致了这个问题。我的部分代码如下:
routes: {
"": "index",
"category/:id": "hashcategory"
},
initialize: function(options){
this._categories = new CategoriesCollection();
this._index = new CategoriesView({collection: this._categories});
},
index: function(){
this._categories.fetch();
},
hashcategory: function(id){
this._todos = new TodosCollection();
this._subtodolist = new TodosView({ collection: this._todos,
id: id
});
this._todos.fetch();
}
如您所见,我在路由器的 initialize
方法中创建索引集合和视图,但我在路由器对应的路由函数中创建子视图集合和视图。我尝试将索引集合和视图放在index
函数中,索引视图中的单击事件的行为方式与子视图相同。所以我认为这就是为什么鼠标按下和鼠标向上会被触发几次的原因。
但问题是,我必须使用 id
作为发送到子视图的参数之一。所以我无法在initialize
方法中创建子视图。更重要的是,我已经看到了其他人基于 Backbone 的项目,其中一些还在相应的路由函数中创建子集合和视图,但他们的应用程序运行良好。所以我不知道我问题的根源是什么。有人可以给我一些想法吗?
听起来您遇到了委托问题,因为:
所有子视图都使用相同的
<div>
元素
主干视图在其el
上使用jQuery的delegate
绑定到事件。如果视图使用 <div>
作为其el
,然后通过替换包含的 HTML 对另一个视图使用相同的<div>
,则最终将通过两个不同的delegate
调用将两个视图附加到该<div>
。如果再次交换视图,您将有三个视图通过三个delegate
接收事件。
例如,假设我们有这个 HTML:
<div id="view-goes-here"></div>
以及这些观点:
var V0 = Backbone.View.extend({
events: { 'click button': 'do_things' },
render: function() { this.$el.html('<button>V0 Button</button>'); return this },
do_things: function() { console.log('V0 clicked') }
});
var V1 = Backbone.View.extend({
events: { 'click button': 'do_things' },
render: function() { this.$el.html('<button>V1 Button</button>'); return this },
do_things: function() { console.log(V1 clicked') }
});
我们用这样的东西在它们之间切换(当然which
从 0 开始(:
which = (which + 1) % 2;
var v = which == 0
? new V0({el: $('#view-goes-here') })
: new V1({el: $('#view-goes-here') });
v.render();
然后,您将遇到我上面描述的多代表问题,并且此行为似乎与您描述的症状相匹配。
下面是一个便于查看的演示:http://jsfiddle.net/ambiguous/AtvWJ/
解决此问题的一种快速简便的方法是在呈现新视图之前对当前视图调用undelegateEvents
:
which = (which + 1) % 2;
if(current)
current.undelegateEvents(); // This detaches the `delegate` on #view-goes-here
current = which == 0
? new V0({el: $('#view-goes-here') })
: new V1({el: $('#view-goes-here') });
current.render();
演示:http://jsfiddle.net/ambiguous/HazzN/
更好的方法是为每个视图提供自己独特的el
,以便在替换 HTML 时所有内容(包括delegate
绑定(都会消失。您最终可能会得到很多<div><div>real stuff</div></div>
结构,但这不值得担心。
- 为什么我的点击事件没有使用 react js 触发
- 为什么不'我的窗口滚动事件根本没有启动.其他答案没有解决问题
- 如何使用我的Jquery代码创建委托事件侦听器
- 为什么动态加载的事件在我的代码中不能正常工作
- onbeforeunload事件在我的代码中没有触发,但其他示例可以工作
- 为什么我的on change事件在ie9上返回空
- 在我的JavaScript模块中绑定一个点击事件
- 如何在javascript中调用onclick事件?我没有'我不想在我的HTML页面中使用任何事件
- 鼠标事件,我的代码出了什么问题
- 我可以让我的网站的内容可编辑区域对安卓股票浏览器上的触摸事件更敏感吗
- 为什么我的onchange事件发生在页面加载时,而不是在触发时
- 为什么我的Jquery.ajax调用会触发错误事件
- 为什么点击或更改事件都没有触发我的函数
- 为什么我从 JSLint 获得从事件调用的函数的“超出范围”
- 将 OnClick 事件附加到我的标签 - JavaScript.亚德夫.
- 为什么IE浏览器不喜欢我的点击事件
- 为什么我的点击事件没有触发
- 我的链接按钮的OnClick事件永远不会被触发
- 将我的nextPage()函数编写为全局函数,以便onclick事件可以访问它
- 为什么我的javascript鼠标事件没有启动