Я работаю над расширением Ext.Button, которое позволяет отображать/скрывать меню кнопки мыши на мыши/мыши. Он отлично работает для непосредственного дочернего меню кнопки, однако я столкнулся с проблемой, когда он корректно ведет себя для любых вспомогательных/третичных/ect-меню.ExtJS 4.1 «HoverButton» вопрос расширения
Прямо сейчас, когда пользователь перемещает элемент am в верхнем меню, содержащем меню, он откроет меню, и пользователь может без проблем переместить курсор в него, все останется открытым. Если пользователь затем перемещает курсор из вторичного меню в открытое пространство, все меню закроют, что тоже правильно. НО, иногда, если пользователь переходит во вторичное меню, а затем возвращается в свое родительское меню, все меню закрываются, что не должно произойти, по крайней мере, что родительское меню, в котором находится курсор, должно оставаться открытым ,
С моей начальной отладки это выглядит как проблема с тем, как стреляют события, и их время. Похоже, что событие mouseenter для родительского меню не срабатывает при переходе из дочернего меню обратно в родительское меню. И, во-вторых, мне кажется, что событие mouseover на экране не срабатывает достаточно надежно или достаточно часто, чтобы отменить задание с задержкой при выполнении события mouseleave в дочернем меню.
Демонстрация выпуска: http://qs1724.pair.com/users/autod1nx/EMPLOYEE/BDAMI/hoverbutton/index.html
А вот код, делает ничего принципиально плохого с ним выделиться?
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);
}
});
Вы пытались добавить «me.isOver = true/false» в menuConfig listener events? –
У меня есть да, похоже, не имеет никакого значения. После большего тестирования похоже, что проблема заключается в том, как запускается событие mouseover. В этом случае не запускается последовательно или достаточно часто, чтобы вызывать .cancel() на delayedHideMenu после того, как событие mouseleave срабатывает при выходе из подменю. –