addEventListener仅在第二次点击时触发问题排查求助
问题:addEventListener首次点击无响应,仅第二次触发
我的代码用于选择单个MovieClip并调整其色相,但遇到异常:addEventListener绑定的"change"事件,首次操作色相滑块时无响应,第二次操作才正常触发,功能本身逻辑是正常的。
以下是完整代码:
var SHELL = _global.getCurrentShell(); var INTERFACE = _global.getCurrentInterface(); function setupOutfit() { trace("Outfit Editor v1.2b Loaded "); if(SHELL.currentSavedOutfits === undefined && INTERFACE.currSlot === undefined) { return (false); } OUTFIT.gotoAndStop(2); OUTFIT.outfit_txt.text = INTERFACE.currSlot.name; OUTFIT.close_btn.onRelease = INTERFACE.closeContent; for (var f in penguin_layers) { setDollOutfit(penguin_layers[f], INTERFACE.currSlot[penguin_layers[f]]); } var _loc3 = Number(SHELL.getPlayerHexFromId(INTERFACE.currSlot.color)); SHELL.setColourFromHex(OUTFIT.paper_doll_mc.body, Number(_loc3)); } function setDollOutfit(type, id) { var dollDepth = OUTFIT.paper_doll_mc.createEmptyMovieClip("pd_" + type + "Clip", SHELL.PAPERDOLL_DEFAULT_LAYER_DEPTHS[type]); var dollClip = dollDepth.createEmptyMovieClip("itemClip", dollDepth.getNextHighestDepth()); if (id > 0) { var _loc9 = id + ".swf"; var dollLoader = new com.cp.hybrid.HybridMovieClipLoader(); dollLoader.loadClip(SHELL.getPath("clothing_paper") + _loc9, dollClip); } updateItemInteractivity(type); } function updateItemInteractivity(type) { var _loc2 = OUTFIT.paper_doll_mc["pd_" + type + "Clip"]; if (_loc2 === null) { return (false); } _loc2.onRelease = com.cp.util.Delegate.create(this, setOptionSection, type); } function setOptionSection(type) { OUTFIT.options_mc.gotoAndStop(2); OUTFIT.options_mc.option_txt.text = "Editing " + type + " item"; setHueClip = OUTFIT.paper_doll_mc["pd_" + type + "Clip"]; OUTFIT.options_mc.huevalue_mc.addEventListener("change", this.setupItemHueModifier); } function setupItemHueModifier(evnt) { var _loc3 = new flash.filters.ColorMatrixFilter(); var _loc1 = new com.gskinner.geom.ColorMatrix(); _loc1.adjustHue(evnt.target.value); trace("Hue Value: " + evnt.target.value); _loc3.matrix = _loc1; setHueClip.filters = [_loc3]; } var setHueClip; var OUTFIT = outfitContainer_mc; var penguin_layers = ["head", "face", "body", "neck", "hand", "feet"]; setupOutfit();
问题根源
- 重复绑定事件:每次点击MovieClip进入
setOptionSection时,都会给huevalue_mc新增一个"change"事件监听器,未移除旧监听器。首次点击后监听器绑定完成,但组件可能因重复绑定的潜在冲突,导致首次操作不触发;第二次操作时,多次绑定的监听器中至少有一个生效。 - 上下文绑定缺失:直接绑定
this.setupItemHueModifier时,事件触发时的this上下文可能偏离当前作用域,虽未直接报错,但存在隐性风险。 - 组件初始化时机:
OUTFIT.options_mc.gotoAndStop(2)切换帧后,滑块组件可能未完全初始化,此时绑定事件无法立即响应首次操作。
解决方案
修改setOptionSection函数,解决上述问题:
function setOptionSection(type) { OUTFIT.options_mc.gotoAndStop(2); OUTFIT.options_mc.option_txt.text = "Editing " + type + " item"; setHueClip = OUTFIT.paper_doll_mc["pd_" + type + "Clip"]; // 先移除旧的事件监听器,避免重复绑定 OUTFIT.options_mc.huevalue_mc.removeEventListener("change", this.setupItemHueModifier); // 使用Delegate绑定正确的上下文 var boundHandler = com.cp.util.Delegate.create(this, this.setupItemHueModifier); OUTFIT.options_mc.huevalue_mc.addEventListener("change", boundHandler); // 手动触发一次,用滑块当前值初始化色相,同时确保事件逻辑生效 setupItemHueModifier({target: OUTFIT.options_mc.huevalue_mc}); }
说明
- 移除旧监听器:避免多次绑定导致的事件重复触发或逻辑冲突。
- 绑定上下文:确保
setupItemHueModifier执行时的this指向当前作用域,消除隐性错误。 - 手动触发初始化:确保滑块切换到编辑状态后,立即应用当前值的色相,同时验证事件逻辑是否正常工作。
内容的提问来源于stack exchange,提问作者Zesty
相关产品推荐
相关产品推荐

