javascript html js many custom class linkage floating menu, js produced menu

Procedures for Principle (recommended reading by reference to the code):

Procedures are based on traditional floating menu to expand from here, let me talk about some more crucial or useful places:

【Function】 Delay
A lot of people understand this is to set up a setTimeout timer, there are two timer, are separately containers timer timer and menu.
Timer is the role of containers move the mouse outside the container when the hidden containers, are difficult to judge how the current mouse are not in the container outside.
General approach is to set up a bool parameter, mouseout, when set to false, mouseover, when set to true (or the other way around), and then judge based on this parameter,
However, this method will not work in this, after the menu container object will trigger container mouseout,
Case because of bubbling, the menu object will trigger the mouseout container mouseout.
For example:

<div>
<div>
</div>
</div>


Recommend a method here, using the contains (ff are compareDocumentPosition) method.
The method is to do my picture slide show effects of muxrwc taught me:

var isIn = false, oT = Event(e).relatedTarget;
Each(oThis.Container, function(o, i){ if(o.contains ? o.contains(oT) || o == oT : o.compareDocumentPosition(oT) & 16){ isIn = true; } });


Detailed reference content like lightbox effects, while the menu timer on nothing in particular, is used to set the menu content.

【Location】 floating
Apart from the mother container menu are fixed, and sub-menu of the container is absolutely positioning, positioning the key is fit to obtain the left and top value.
First of all, to get a menu on the left and top value.
Menu because of the mother is a relative positioning, it is necessary to check that it's absolute left and top value on the value must be up layer by layer, and add up to:

while (o.offsetParent) { o = o.offsetParent; iLeft += o.offsetLeft; iTop += o.offsetTop; }


Made up a menu of left and top value, then the corresponding displacement can be a:

switch (position.toLowerCase()) {
    case "up" :
        iTop -= oContainer.offsetHeight;
        break;
    case "down" :
        iTop += o.offsetHeight;
        break;
    case "left" :
        iLeft -= oContainer.offsetWidth;
        break;
    case "right" :
    default :
        iLeft += o.offsetWidth;
}
here to note that if none of the display as it would not be able to obtain offset values,
So in order to hide at the status can be targeted, it is necessary to use visibility to hide.
Of course, if the display can show the re-positioning, but it will appear the moment the situation of mobile, it is not recommended.

Automatic generation of container object 【】
Apart from the first container object, when found in containers not enough will, in accordance with the previous container to generate a new container.
I want to start using cloneNode, but because of the object in case there is so such use should not only build a manual.

First of all, before a container in accordance with the tagName to create a new container,
In order to use the same style, copy cssText (This is the muxrwc told me) and the className to the new containers,
And with IniContainer () function you can set the:

var oPre = this.Container[i-1], oNew = document.body.appendChild(document.createElement(oPre.tagName));
oNew.style.cssText = oPre.style.cssText; oNew.className = oPre.className;
this.IniContainer(this.Container[i] = oNew, true);


【Linkage】 many class
Multi-level interaction, the key is how to get sub-menu structure and the basis of this sub-menu to generate the menu structure of the object.
First talk about the menu structure, are similar to this structure:

json know
[
    {'txt': '1' },
    {'txt': '2', 'position': 'down', 'menu': [
        {'txt': '2_1'},
        {'txt': '2_2'}
    ]}
]
should all know what are, js a target structure:
txt contents are displayed may also be a html, when it will be inserted into innerHTML;
position is the position, can be "right" (default), "down", "up", "left", the floating position to set the basis of this value;
menu are the next level of menu structure.
Can be seen similar to a n-dimensional array, are similar attention.

How it was in accordance with the menu structure of the current menu Submenu it?
First of all objects from the menu onmouseover begins,
At the onmouseover menu a Medium, to do is re-instated and re-set the menu style (this later).
Settings menu also includes the provision of an index property index to record the current menu container index (number of containers the first menu),
Here is rather tricky container index menu menu structure with the corresponding index in the menu are the same (the back will be used),
_index Containers and are the current index (the first of several containers), this same index can also be used to indicate the current menu at the first class a few.
_onmenu Would also like to set the menu for the current object, its location at the floating check needed.
And you can use Set () procedure to set up a menu:

