假设我们有一个有两个正方形的舞台,如下所示:
假设我们希望黄色方块最初是隐藏的,并且只要鼠标光标在红色方块的边界内,我们希望这样 - 黄色方块将是可见的,并且只要鼠标光标在外面红色方块的边界 - 黄色方块将被隐藏。
直观的方法是这样写:
inSqr.visible = false;
outSqr.addEventListener (MouseEvent.ROLL_OVER,sqrOver);
outSqr.addEventListener (MouseEvent.ROLL_OUT,sqrOut);
function sqrOver(e:MouseEvent) {
inSqr.visible = true;
}
function sqrOut (e:MouseEvent) {
inSqr.visible = false;
}
但是,使用此代码 - 任何时候将鼠标光标移动到黄色方块内- 显然,它都算作红色方块的ROLL_OUT - 因此触发 sqrOut 函数 - 使黄色方块消失,一旦黄色方块不存在 - 光标突然再次在红色方块的范围内 - 所以调用了 sqrOver 函数 - 恢复黄色方块的可见性 - 触发 sqrOut 等等,因此当鼠标光标在他身上:黄色方块消失并一遍又一遍地再次出现。
一个可能的“修复”是在光标位于黄色内部时移除红色滚动事件的侦听器(如果它在黄色内部,它肯定也在红色内部),并在它出来时将其带回来,通过将其添加到上面的代码中:
inSqr.addEventListener (MouseEvent.ROLL_OVER,insqrOver);
inSqr.addEventListener (MouseEvent.ROLL_OUT,insqrOut);
function insqrOver(e:MouseEvent) {
if (outSqr.hasEventListener (MouseEvent.ROLL_OUT)) {
outSqr.removeEventListener(MouseEvent.ROLL_OUT,sqrOut);
}
inSqr.visible = true;
}
function insqrOut(e:MouseEvent) {
if (!outSqr.hasEventListener (MouseEvent.ROLL_OUT)) {
outSqr.addEventListener(MouseEvent.ROLL_OUT,sqrOut);
}
}
这行得通。但这很麻烦。您必须为红色方块范围内的每个对象执行此操作 - 导致代码长、事件侦听器和持续的侦听器注册和注销。
几年前有人向我建议了这种技术:
outSqr.addEventListener (Event.ENTER_FRAME,hoverCheck);
function hoverCheck (e:Event) {
if (e.currentTarget.hitTestPoint(stage.mouseX,stage.mouseY,true)) {
inSqr.visible = true;
}
else {
inSqr.visible = false;
}
}
这是一个有效的简单短代码。但是,如果您的项目真的不需要使用 ENTER_FRAME 事件,它会产生不必要的开销和重复运行命中测试的 CPU 周期。此外,如果红色方块覆盖整个舞台(与舞台具有相同的尺寸) - 它会产生问题(它不起作用)。
有没有人知道一种简单而优雅的方法来实现这一点 - 一种不会涉及太繁琐和冗长的代码,并且不必使用重复的计时器来一遍又一遍地进行命中测试......?