跨幀 (frameset,freame,iframe) 的無限級菜單

                                  跨幀 (frameset,freame,iframe) 的無限級菜單                     

        大家都知道在IE中,存在frameset,freame,iframe三種幀元素,他們在佈局中運用廣泛,而且也很實用,但是有時候使用起來還是有一些小麻煩。如你是做相關框架或者是企業管理軟件的,需要使用到它來佈局,那他的層級是最高的,也就是說他的z-index是最高的,那就會帶來一個問題,假如你的ifream上面可能會出現諸如菜單,懸浮div的時候,那他們將會被幀覆蓋。這樣降帶來用戶無法接受的體驗,可以解決的方案很多,但是如果你確實已經在用幀並且無法替代它(出於開發時間或者成本),那麼我們不妨來學習製作一下跨幀的下拉菜單,僅限IE,其他瀏覽器不再考慮範圍。

        首先我們採用的方案就是IE下的window.createPopup,它是彈出對話框,當用戶焦點退出對話框的時候,對話框會自動消失,我們也可以再它消失的時候釋放一些資源等。但是他也會帶來幾個問題,需要我們去考慮:

        1. 我們需要寫一些javascript來實現下拉菜單,這需要對javascript有一點了解。

        2. popup window 是不支持父窗口css導入,這需要我們去用javascript動態寫入,

            好像CSS風格也不支持expression。

        3. popup window初始化的時候是不可見的,需要調用popupwin.show()來顯示窗口,這點我們可能好好利用。

好了下面我們看一個列子:當點擊按鈕時會出現一個彈出框。

<HTML>
<HEAD>
<TITLE>Popup Example</TITLE>
<SCRIPT LANGUAGE="JScript">
var oPopup = window.createPopup();
function ButtonClick()
{
var oPopBody = oPopup.document.body;
oPopBody.style.backgroundColor = "lightyellow";
oPopBody.style.border = "solid black 1px";
oPopBody.innerHTML = "Click outside <B>popup</B> to close.";
oPopup.show(100, 100, 180, 25, document.body);
}
</SCRIPT>
</HEAD>
<BODY>
<BUTTON οnclick="ButtonClick()">Click Me!</BUTTON>
</BODY>
</HTML>


         接下來我們一起來分析怎樣來實現無限級跨幀菜單,我想第一步分析下數據結構,以便我們來用基於對象的javascript來實現menu Object。很容易想到它就是tree結構。

MenuItem
屬行 描述 值描述
Id menuitem 的唯一標示 可以任意定義,但是得保證唯一
index 序列,用與所有menuitem排序,擴展功能 一般從0開始不斷增加
title menuitem標題,描述 任意字符串
properties 屬性集合,擴展使用 存儲任意其他信息
parentId 父menuitem的Id,  
children menuitem的子按鈕  
classStyle 常量字符串,用於模擬typeof  
icon 按鈕圖標,擴展用  
url 按鈕鏈接地址  

還有一個target屬性,指定我們以怎樣的方式打開我們的新的鏈接,如_self, _blank,或者其他frame的引用。

 

MenuItem = function(id ,index,parentId, title,icon,url,toTarget)
 
{
     
    this.defaultIcon = "menu.gif";
     
    this.id =id;
     
    this.index = (index!=null && parseInt(index)>0) ? parseInt(index): 0 ;
     
    this.title = title;
     
    this.properties = new Array();
     
    this.parentId = parentId;
     
    this.children = new Array();
     
    this.classStyle ="MenuItem";
     
    this.icon = (icon!=null && icon.length>0)? icon : this.defaultIcon;
     
    this.url = (url!=null && url.length>0)? url:"";

  	this.toTarget = toTarget;

};

     以上就是類似與樹的節點,那下面就是我們樹本身的一些操作和封裝,比如menu的樣式css,添加主菜單和子菜單的基本方法:

 1.  Menubar 的結構:

PopMenu = function (cssFile, normalClass,hotClass,menuClass,menuWidth,menuHeight)
 