oThis._timerMenu = setTimeout(function(){
    oContainer.index = i; oThis._onmenu = oMenu; oThis._index = index + 1;  oThis.Set();
}, oThis.Delay);
in Set () procedure is to first hide the first select, This is a common practice:

Each(document.getElementsByTagName("select"), function(o){ o.style.visibility = "hidden"; })


Setting a parameter, as the index of the collection containers, you can directly start from the second class, so i set the initial value of 1.
A while to repeatedly check sub-menu structure (menu), until there are no sub-menu (menu length is 0) or to obtain a sub-menu structure (_index == i).
There is no use for, because while I think the more appropriate, or perhaps for better.
Here, apart from sub-menu structure should be made to obtain sub-menu positioning (position).
If the container is not enough during the period will be automatically added.
Made sub-menu structure and positioning, you can use SetContainer () set up a container at a lower level menu:

var i = 1;
while (menu.length > 0) {
    // Gets the child menu structure and positioning  
    
    // If the container is not under previous automatically added  
    
    // Set up the next level of menu  
    if(this._index == i++){ this.SetContainer(menu, position); break; }
}

Procedures SetContainer () with few skills, the first set of containers associated with the use of SetMenu () to set the menu object,
And are the positioning and display containers, and finally Do not need to hide the containers, this part is not illustrated.

Want to talk about are the SetMenu () procedure, its role is to set the menu under the menu structure on the object and container.
According to the menu structure of each element to create a menu object, innerHTML elements txt property, set mouseover case, the last appendChild to the container.
More important here are mouseover events at mouseover case will be re-instated and re-set the menu style,
When the trigger mouseover on the case back to the beginning of one of the "object from the menu onmouseover about" (reincarnation !-_-) 。
I do not know you do not halo halo, since the beginning of me is more of a halo.

【Focus style settings】
Say here is SetMenu () to re-set the style part.
Procedures can be seen in the mouse menu and specify the parent menu will use another definition of the style to display.
General practice is at mouseover and mouseout set style,
But not here, because there is delay, when the fast-moving mouse to another menu, and then moved to the original menu, the
Style does not automatically set up on the back, so had no choice but to re-set every time mouseover each container style menu.
Temporarily can not find a better way, so remember to inform me Oh o (_ _) o

Each(oThis.Container, function(o, i){
    if(i > index) return;
    Each(o.getElementsByTagName(oThis.Tag), function(o){ o.className = oThis.Class; });
    if(i == index){
        oMenu.className = oThis.onClass;
    } else if(o.index >= 0) {
        o.getElementsByTagName(oThis.Tag)[o.index].className = oThis.onClass;
    } else return;
});


】 【Extensions
Have these attributes can be set:
Position: The default location (up, down, left, right);
Tag: default tag generated;
Class: default style;
onClass: focus style;
Delay: delay value (ms);

The time being there is this two methods:
Add (menu): Add menu, parameters are a menu structure;
Delete (index): delete the menu, the menu parameters are indexed;

_menu Can also directly modify the property, how to expand your imagination on the look.

Procedures for testing:
Parameter 1 is a collection of containers:

var arrContainer=["idMenu1"]; 


Parameter 2 is a menu structure:

var menu = [
    {'txt': '1 <a href="http://shundebk.cn/">link</a>' },
    {'txt': '2  →  ', 'menu': [
        {'txt': '2_1'},
        {'txt': '2_2'}
    ]},
    {'txt': '3  →  ', 'menu': [
        {'txt': '3_1  ↑  ', 'position': 'up', 'menu': [
            {'txt': '3_1_1'},
            {'txt': '3_1_2'}
        ]},
        {'txt': '3_2'}
    ]},
    {'txt': '4  →  ', 'menu': [
        {'txt': '4_1  ↓  ', 'position': 'down', 'menu': [
            {'txt': '4_1_1  →  ', 'menu': [
                {'txt': '4_1_1_1'}
            ]}
        ]}
    ]},
    {'txt': '5  →  ', 'menu': [
        {'txt': '5_1  →  ', 'menu': [
            {'txt': '5_1_1  ↓  ', 'position': 'down', 'menu': [
                {'txt': '5_1_1_1  ←  ', 'position': 'left', 'menu': [
                    {'txt': '5_1_1_1_1'}
                ]}
            ]}
        ]}
    ]}
];

