跨帧 (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
属行描述值描述
Idmenuitem 的唯一标示可以任意定义,但是得保证唯一
index序列,用与所有menuitem排序,扩展功能一般从0开始不断增加
titlemenuitem标题,描述任意字符串
properties属性集合,扩展使用存储任意其他信息
parentId父menuitem的Id, 
childrenmenuitem的子按钮 
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.youkuaiyun.com/detail/wodetiankong516/4493907

       

         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值