jQuery气泡效果迁移至Backbone遇bubble未定义问题求助
解决Backbone视图中气泡效果的「bubble未定义」错误
看起来你在把原生气泡动画迁移到Backbone视图时,踩了一个核心的逻辑坑:你把独立的bubble类拆成了视图的方法,导致没有创建真正的气泡实例。原代码里每个气泡都是bubble类的独立对象,拥有专属的位置、大小等属性,但你现在试图用视图的全局属性模拟单个气泡,这不仅会触发「bubble未定义」错误,还会让所有气泡共享同一套属性,完全失去多气泡动画的效果。
下面是修正后的完整Backbone视图代码,我会标注关键修改点:
var Achievement = CcCarousel.extend({ initialize: function() { // 初始化requestAnimationFrame兼容层 this._setupRequestAnimFrame(); }, render: function() { var courseData = this.gameData ? this.gameData : this.app.courseData; if (courseData.getStatus() == Status.COMPLETED) { this.app.router.next(); } else { CcCarousel.prototype.render.call(this); this.showStaggerAnimation(); this.changeLockedChaptersImage(); this.setupButtonListeners(); this.backgroundSetupVariables(); } }, // 1. 重新定义独立的Bubble构造函数,保留原类的封装性 Bubble: function(canvasWidth, canvasHeight) { this.maxHeight = canvasHeight; this.maxWidth = canvasWidth; this.randomise(); }, // 把原bubble类的方法挂载到Bubble原型上 _bubbleProto: { generateDecimalBetween: function(min, max) { return (Math.random() * (min - max) + max).toFixed(2); }, update: function() { this.posX = this.posX - this.movementX; this.posY = this.posY - this.movementY; if (this.posY < 0 || this.posX < 0 || this.posX > this.maxWidth) { this.randomise(); this.posY = this.maxHeight; } }, randomise: function() { this.colour = "255, 255, 255"; this.size = this.generateDecimalBetween(10, 15); this.movementX = this.generateDecimalBetween(-1, 1); this.movementY = this.generateDecimalBetween(1, 2); this.alpha = this.generateDecimalBetween(0.1, 1); this.posX = this.generateDecimalBetween(0, this.maxWidth); this.posY = this.generateDecimalBetween(0, this.maxHeight); } }, backgroundSetupVariables: function() { this.canvas = document.getElementById("floatingbubbles"); this.ctx = this.canvas.getContext("2d"); this.canvas.height = window.innerHeight; this.canvas.width = window.innerWidth; this.bubblesList = []; // 绑定Bubble的原型方法 this.Bubble.prototype = this._bubbleProto; this.generateBubbles(); this.animate(); }, generateBubbles: function() { var self = this; // 修正气泡密度计算的语法错误:原逗号运算符无效,改为计算画布面积平方根并缩放 var density = Math.sqrt(this.canvas.height * this.canvas.width) * 0.01; for (let i = 0; i < density; i++) { // 2. 创建真正的Bubble实例,添加到列表中 this.addBubble(new self.Bubble(self.canvas.width, self.canvas.height)); } }, addBubble: function(bubble) { return this.bubblesList.push(bubble); }, // 3. 补上原background类的animate动画循环方法 animate: function() { let self = this; self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height); self.bubblesList.forEach(function(bubble) { bubble.update(); self.ctx.beginPath(); self.ctx.arc(bubble.posX, bubble.posY, bubble.size, 0, 2 * Math.PI); self.ctx.strokeStyle = "rgba(" + bubble.colour + "," + bubble.alpha + ")"; self.ctx.stroke(); }); requestAnimationFrame(self.animate.bind(self)); }, // 兼容旧浏览器的requestAnimationFrame polyfill _setupRequestAnimFrame: function() { window.requestAnimFrame = (function() { return ( window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); } ); })(); } });
关键修改说明:
- 恢复独立气泡实例:重新定义
Bubble构造函数和原型方法,确保每个气泡都是拥有专属属性的独立对象,避免视图属性被共享覆盖。 - 修正气泡生成逻辑:替换原错误的
getCanvasLength调用,改为创建Bubble实例并添加到列表,这样bubblesList里才会有可调用update方法的有效对象。 - 补全动画循环:迁移原
background类的animate方法,确保气泡的更新和渲染循环正常运行,同时用bind(self)保证回调中的上下文指向视图实例。 - 修复密度计算错误:原代码的逗号运算符无法正确计算画布面积,改为基于面积平方根的合理密度公式,避免气泡过多或过少。
- 添加兼容层:在视图初始化时设置
requestAnimationFrame的polyfill,确保旧浏览器也能正常运行动画。
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