3 parameters are some settings:

{ Delay: 200, onClass: "on" }


Instantiated object:

new CascadeMenu(arrContainer, arrMenu, { Delay: 200, onClass: "on" });


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>JavaScript  Custom multilevel linkage floating menu  </title>
<script type="text/javascript">
var $ = function (id) {
	return "string" == typeof id ? document.getElementById(id) : id;
};

function addEventHandler(oTarget, sEventType, fnHandler) {
	if (oTarget.addEventListener) {
		oTarget.addEventListener(sEventType, fnHandler, false);
	} else if (oTarget.attachEvent) {
		oTarget.attachEvent("on" + sEventType, fnHandler);
	} else {
		oTarget["on" + sEventType] = fnHandler;
	}
};

function Event(e){
	var oEvent = document.all ? window.event : e;
	if (document.all) {
		if(oEvent.type == "mouseout") {
			oEvent.relatedTarget = oEvent.toElement;
		}else if(oEvent.type == "mouseover") {
			oEvent.relatedTarget = oEvent.fromElement;
		}
		
		oEvent.stopPropagation = function() { this.cancelBubble = true; }
	}
	return oEvent;
}

function Each(list, fun){
	for (var i = 0, len = list.length; i < len; i++) { fun(list[i], i); }
};


var Class = {
  create: function() {
	return function() {
	  this.initialize.apply(this, arguments);
	}
  }
}

Object.extend = function(destination, source) {
	for (var property in source) {
		destination[property] = source[property];
	}
	return destination;
}


