EaselJS Shape对象拖拽报错:无法读取'on'属性(未定义)
解决EaselJS拖拽矩形时的
Cannot read property 'on' of undefined错误 这个报错的根源很清晰——你在拖拽事件里误用了全局变量i,导致索引错位了。
每次点击画布生成新矩形时,全局的i都会自增。等你去拖拽之前生成的矩形时,i已经指向了数组里还没赋值的位置,这时候rects[i]自然就是undefined,调用on方法肯定会报错。
最简单的修复方案:直接操作事件目标
不需要依赖全局的i,我们可以通过事件对象里的target属性直接获取当前被点击的矩形实例,这样就彻底避免了索引问题。
修正后的完整代码如下:
var rects = []; var i = 0; var stage; window.onload = function() { canvas = document.getElementById("drawingCanvas"); context = canvas.getContext("2d"); stage = new createjs.Stage("drawingCanvas"); canvas.onclick = canvasClick; } function canvasClick(e) { var d = Math.random() * 150; rects[i] = new createjs.Shape(); // 用模板字符串优化颜色拼接,可读性更好 rects[i].graphics.beginStroke("black") .beginFill(`RGB(${parseInt(Math.random()*255)},${parseInt(Math.random()*255)},${parseInt(Math.random()*255)})`) .drawRect(e.offsetX - d/2, e.offsetY - d/2, d, d); stage.addChild(rects[i]); rects[i].on("mousedown", function (event) { console.log("开始拖拽"); var offset = { x: event.target.x - event.stageX, y: event.target.y - event.stageY }; // 直接绑定到当前被点击的矩形,无需依赖全局i event.target.on("pressmove", function (event) { event.target.x = event.stageX + offset.x; event.target.y = event.stageY + offset.y; stage.update(); }); }); i++; stage.update(); }
修复要点说明:
- 移除全局索引依赖:在
mousedown回调里,用event.target直接获取当前操作的Shape实例,替代原来的rects[i],从根源上避免索引错位问题。 - 优化代码可读性:把原来繁琐的RGB颜色字符串拼接改成了ES6模板字符串,看起来更清爽。
- 修正拼写错误:把事件参数的
evant改成了标准的event(虽然不影响运行,但规范的命名能减少后续维护的困惑)。
另一种方案:用闭包保存当前索引
如果你坚持要用数组索引来操作,也可以通过闭包把当前的i值保存下来,避免后续i自增影响:
rects[i].on("mousedown", (function(currentIndex) { return function(event) { console.log("开始拖拽"); var offset = { x: rects[currentIndex].x - event.stageX, y: rects[currentIndex].y - event.stageY }; rects[currentIndex].on("pressmove", function (event) { rects[currentIndex].x = event.stageX + offset.x; rects[currentIndex].y = event.stageY + offset.y; stage.update(); }); } })(i));
不过相比之下,第一种直接操作事件目标的方法更简洁直观,推荐使用。
内容的提问来源于stack exchange,提问作者Ольга Кужикова
相关产品推荐
相关产品推荐

