天天看點

使用Popup視窗建立無限級Web頁菜單(7)

  這一節主要說一下Menu對鍵盤的支援,本來不支援鍵盤這個菜單也完全可用了,不過還是為了和WinForm的Menu統一,是以支援了和WinForm菜單一樣的操作方式。

    菜單的處理函數Menu.prototype.Keydown是在AttachEvents()方法裡通過:

使用Popup視窗建立無限級Web頁菜單(7)

doc.attachEvent('onkeydown', this.Keydown);

使用Popup視窗建立無限級Web頁菜單(7)

來attach的,為什麼要使用onkeydown不用onkeypress呢?是為了讓菜單通過鍵盤快捷鍵來彈出子菜單時和WinForm方式菜單一樣。這個doc是該菜單的popup視窗的doucment對象。

    下面一邊看代碼一邊講吧:

使用Popup視窗建立無限級Web頁菜單(7)

    if ( !evt || !evt.srcElement )

使用Popup視窗建立無限級Web頁菜單(7)

    {

使用Popup視窗建立無限級Web頁菜單(7)

        return;

使用Popup視窗建立無限級Web頁菜單(7)

    }

使用Popup視窗建立無限級Web頁菜單(7)

    var menuBody = evt.srcElement;

使用Popup視窗建立無限級Web頁菜單(7)

    var menuHtml = FindChildElement(menuBody, 'TABLE');

使用Popup視窗建立無限級Web頁菜單(7)

    if ( !menuHtml || !menuHtml.uniqueId )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        menuHtml = FindParentElement(menuBody, 'TABLE');

使用Popup視窗建立無限級Web頁菜單(7)

        if ( !menuHtml || !menuHtml.uniqueId )

使用Popup視窗建立無限級Web頁菜單(7)

        {

使用Popup視窗建立無限級Web頁菜單(7)

            return;

使用Popup視窗建立無限級Web頁菜單(7)

        }

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

    var menuObj = __MenuCache__[menuHtml.uniqueId];

使用Popup視窗建立無限級Web頁菜單(7)

    if ( menuObj.HasSubMenuExpanded() )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

    由于onkeydown事件處理函數attach在document上,是以要得到菜單必須尋找body裡面的Table

element,不過這個evt.srcElement可能是body,也可能是table的裡的元素,關鍵是看當時菜單popup裡的焦點在那個element上。上面代碼的最後4句話是判斷響應onkeydown事件的菜單是否有子菜單expanded,因為我們隻讓最後一級顯示的子菜單處理keystroke,父級的必須忽略,否則就亂套了。

使用Popup視窗建立無限級Web頁菜單(7)

    if ( menuObj.m_ShowTimer )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        window.clearTimeout(menuObj.m_ShowTimer);

使用Popup視窗建立無限級Web頁菜單(7)

        menuObj.m_ShowTimer = null;

使用Popup視窗建立無限級Web頁菜單(7)

    這是用來支援子菜單顯示特效的一個timer,如果手動顯示子菜單(包括滑鼠click和鍵盤快捷鍵),清除這個timer。

使用Popup視窗建立無限級Web頁菜單(7)

    var activeIndex = -1;

使用Popup視窗建立無限級Web頁菜單(7)

    for ( var i=0 ; i < menuObj.m_Items.length ; ++i )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        if ( menuObj.m_ActiveItem == menuObj.m_Items[i] )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

            activeIndex = i;

使用Popup視窗建立無限級Web頁菜單(7)

            break;

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

    把菜單中已active的item的index搜尋出來,沒有active的menuitem,index為-1。

使用Popup視窗建立無限級Web頁菜單(7)

    var sign = -1; 

使用Popup視窗建立無限級Web頁菜單(7)

    switch( evt.keyCode )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        case 37 : // left

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

            if ( menuObj.m_ParentMenu )

使用Popup視窗建立無限級Web頁菜單(7)

            {

使用Popup視窗建立無限級Web頁菜單(7)

                menuObj.Hide();

使用Popup視窗建立無限級Web頁菜單(7)

            }

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        case 38 : // up | no break;

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

            sign = 1;

使用Popup視窗建立無限級Web頁菜單(7)

            if ( activeIndex == -1 )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                activeIndex = 0;

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        case 40 : // down

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

            var itemCount = menuObj.m_Items.length;

使用Popup視窗建立無限級Web頁菜單(7)

            for ( var i=1 ; i <= itemCount ; ++i )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                var index = (itemCount+activeIndex-i*sign)%itemCount;

使用Popup視窗建立無限級Web頁菜單(7)

                var item = menuObj.m_Items[index];

使用Popup視窗建立無限級Web頁菜單(7)

                if ( !item.m_Disabled && item.m_Text != '-' )