{
     
    this.defaultMenuWidth = 80;
     
    this.defaultMenuHeight = 25;
     


    this.cssFile = cssFile;
     
    this.normalClass = normalClass;
     
    this.hotClass = hotClass;
     
    this.menuClass = menuClass;
     
    this.menuWidth = (menuWidth && menuWidth!=null && parseInt(menuWidth) >0)? parseInt(menuWidth):this.defaultMenuWidth;
     
    this.menuHeight = (menuHeight && menuHeight!=null && parseInt(menuHeight) >0)? parseInt(menuHeight):this.defaultMenuHeight;
     

    this.menus = new Array();
     

    this.popWin =window.createPopup();
     
    this.popWin.document.createStyleSheet(this.cssFile);
     

    if(window.navigator.appName.indexOf("Microsoft")>=0) this.appName = "IE";
     
    else if(window.navigator.appName.indexOf("Netscape")>=0) this.appName="NS";
     
    else this.appName ="OT";
     

    appName = this.appName;
     

    };

 

2.初始化菜單

PopMenu.prototype.initTopMenu = function (divId)
 
{
     

    popMenuInstant = this;
     

    var target = null;
     

    if(divId!=null && divId.length>0)
     
    {
         
        target = document.getElementById(divId);
         
        if (target==null ) {
            alert("could not find the menu element!"); 
            return;
        }
         
    }
     
    var len = this.getTopMenusLength();

    target.style.width= (parseInt(this.getMenuWidth())*len+ 10 * len);
     
    target.style.height= parseInt(this.getMenuHeight()+4);
     


    if(len>0)
     
    {
         
        var menutable = document.createElement("table");
         


        var menuContent ="";
         
        for(var i=0;
        i<len ;
        i++)
         
        {
             
            var tempMenu = this.getTopMenus()[i];
             
            var url = (tempMenu.getURL()!=null && tempMenu.getURL().length>0)?tempMenu.getURL():".";
             
            menuContent+=("<td id ='"+tempMenu.getMenuId()+"' class='"+this.normalClass+"' " +
             
            " οnmοuseοver='javascript:_onMenuItemFocus.call(this);' " +
             
            " onmouseout ='javascript:_onMenuItemNormal.call(this);' " +
             
            " >"+tempMenu.getMenuTitle()+"</td>");
             

        }
         


        target.innerHTML = 

        "<table class='menuTable'>"+
         
        "<tr>"+
         
        menuContent+
         
        "</tr>"+
         
        "</table>";
         
   }
     

     
     
    };


 

 

 


3. 創建菜單:

PopMenu.prototype.addMenuItem = function(id ,index,title,icon,url)
 
{
     

    var menuItem = new MenuItem(id ,index,null, title,icon,url,null);
     

    this.menus.push(menuItem);
     

    };


4. 創建子菜單:

PopMenu.prototype.addSubMenuItem = function(id ,index,parentId, title,icon,url,toTarget)
 
{
     
    if(parentId ==null ||parentId.length<=0)
     
    {
         
        this.addMenuItem(id, index, title, icon,url);
         
            }
     
    else
     
    {
         
        var parent = this.findMenu(parentId);
         
        var menuItem = new MenuItem(id ,index,parentId, title,icon,url,toTarget);
         
        parent.addChild(menuItem);
         
            }
     

    };

 

4.點擊按鈕,創建popup 子菜單

_createSubMenu =function(menuId)
 
{
     
    var menu = popMenuInstant.findMenu(menuId);
	var parentMenu = null;
	
	 if(menu.getParentId()!=null && menu.getParentId().length>0 )
	    parentMenu =  popMenuInstant.findMenu(menu.getParentId());

    var children = menu.getChildren();
     


    if(children.length && children.length>0)
     
    {
		
		var width = popMenuInstant.menuWidth;
		var height = ((parseInt(children.length)+1) * popMenuInstant.menuHeight);
         
        var htmlStr = "<div style=\"width:"+(parseInt(width))+"px;\" >"
         
        + "<table class=\"menuTable\" >";
 
        for (var i = 0;  i < children.length; i++)
        {
             
            var menu = children[i];
             
           if(typeof menu == "object" && menu.getClassStyle()=="MenuItem")
            {
                 
                htmlStr += "<tr style=\"width:"+(parseInt(width))+"px;\"><td id=\""+menu.getMenuId()+"\"" +
                 
                " class=\"" +popMenuInstant.normalClass+"\""+
                 
                " οnmοuseοver=\"javascript:window.top._onMenuItemFocus.call(this);" +"\""+
                 
                " οnmοuseοut=\"javascript:window.top._onMenuItemNormal.call(this);" +"\""+
                 
                " οnclick=\"javascript:window.top._onMenuItemClick.call(this);" +"\""+
                 
                "><div>" +menu.getMenuTitle()+"</div></td></tr>";
                 
            }
             
        }
         

        htmlStr += "</table>";
         
        htmlStr += "</div>";
         
		 var popWin =null;
		 

			
		 
		 
        if(parentMenu!=null&&parentMenu.getMenuId()!=null && parentMenu.getMenuId().length>0 )
        {
         		popWin = this.document.parentWindow.createPopup();
            	 
            	popWin.document.createStyleSheet(popMenuInstant.cssFile);
            	 
            	popWin.document.body.innerHTML = htmlStr;
            	 
            	
				if(!popWin.isOpen)
				{
				   popWin.show ((parseInt(this.clientLeft)+parseInt(this.clientWidth)),
				          (parseInt(this.clientTop)+parseInt(this.clientHeight)), width, height, this);
				}
				else
				{
					 popWin.hide();
					 popWin.show ((parseInt(this.clientLeft)+parseInt(this.clientWidth)),
					                     (parseInt(this.clientTop)), width, height, this);
				}
             


        }
         
        else
         
        {
            	 popWin =  window.top.createPopup();
            	 popWin.document.createStyleSheet(popMenuInstant.cssFile);
            	 popWin.document.body.innerHTML = htmlStr;
           
				 
            	 if(!popWin.isOpen)
            	       popWin.show (-5,  parseInt(this.offsetHeight)+2, width, height, this);
            	 else
            	 	{
            	 		   popWin.hide();
            	 		   popWin.show (-5, parseInt(this.offsetHeight)+2, width, height, this);
            	 	}
            	 
         }

    }
     

    };