var CascadeMenu = Class.create();
CascadeMenu.prototype = {
  // Initializes the object  ( The container collection  ,  The menu structure  )
  initialize: function(arrContainer, arrMenu, options) {
	if(arrContainer.length <= 0 || arrMenu.lenght <= 0) return;
	
	var oThis = this;
	
	this._timerContainer = null;// Container for the timer  
	this._timerMenu = null;// Menu timer  
	this._onmenu = null;// Current menu object  
	this._index = -1;// To set the container's index  
	
	this.Container = [];// The container collection  
	this._menu = arrMenu;// The menu structure  
	
	this.SetOptions(options);
	
	this.Position = this.options.Position || "right";
	this.Delay = parseInt(this.options.Delay) || 0;
	this.Class = this.options.Class || "";
	this.onClass = this.options.onClass || this.Class;
	this.Tag = this.options.Tag;
	
	// Sets the container  
	Each(arrContainer, function(o, i){ oThis.IniContainer(oThis.Container[i] = (o = $(o)), i > 0); });
	
	this.Ini();
  },
  // Set default property  
  SetOptions: function(options) {
	this.options = {// The default value  
		Position:	"right",// The default location  (up,down,left,right)
		Tag:		"div",// The default generated labels  
		Class:		"",// The default style  
		onClass:	"",// Focus style  
		Delay:		0// Delay value  ( Microseconds  )
	};
	Object.extend(this.options, options || {});
  },
  // Initialize the container  ( The container collection  ,  If the sub menu containers  )
  IniContainer: function(container, bChild) {
	var oThis = this;
	addEventHandler(container, "mouseover", function(){ clearTimeout(oThis._timerContainer); });
	addEventHandler(container, "mouseout", function(e){
		// Whether within the menu  
		var isIn = false, oT = Event(e).relatedTarget;
		Each(oThis.Container, function(o, i){ if(o.contains ? o.contains(oT) || o == oT : o.compareDocumentPosition(oT) & 16){ isIn = true; } });
		// Hidden in menus  
		if(!isIn){
			clearTimeout(oThis._timerContainer); clearTimeout(oThis._timerMenu);
			oThis._timerContainer = setTimeout(function(){ oThis.Hide(); }, oThis.Delay);
		}
	});
	// Reset an index  
	container.index = -1;
	// Sets the sub menu containers  
	if (bChild) { container.style.position = "absolute"; container.style.visibility = "hidden"; }
  },
  // Initialize the first container  
  Ini: function() {
	this.Container[0].innerHTML = ""; this._index = 0; this.SetMenu(this._menu);
  },
  // Global settings  
  Set: function() {
	// Hide select  
	Each(document.getElementsByTagName("select"), function(o){ o.style.visibility = "hidden"; })
	
	var menu = this._menu;
	// The first does not require processing so start at 1  
	var i = 1;
	while (menu.length > 0) {
		// Gets the child menu structure and positioning  
		var iC = this.Container[i-1].index, position = this.Position;
		if(iC >= 0){
			// Here is the first fetch position then set menu  
			position = menu[iC].position || this.Position; menu = menu[iC].menu || [];
		} else { menu = []; }
		
		// If the container is not under previous automatically added  
		if(!this.Container[i]){
			var oPre = this.Container[i-1], oNew = document.body.appendChild(document.createElement(oPre.tagName));
			oNew.style.cssText = oPre.style.cssText; oNew.className = oPre.className;
			this.IniContainer(this.Container[i] = oNew, true);
		}
		
		// Set up the next level of menu  
		if(this._index == i++){ this.SetContainer(menu, position); break; }
	}
  },
  // Container settings  ( The menu structure  ,  Location  )
  SetContainer: function(menu, position) {
	var oContainer = this.Container[this._index];
	
	// Sets the container  
	oContainer.innerHTML = ""; oContainer.index = -1; oContainer.style.visibility = "hidden";
	
	if(menu.length > 0){
		// Settings menu  
		this.SetMenu(menu);
		
		// Container positioning  
		//offset The value is biased, it is important to note that  
		var o = this._onmenu, iLeft = o.offsetLeft, iTop = o.offsetTop;
		// Note that if you display to none, not offset values, so you want to use visibility  
		switch (position.toLowerCase()) {
			case "up" :
				iTop -= oContainer.offsetHeight;
				break;
			case "down" :
				iTop += o.offsetHeight;
				break;
			case "left" :
				iLeft -= oContainer.offsetWidth;
				break;
			case "right" :
			default :
				iLeft += o.offsetWidth;
		}
		while (o.offsetParent) { o = o.offsetParent; iLeft += o.offsetLeft; iTop += o.offsetTop; }
		oContainer.style.left = iLeft + "px"; oContainer.style.top = iTop + "px";
		oContainer.style.visibility = "visible";
	}
	
	// Hide unwanted container  
	for(var i = this._index + 1, len = this.Container.length; i < len; i++){ this.Container[i].style.visibility = "hidden";  }
  },
  // The menu settings  ( The menu structure  )
  SetMenu: function(menu) {
	var oThis = this, index = this._index, oContainer = this.Container[index];
	Each(menu, function(o, i){
		var oMenu = document.createElement(oThis.Tag);
		oMenu.innerHTML = o.txt;
		oMenu.onmouseover = function(){
			clearTimeout(oThis._timerMenu);
			
			// To reset the menu  
			oThis._timerMenu = setTimeout(function(){
				oContainer.index = i; oThis._onmenu = oMenu; oThis._index = index + 1;  oThis.Set();
			}, oThis.Delay);
			
			// Reset styles  
			// To resolve time after style question each time are all reset  
			Each(oThis.Container, function(o, i){
				if(i > index) return;
				Each(o.getElementsByTagName(oThis.Tag), function(o){ o.className = oThis.Class; });
				if(i == index){
					oMenu.className = oThis.onClass;
				} else if(o.index >= 0) {
					o.getElementsByTagName(oThis.Tag)[o.index].className = oThis.onClass;
				} else return;
			});
		}
		oContainer.appendChild(oMenu);
	});	
  },
  // To hide the menu  
  Hide: function() {
	var oThis = this;
	// In addition to the first one hides  
	Each(this.Container, function(o, i){
		if(i == 0){
			Each(o.getElementsByTagName(oThis.Tag), function(o, i){ o.className = oThis.Class; })
		} else { o.style.visibility = "hidden"; }
		o.index = -1;
	});
	
	// Displays the select  
	Each(document.getElementsByTagName("select"), function(o){ o.style.visibility = "visible"; })
  },
  // Add a menu  ( A menu structure  )
  Add: function(arrMenu) {
	this._menu.push(arrMenu); this.Ini();
  },
  // Delete a menu  
  Delete: function(index) {
	if(index < 0 || index >= this._menu.length) return;
	for(var i = index, len = this._menu.length - 1; i < len; i++){ this._menu[i] = this._menu[i + 1]; }
		this._menu.pop(); this.Ini();
  }
};


