本文介绍了ExtJS的4.1" HoverButton"扩展问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作Ext.Button的延伸,使一个按钮的鼠标悬停/鼠标移开菜单的显示/隐藏。这是可以正常使用的按钮的直接子菜单,但是我遇到了一个问题,与有它循规蹈矩任何二级/三级/等菜单。

现在,当用户移动过上午项在包含菜单顶层菜单中,它会打开菜单,并且用户可以将光标移动到它没有问题,一切都将保持打开。如果用户然后移动光标移出二级菜单进入开放的空间,所有的菜单将关闭这是正确的为好。但有时如果用户移动到二级菜单,然后再返回到它的父菜单,所有的菜单将关闭,这是不应该发生的事情,最起码光标已经结束应该保持开放的父菜单

这是我的初步调试它看起来是与事件是如何烧制的问题,他们的时间。看来,从孩子的菜单搬回到父菜单时父菜单MouseEnter事件不火。其次它看起来像我的菜单鼠标悬停不会触发事件足够可靠或往往不够它取消延迟隐藏任务后子菜单mouseLeave事件已被触发。

问题的演示:

和这里的code,没有什么根本性的错误脱颖而出?

  Ext.define('Ext.HoverButton',{
    延伸:Ext.Button',
    别名:widget.hoverButton',
    ISOVER:假的,
    hideDelay:250,
    showDelay:200,    applyListeners:功能(菜单,CFG){
        Ext.apply(菜单,CFG);
        Ext.each(menu​​.items,函数(项目,IDX,allItems){
            如果(item.menu)this.applyListeners(item.menu,CFG);
        }, 这个);
    },    initComponent:功能(){
        无功配置= {},
            menuconfig的= {},
            我该=;        me.delayedShowMenu =新Ext.util.DelayedTask(函数(){
            如果回报(me.isOver!);
            me.showMenu();
        }, 这个);        me.delayedHideMenu =新Ext.util.DelayedTask(函数(){
            如果(me.isOver)回报;
            me.hideMenu();
        });        如果(Ext.isDefined(this.initialConfig.menu)){
            配置= {
                听众:{
                    鼠标移到: {
                        适用范围:我,
                        FN:功能(B){
                            me.isOver = TRUE;
                            me.delayedShowMenu.delay(me.showDelay);
                        }
                    },
                    鼠标移开:{
                        适用范围:我,
                        FN:功能(B){
                            me.isOver = FALSE;
                            me.delayedHideMenu.delay(me.hideDelay);
                        }
                    }
                }
            };            menuconfig中= {
                听众:{
                    鼠标移到: {
                        适用范围:我,
                        FN:功能(菜单项,E){
                            me.delayedHideMenu.cancel();
                        }
                    },
                    的mouseenter:{
                        适用范围:我,
                        FN:功能(菜单,E){
                            me.delayedHideMenu.cancel();
                        }
                    },
                    鼠标离开:{
                        适用范围:我,
                        FN:功能(菜单,E){
                            me.delayedHideMenu.delay(me.hideDelay);
                        }
                    }
                }
            };
            //申请鼠标悬停/离开听众所有子菜单递归
            me.applyListeners(me.menu,menuconfig的);
        }        Ext.apply(我,Ext.apply(me.initialConfig,配置));
        Ext.HoverButton.superclass.initComponent.apply(我,参数);
    }
});


解决方案

我一直在做的东西有点类似,我已经采取了偷看的

看来,DOM的事件顺序应该是鼠标悬停 - >的mouseenter - >鼠标移开 - >鼠标离开这意味着有时会取消()延迟之前,将被称为()设置。为了解决这个问题,我保留最后一个变量中输入:

 的mouseenter:{
 适用范围:我,
 FN:功能(菜单,E){
  presentlyInside =菜单; / *<< * /
  me.delayedHideMenu.cancel();
 }
},
鼠标离开:{
 适用范围:我,
 FN:功能(菜单,E){
  如果(presentlyInside ==菜单)/ *<< * /
    me.delayedHideMenu.delay(me.hideDelay);
 }
}

希望它帮助!

I am working on an extension of Ext.Button that enables the showing/hiding of a button's menu on mouseover/mouseout. It is working perfectly for the button's immediate child menu, however I am running into an issue with having it behave properly for any secondary/tertiary/ect menus.

Right now, when the user moves over am item in the top menu that contains a menu, it will open the menu and the user can move the cursor into it with no problems, everything will stay open. If the user then moves the cursor out of the secondary menu into open space, all menus will close which is correct as well. BUT, sometimes if a user moves into a secondary menu, and then back into its parent menu, all the menus will close, which isn't what should happen, at the very least that parent menu that the cursor is now over should remain open.

From my initial debugging it looks to be an issue with how the events are firing, and their timing. It appears that the mouseenter event for a parent menu does not fire when moving from a child menu back into the parent menu. And secondly it looks to me like the the menu mouseover event does not fire reliably enough or often enough for it to cancel the delayed hide task after a mouseleave event on a child menu has fired.

Demo of the issue: http://qs1724.pair.com/users/autod1nx/EMPLOYEE/BDAMI/hoverbutton/index.html

And here's the code, does anything fundamentally wrong with it stand out?

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);
    }
});
解决方案

I've been doing something a bit similar and I've solved the problem after taking a peek at http://www.quirksmode.org/dom/events/mouseover.html

It seems that DOM's event order should be mouseover -> mouseenter -> mouseout -> mouseleave which means that sometimes the cancel() will be called before the delay() is set. To solve the problem I keep the last entered in a variable:

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);
 }
}

Hope it helps!

这篇关于ExtJS的4.1&QUOT; HoverButton&QUOT;扩展问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 04:11