events: {
"click span.cpm-right": "collect",
},
initialize: function (attrs) {
this.tabs();//但是我想把这个操作绑定到$el中
},
tabs:function() {//当页面载入时,这个执行
$('.cpm-tabs li').each(function(index){
if($(this).hasClass('on')){
$('.tabs').hide();
$('.tabs:eq('+index+')').show();
}
})
$('.cpm-tabs li').on('click',function(){
var index=$(this).index();
$('.tabs').hide();
$(this).addClass('on').siblings('li').removeClass('on');
$('.tabs:eq('+index+')').show();
})
},
但是我想把这个操作tabs()绑定到$el中;(可能是干扰了大家,实际想问的的代码如下:)
events: {
"click span.cpm-right": "collect",
},
broadcast:function(){
//存在问题:浏览器返回再进来,定时器累加,轮播就乱了
//就是想把他绑定在body里,然后$('body').off()
$(".cpm-broadcast li:eq(0)").clone(true).appendTo($(".cpm-broadcast"));
var liHeight = $(".cpm-swiper").outerHeight();
var index = 0;
function next() {
index++;
$(".cpm-broadcast").animate({
top: -index * liHeight
},400,function(){
if(index == $(".cpm-broadcast li").length -1) {
$(".cpm-broadcast").css({top:0});
index = 0;
}
})
console.log('autoTimer')
}
//自动轮播
this.autoTimer = setInterval(next,3000);
},
render: function (e) {
this.$el.html(this.template(this.model.toJSON()));
this.broadcast();//这里怎么绑定
return this;
},
浏览器返回再进来,定时器累加,轮播就乱了,就是想把他绑定在body里,然后$('body').off(),不知道怎么实现比较好
问题更新后回答
你的某个视图模块
define(function(require, exports, module){
var Backbone = require('backbone');
var CustomView = Backbone.View.extend({
events: {},
boradcast: function(){
var next = function(){};
// 万恶的定时器,
this.autoTimer = setInterval(next,3000);
}
});
module.exports = new CustomView(); // 这样返回一个单例视图
});
页面调用模块时候
var Router = Backbone.Router.extend({
routes: {
'cutprice': 'cutprice'
},
cutprice: function(){
require(['module/customView'], function(customView){
// 这里不用再实例化了,customView被第一次require的时候,就已经实例化过
});
}
});
到这里为止,你的轮播定时器就能正常运作,但这里有2个问题
当离开页面后,其实定时器也在工作,白白性能开销
由于是单例视图,如果你在不恰当的时机提早require了(比如el选择器的目标元素不在Document上),会导致实例化失败,然后一直失败下去
最佳实践
Backbone.Router仅仅是一个路由,并没有页面功能。
对于这种需求,最好封装一个PageManager,每次路由调用,由PageManager来实例化新的视图和销毁旧视图。
原回答
Backbone.View中,events里面标记的事件,默认就绑定在view.el上。
TabView是Backbone.View的拓展,视图里面通过events标记的事件,都会在视图被销毁的时候自动解绑,所有事件默认是绑定在视图的el上。
像你评论所说的将事件绑定在body上便于统一销毁,按照Backbone的世界来玩,是不需要关心事件销毁的。
https://jsfiddle.net/qq286735628/qbgzv3h0/2/
激动,好久没看到关于 Backbone 的提问了。View 拥有一个 events
属性,就如楼主的 events 一样,会在 View 初始化的时候自动委托 el
元素绑定各种事件。比如楼主的 events
实际上可以转换为如下的代码:
// 为了说明方便把 `events` 的事件写在 `initialize` 中
initialize: function() {
// events 的行为会为处理方法绑定 `this` 指针为当前的 View
// 并为传入的 `event` 增加一个 `currentTarget` 作为本应指向
// 被单击的元素。
this.$el.on('click', 'span.cpm-right', collect.bind(this));
}
更详细的,可以查看 Backbone#View
按楼主的问题,可以把 tabs()
写入 events 中,大概更新后的源码应该如下
events: {
'click span.cpm-right': 'collect',
'click .cpm-tabs li': 'tab'
},
initialize: function() {
$('.cpm-tabs li').each(function(idx) {
if ($(this).hasClass('on')) {
$('.tabs').hide().eq(idx).show();
}
});
},
tab: function(e) {
var $tab = $(e.currentTarget),
idx = $tab.index();
$('.tabs').hide();
$tab.addClass('on').siblings('li').removeClass('on');
$tabs.eq(idx).show();
}