Button ExtJS 4.1“;悬停按钮“;延期发行
我正在开发Ext.Button的一个扩展,它可以在mouseover/mouseout上显示/隐藏按钮的菜单。它对于按钮的直接子菜单非常有效,但是我遇到了一个问题,即对于任何二级/三级/ect菜单,它都能正常工作 现在,当用户移动到包含菜单的顶部菜单中的am项上时,它将打开菜单,用户可以毫无问题地将光标移动到其中,所有内容都将保持打开状态。如果用户随后将光标从辅助菜单移到开放空间,所有菜单也将关闭,这也是正确的。但是,有时如果用户移动到辅助菜单,然后返回到其父菜单,所有菜单都将关闭,这不是应该发生的事情,至少光标现在所在的父菜单应该保持打开状态 从我最初的调试来看,这似乎是一个事件如何触发及其时间安排的问题。从子菜单移回父菜单时,似乎不会触发父菜单的mouseenter事件。其次,在我看来,菜单mouseover事件的触发不够可靠,或者不够频繁,无法在子菜单上的mouseleave事件触发后取消延迟的隐藏任务 本期演示: 这是代码,它有什么根本性的错误吗Button ExtJS 4.1“;悬停按钮“;延期发行,button,extjs,menu,hover,extjs4,Button,Extjs,Menu,Hover,Extjs4,我正在开发Ext.Button的一个扩展,它可以在mouseover/mouseout上显示/隐藏按钮的菜单。它对于按钮的直接子菜单非常有效,但是我遇到了一个问题,即对于任何二级/三级/ect菜单,它都能正常工作 现在,当用户移动到包含菜单的顶部菜单中的am项上时,它将打开菜单,用户可以毫无问题地将光标移动到其中,所有内容都将保持打开状态。如果用户随后将光标从辅助菜单移到开放空间,所有菜单也将关闭,这也是正确的。但是,有时如果用户移动到辅助菜单,然后返回到其父菜单,所有菜单都将关闭,这不是应该发
Ext.define('Ext.HoverButton', {
extend: 'Ext.Button',
alias: 'widget.hoverButton',
isOver: false,
hideDelay: 250,
showDelay: 200,
applyListeners: function(menu, cfg) {
Ext.apply(menu, cfg);
Ext.each(menu.items, function(item, idx, allItems) {
if(item.menu) this.applyListeners(item.menu, cfg);
}, this);
},
initComponent: function() {
var config = {},
menuConfig = {},
me = this;
me.delayedShowMenu = new Ext.util.DelayedTask(function() {
if(!me.isOver) return;
me.showMenu();
}, this);
me.delayedHideMenu = new Ext.util.DelayedTask(function() {
if(me.isOver) return;
me.hideMenu();
});
if(Ext.isDefined(this.initialConfig.menu)) {
config = {
listeners: {
mouseover: {
scope: me,
fn: function(b) {
me.isOver = true;
me.delayedShowMenu.delay(me.showDelay);
}
},
mouseout: {
scope: me,
fn: function(b) {
me.isOver = false;
me.delayedHideMenu.delay(me.hideDelay);
}
}
}
};
menuConfig = {
listeners: {
mouseover: {
scope: me,
fn: function(menu, item, e) {
me.delayedHideMenu.cancel();
}
},
mouseenter: {
scope: me,
fn: function(menu, e) {
me.delayedHideMenu.cancel();
}
},
mouseleave: {
scope: me,
fn: function(menu, e) {
me.delayedHideMenu.delay(me.hideDelay);
}
}
}
};
//apply mouseover/leave listeners to all submenus recursively
me.applyListeners(me.menu, menuConfig);
}
Ext.apply(me, Ext.apply(me.initialConfig, config));
Ext.HoverButton.superclass.initComponent.apply(me, arguments);
}
});
我一直在做一些类似的事情,在看了一眼之后,我解决了这个问题 DOM的事件顺序似乎应该是mouseover->mouseenter->mouseout->mouseleave,这意味着有时会在设置delay()之前调用cancel()。为了解决这个问题,我将最后输入的值保留在一个变量中:
mouseenter: {
scope: me,
fn: function(menu, e) {
presentlyInside = menu; /* << */
me.delayedHideMenu.cancel();
}
},
mouseleave: {
scope: me,
fn: function(menu, e) {
if(presentlyInside==menu) /* << */
me.delayedHideMenu.delay(me.hideDelay);
}
}
mouseenter:{
范围:我,
fn:功能(菜单,e){
presentlyInside=menu;/*我一直在做一些类似的事情,在看了一眼之后,我解决了这个问题
DOM的事件顺序似乎应该是mouseover->mouseenter->mouseout->mouseleave,这意味着有时会在设置delay()之前调用cancel()。为了解决这个问题,我将最后输入的值保留在一个变量中:
mouseenter: {
scope: me,
fn: function(menu, e) {
presentlyInside = menu; /* << */
me.delayedHideMenu.cancel();
}
},
mouseleave: {
scope: me,
fn: function(menu, e) {
if(presentlyInside==menu) /* << */
me.delayedHideMenu.delay(me.hideDelay);
}
}
mouseenter:{
范围:我,
fn:功能(菜单,e){
presentlyInside=menu;/*我发现这个方法很有效,而且更简单
Ext.define('Ext.HoverButton', {
extend : 'Ext.Button',
alias : 'widget.hoverButton',
listeners : {
mouseover : function() {
this.showMenu();
},
menushow : function() {
this.mouseLeaveMonitor = this.menu.el.monitorMouseLeave(100, this.hideMenu, this);
},
destroy : function(combo) {
combo.menu.el.un(combo.mouseLeaveMonitor);
}
}
});
我发现这个很有效,而且更简单
Ext.define('Ext.HoverButton', {
extend : 'Ext.Button',
alias : 'widget.hoverButton',
listeners : {
mouseover : function() {
this.showMenu();
},
menushow : function() {
this.mouseLeaveMonitor = this.menu.el.monitorMouseLeave(100, this.hideMenu, this);
},
destroy : function(combo) {
combo.menu.el.un(combo.mouseLeaveMonitor);
}
}
});
您是否尝试将me.isOver=true/false
添加到menuConfig侦听器事件中?是的,似乎没有任何区别。经过更多测试后,问题似乎在于mouseover事件的触发方式。在这种情况下,触发的频率并不一致,也不足以调用.cancel()在delayedHideMenu上,MouseAve事件在离开子菜单时触发。您是否尝试将me.isOver=true/false
添加到menuConfig listener事件中?我尝试过,是的,似乎没有任何区别。经过更多测试后,问题似乎在于mouseover事件如何触发。在这方面,mouseover事件没有持续或持续地触发经常调用.cancel()命令在delayedHideMenu上,mouseleave事件在离开子菜单时触发。有趣的是,我已经有一段时间没有接触过这段代码了,但下一次我一定要尝试一下。感谢您的回复!在发布anwser之前,我只让它工作了几分钟,但到目前为止,我的实现(以及在Chrome上)我没有发现任何问题。我知道这个响应很晚,但我终于用你的补丁更新了扩展,它工作得很好!再次感谢!!不适合我,菜单突然消失…请在这里发布完整代码有趣的是,我已经有一段时间没有接触过这个代码了,但我一定要在下一次机会尝试一下获取。感谢您的回复!在发布anwser之前几分钟,我才让它工作,但到目前为止,我的实现(和Chrome上的实现)还没有完成我没有发现任何问题。我知道这个响应很晚,但我终于用你的补丁更新了扩展,它工作得很好!再次感谢!!不适合我,菜单突然消失…请在这里发布完整代码