這樣我們就可以很簡單的來實現頁面的東西了:iframe就是爲了測試是不是可以跨幀。

<div id ="popmenu"></div>
 
<iframe name="mainFreame"  id="mainFreame"  width="1024" height="800"></iframe>

 

是不是有點操作對象的感覺了:

 

<script type="text/javascript">
 
var popMenu = new PopMenu("css/menu.css","normalMenu","focusMenu","menu","200","25");
 

popMenu.addMenuItem("menu1", 1, "Menu 1", "file.gif","");
 
popMenu.addMenuItem("menu2", 2, "Menu 2", "file.gif","");
 
popMenu.addMenuItem("menu3", 3, "Menu 3", "file.gif","");
 
popMenu.addMenuItem("menu4", 4, "Menu 4", "file.gif","");
 

popMenu.addSubMenuItem("menu21", 1, "menu2", "Menu 2-1", "file.gif","http://www.hao123.com","_blank");
 
popMenu.addSubMenuItem("menu22", 2, "menu2", "Menu 2-2", "file.gif","http://www.hao123.com","_self");
 

popMenu.addSubMenuItem("menu211", 1, "menu21", "Menu 2-1-1", "file.gif","http://www.hao123.com","mainFreame");
 
popMenu.addSubMenuItem("menu2111", 1, "menu211", "Menu 2-1-1-1", "file.gif","http://www.163.com","mainFreame");
 
popMenu.addSubMenuItem("menu2112", 2, "menu211", "Menu 2-1-1-2", "file.gif","http://www.163.com","mainFreame");

popMenu.addSubMenuItem("menu21121", 1, "menu2112", "Menu 2-1-1-2-1", "file.gif","http://www.163.com","mainFreame");
 
popMenu.addSubMenuItem("menu21122", 2, "menu2112", "Menu 2-1-1-2-2", "file.gif","http://www.163.com","mainFreame");
 

popMenu.addSubMenuItem("menu221", 2, "menu22", "Menu 2-2-1", "file.gif","http://www.csdn.com","mainFreame");
 
popMenu.addSubMenuItem("menu222", 2, "menu22", "Menu 2-2-1", "file.gif","http://www.csdn.com","mainFreame");
 

popMenu.addSubMenuItem("menu31", 1, "menu3", "Menu 3-1", "file.gif","http://www.baidu.com","mainFreame");
 
popMenu.addSubMenuItem("menu32", 2, "menu3", "Menu 3-2", "file.gif","http://www.baidu.com","mainFreame");
 
popMenu.addSubMenuItem("menu33", 2, "menu3", "Menu 3-3", "file.gif","http://www.baidu.com","mainFreame");
 

popMenu.initTopMenu("popmenu");
 

</script>


效果圖:

 

點擊效果:

 完成,本人只是在探討實現方法和過程,有可能程序不夠完善,讀者見諒。如果想下載源代碼,

請鏈接:http://download.csdn.net/detail/wodetiankong516/4493907

       

         

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章