window.onload=function(){
	
	var menu = [
		{'txt': '1 <a href="http://shundebk.cn/">link</a>' },
		{'txt': '2  →  ', 'menu': [
			{'txt': '2_1'},
			{'txt': '2_2'}
		]},
		{'txt': '3  →  ', 'menu': [
			{'txt': '3_1  ↑  ', 'position': 'up', 'menu': [
				{'txt': '3_1_1'},
				{'txt': '3_1_2'}
			]},
			{'txt': '3_2'}
		]},
		{'txt': '4  →  ', 'menu': [
			{'txt': '4_1  ↓  ', 'position': 'down', 'menu': [
				{'txt': '4_1_1  →  ', 'menu': [
					{'txt': '4_1_1_1'}
				]}
			]}
		]},
		{'txt': '5  →  ', 'menu': [
			{'txt': '5_1  →  ', 'menu': [
				{'txt': '5_1_1  ↓  ', 'position': 'down', 'menu': [
					{'txt': '5_1_1_1  ←  ', 'position': 'left', 'menu': [
						{'txt': '5_1_1_1_1'}
					]}
				]}
			]}
		]}
	];
	
	var container=["idMenu1"];
	
	var cs = new CascadeMenu(container, menu, { Delay: 200, onClass: "on" });
	
	////////////////test2
	
	var menu2 = [
		{'txt': '<a href="#">1  ↓  </a>', 'position': 'down', 'menu': [
			{'txt': '<a href="#">1_1</a>'},
			{'txt': '<a href="#">1_2</a>'}
		]},
		{'txt': '<a href="#">2  ↓  </a>', 'position': 'down', 'menu': [
			{'txt': '<a href="#">2_1</a>'},
			{'txt': '<a href="#">2_2  →  </a>', 'menu': [
				{'txt': '<a href="#">2_2_1</a>'},
				{'txt': '<a href="#">2_2_2</a>'}
			]}
		]},
		{'txt': '<a href="#">3  ↓  </a>', 'position': 'down', 'menu': [
			{'txt': '<a href="#">3_1  →  </a>', 'menu': [
				{'txt': '<a href="#">3_1_1  →  </a>', 'menu': [
					{'txt': '<a href="#">3_1_1_1</a>'}
				]}
			]}
		]}
	];
	
	var container2=["idMenu2", "idMenu2_1", "idMenu2_2", "idMenu2_3", "idMenu2_4", "idMenu2_5", "idMenu2_6"];
	
	var cs2 = new CascadeMenu(container2, menu2, { Delay: 200, onClass: "on" });
	
	$("btnA").onclick=function(){cs2.Delay=0;}
	$("btnD").onclick=function(){cs2.Delay=500;}
	
	$("btnB").onclick=function(){
		cs2.Add(
			{'txt': '<a href="#">+  ↓  </a>', 'position': 'down', 'menu': [
				{'txt': '<a href="#">+_1  ←  </a>', 'position': 'left', 'menu': [
					{'txt': '<a href="#">+_1_1  ↓  </a>', 'position': 'down', 'menu': [
						{'txt': '<a href="#">+_1_1_1  →  </a>', 'menu': [
							{'txt': '<a href="#">+_1  ↓  </a>', 'position': 'down', 'menu': [
								{'txt': '<a href="#">+_1_1_1  →  </a>', 'menu': [
									{'txt': '<a href="#"> ★  </a>'}
								]}
							]}
						]}
					]}
				]}
			]}
		)
	}
	
	$("btnC").onclick=function(){
		cs2.Delete(1)
	}
}
</script>
<style type="text/css">
.container {
	width:100px;
}
.container div {
	width:100px;
	background:#CCCCCC;
	line-height:30px;
	border:1px solid #000000;
}
.on {
	font-weight:bold;
}
.container2 {
	width:100px;
	text-align:center;
}
.container2 div {
	width:100px;
	line-height:30px;
}
.container2 a {
	text-decoration:none;
	display:block;
	border:1px solid #d4d4d3;
	background:#e6e6e6;
	color:#000000;
}
.container2 .on a {
	background:#ffebac;
	color:#982e00;
	border-color:#ffb200;
}
#idMenu2 {
	clear:both;
	width:auto;
}
#idMenu2 div {
	float:left;
}
#idMenu2_6 a {
	background-color:red;
	border-color:red;
	color:#ffb200;
}
</style>
</head>
<body>
<div></div>
<br />
<br />
<br />
<div>
  <input type="button" value=" Add a menu  " />
  <input type="button" value=" Reduce menu  ( The second  )" />
  <input type="button" value=" Do not delay  " />
  <input type="button" value=" Delay 500  " />