使用Popup視窗建立無限級Web頁菜單(7)

                {

使用Popup視窗建立無限級Web頁菜單(7)

                    menuObj.__resumeItem();

使用Popup視窗建立無限級Web頁菜單(7)

                    menuObj.m_ActiveItem = item;

使用Popup視窗建立無限級Web頁菜單(7)

                    menuObj.__activeItem();

使用Popup視窗建立無限級Web頁菜單(7)

                    break;

使用Popup視窗建立無限級Web頁菜單(7)

                }

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        case 39 : // right | no break;

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

            var activeItem = menuObj.m_ActiveItem; 

使用Popup視窗建立無限級Web頁菜單(7)

            if ( !activeItem || !activeItem.m_ChildMenu )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                break;

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        case 13 : // enter

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

            menuObj.Click();

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        case 27 :

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

    處理left, right, up, down四個鍵,up和down要麻煩些,因為要查找可用的(separator

item和disabled

item是不可用的,不能被active)下一個itme來active,到了最有一條itme再同方向up或down還需要有輪轉的效果。

    HACK: 由于up和down的代碼完全相同,隻是搜尋方向不同,是以用了一個sign(取值1|-1)标志來判斷搜尋方向。

使用Popup視窗建立無限級Web頁菜單(7)

    if ( evt.keyCode >= 48 && evt.keyCode <= 90 )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        var keyList = '';

使用Popup視窗建立無限級Web頁菜單(7)

        var key = String.fromCharCode(evt.keyCode); 

使用Popup視窗建立無限級Web頁菜單(7)

        for ( var i=0 ; i < menuObj.m_Items.length ; ++i )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

            var item = menuObj.m_Items[i];

使用Popup視窗建立無限級Web頁菜單(7)

            if ( !item.m_Disabled && item.m_Mnemonic )

使用Popup視窗建立無限級Web頁菜單(7)

            { 

使用Popup視窗建立無限級Web頁菜單(7)

                keyList += item.m_Mnemonic;

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

            else

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                keyList += '-';

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

        var index = keyList.indexOf(key); 

使用Popup視窗建立無限級Web頁菜單(7)

        if ( index != -1 )

使用Popup視窗建立無限級Web頁菜單(7)

        { 

使用Popup視窗建立無限級Web頁菜單(7)

            if ( keyList.indexOf(key) == keyList.lastIndexOf(key) )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                if ( !menuObj.m_Items[index].m_Disabled )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                    menuObj.__resumeItem(); 

使用Popup視窗建立無限級Web頁菜單(7)

                    menuObj.m_ActiveItem = menuObj.m_Items[index];

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                    menuObj.Click();

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                menuObj.__resumeItem();

使用Popup視窗建立無限級Web頁菜單(7)

                var newActive;

使用Popup視窗建立無限級Web頁菜單(7)

                if ( !evt.shiftKey )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                    newActive = keyList.indexOf(key, activeIndex+1);

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                else

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                    if ( activeIndex == 0 )

使用Popup視窗建立無限級Web頁菜單(7)

                    {

使用Popup視窗建立無限級Web頁菜單(7)

                        newActive = -1;

使用Popup視窗建立無限級Web頁菜單(7)

                        index = keyList.lastIndexOf(key);

使用Popup視窗建立無限級Web頁菜單(7)

                    }

使用Popup視窗建立無限級Web頁菜單(7)

                    else 

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                        newActive = keyList.lastIndexOf(key, activeIndex-1);

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                if ( newActive == -1 )

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                    menuObj.m_ActiveItem = menuObj.m_Items[newActive];

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

                menuObj.__activeItem();

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

    處理菜單條目上的快捷鍵Mnemonic,這裡的算法是這樣的,把該菜單上的每個item上的Mnemonic字元取出組成一個字元串,沒有Mnemonic就用'-'代替。比如下面的菜單的Mnemonic字元組成的字元串分别是:

第一級:"--N---",第二級:"M",第三級:"TTTT"。然後使用String.indexOf(key)就取到被按快捷鍵的MenuItem的index了,由于沒有限制同一個Menu裡面多個MenuItem具有相同的Mnemonic,是以像第三級菜單,一直按T鍵的效果就和按down

key一樣,它的效果使用語句Sting.indexOf(key, activeIndex+1)來獲得。 

使用Popup視窗建立無限級Web頁菜單(7)

#region 附Menu.prototype.Keydown = function(evt)代碼 

使用Popup視窗建立無限級Web頁菜單(7)

Menu.prototype.Keydown = function(evt)

使用Popup視窗建立無限級Web頁菜單(7)

{

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

    if ( evt.keyCode != 27 )

使用Popup視窗建立無限級Web頁菜單(7)

    {  

使用Popup視窗建立無限級Web頁菜單(7)

        evt.returnValue = null;

使用Popup視窗建立無限級Web頁菜單(7)

        evt.cancelBubble = true; 

使用Popup視窗建立無限級Web頁菜單(7)
使用Popup視窗建立無限級Web頁菜單(7)

};

本文轉自部落格園鳥食軒的部落格,原文連結:http://www.cnblogs.com/birdshome/,如需轉載請自行聯系原部落客。

繼續閱讀