</div>
<br />
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</body>
</html>


Transfer from: http://www.cnblogs.com/cloudgamer/archive/2008/06/28/1231557.html #

Black hair: http://heisetoufa.javaeye.com/
  • del.icio.us
  • StumbleUpon
  • Digg
  • TwitThis
  • Mixx
  • Technorati
  • Facebook
  • NewsVine
  • Reddit
  • Google
  • LinkedIn
  • YahooMyWeb

Related Posts of javascript html js many custom class linkage floating menu, js produced menu

  • Hibernate configuration parameters hibernate.hbm2ddl.auto

    Hibernate in the configuration file: <properties> <property name="hibernate.hbm2ddl.auto" value="create" /> </ properties> Parameter Description: validate load hibernate, the authentication to create a database t ...

  • Build flex + spring + blazeds + hibernate application

    Build flex + spring + blazeds + hibernate application First, set up the project blazeds 1, will blazeds.war extract to a directory, such as: myflex /; 2, set up java works were such as: MyFlex, in the orientation of selection create project from exis ...

  • Hibernate connection pool configuration

    Hibernate connection pool configuration <! - Jdbc -> <property name="connection.driver_class"> oracle.jdbc.driver.OracleDriver </ property> <property name="connection.url"> jdbc: oracle: thin: @ 10.203.14.1 ...

  • hibernate to use the principle of

    The use of hibernate, implementation of data persistence. Has the following several processes. One configuration database connection information. Hibernate.config 2 configuration mapping. 3 use: the use of the process are the following steps: 3.1: Ge ...

  • hibernate generic generic DAO

    hibernate generic generic DAO

  • can not be represented as java.sql.Timestamp

    Development of procedures for the use of hibernate when, some time there is no need to fill in the fields, but after the hibernate query time reported "Java.sql.SQLException: Value'0000-00-00 'can not be represented as java.sql.Timestamp ...

  • Struts2 + hibernate + spring problem user log in

    dao layer services layer action jsp <tr> <td align="center"> <b> user name: </ b> </ td> <td> <s: textfield name = "czyNumber" cssClass = "textstyle" theme = "simple" size = &q

  • Hibernate secondary cache

    Hibernate cache: 2-bit cache, also known as process-level cache or SessionFactory level cache, secondary cache can be shared by all of the session Cache configuration and the use of: Will echcache.xml (the document code in hibernate package directory ...

  • Hibernate's lazy strategy

    hibernate Lazy strategy can be used in: <class> tag, it can be true / false Tags can <PROPERTY> values true / false type of necessary tools to enhance <set> <list> can tag values true / false / extra <many-to-one> <on ...

Leave a Reply

Recent
Recent Entries
Tag Cloud
Random Entries