我想写一个把多层UL转换成树形菜单的函数 在IE下以下正常 (个别地方用了JQuery的查询)
javascriptvar $pl = {
/**
* 事件绑定
* @param {Object} o 要绑定到的控件
* @param {String} ev 要绑定到的事件
* @param {Function} fn 要绑定到事件的方法
* return {Object} o 已绑定完成的控件
*/
bind: function(o, ev, fn){
if (document.all) {
o.attachEvent('on' + ev, fn);
}
else {
o.addEventListener(ev, fn, false);
}
return o;
}
};
/**
* 获取或判断目标的标签类型
* @param {Object} element 要获取类型的目标
* @param {Object} CompareTag 判定值(不区分大小写)
*/
var TagName = function(element, CompareTag){
if (CompareTag && typeof(CompareTag) === "string") {
return (element.tagName || element.nodeName).toLocaleLowerCase() === CompareTag.toLocaleLowerCase();
}
else {
return element.tagName || element.nodeName;
}
};/**
* IE FF 兼容工具
* @param {Object} element
*/
var tool = function(element, eType){ return new tool.fn.init(element, eType);
};
tool.fn = tool.prototype = { /**
* 包装初始化Element
* @param {Object} element element
* @param {Object} eType 节点类型
*/
init: function(element, eType){
if (eType === "e") {
this.context = this[0] = e = element || window.event;
this.srcElement = this.target = tool(e.srcElement || e.target);
}
else {
this.context = this[0] = element;
this.tagName = this[0].tagName || this[0].nodeName;
this.style = this[0].style;
}
return this;
},
parent: function(){
return tool(this[0].parentElement || this[0].parentNode);
},
child: function(index){
var childArray = this[0].children || this[0].childNode;
if (index) {
return tool(childArray[index] || childArray[index]);
}
else {
return childArray;
}
},
attribute: function(attributeName){
return tool(this[0][attributeName] || this[0].getAttribute(attributeName));
}
};
tool.fn.init.prototype = tool.fn;
/**
* 初始化多层UL列表为可伸缩列表
* @param {Object} menu 要初始化的UL(JQuery选择器)
*/
var MultilayerMenu = function(menu){
if (typeof(menu) === "string") {
menu = $(menu)[0];
Init(menu);
}
/**
* 初始化UL为可伸缩列表
* @param {Object} ul 要初始化的UL对象
* @param {Object} deep 当前列表深度,初始为0
*/
function Init(ul, deep){
var ul_items = ul.children;
if (deep && deep > 0) {
ul.style.display = "none";
}
else {
deep = 0;
}
//遍历ul内的子成员 li
for (var i = 0; i < ul_items.length; i++) {
var li_items = ul_items[i].children;
var childUl = 0;
//若当前li内子成员数为0
if (li_items.length === 0) {
$pl.bind(ul_items[i], "mouseover", hover);
$pl.bind(ul_items[i], "mouseleave", out);
$pl.bind(ul_items[i], "mouseout", out);
}
else {
//遍历li内的子成员
for (var j = li_items.length - 1; j >= 0; j--) {
$pl.bind(li_items[j], "mouseover", hover);
$pl.bind(li_items[j], "mouseleave", out);
$pl.bind(li_items[j], "mouseout", out);
if (TagName(li_items[j], "ul")) {
Init(li_items[j], deep + 1);
}
else {
var tmp = li_items[j];
$pl.bind(li_items[j], "mouseover", show);
if (childUl === 0) {
$pl.bind(ul_items[i], "mouseleave", hid);
$pl.bind(ul_items[i], "mouseout", hid);
childUl = 1;
}
}
}
}
}
}
/**
* 鼠标离开列表项触发事件
* @param {Object} e 事件参数
*/
function out(e){
var e = tool(e, "e");
e.target.style.backgroundColor = "#CCCCCC";
}
/**
* 鼠标悬停列表项触发事件
* @param {Object} e
*/
function hover(e){
var e = tool(e, "e");
e.target.style.backgroundColor = "#FFCCCC";
}
/**
* 展开子列表事件
* @param {Object} e
*/
function show(e){
var e = tool(e, "e");
var tt = e.target;
var pp = tt.parentNode;
var liItems = e.target.parent().child();
for (var i = 0; i < liItems.length; i++) {
liItems[i].style.display = "block";
}
}
/**
* 隐藏子列表事件
* @param {Object} e
*/
function hid(e){
var e = tool(e, "e");
var liItems = e.target.child();
for (var i = 0; i < liItems.length; i++) {
if (TagName(liItems[i], "ul")) {
liItems[i].style.display = "none";
}
}
}
};
下面是调用的页面<!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>
<script type="text/javascript" src="jquery-1.4.2.min.js">
</script>
<script type="text/javascript" src="page.js">
</script>
<style type="text/css">
#abc{
width:400px;
}
#abc li{
background:#CCC;
}
</style>
</head>
<body>
<ul id="abc">
<li>
<span>BBBBBBBBBBBBBBBBBBBB</span>
<ul>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
</ul>
</li>
</ul>
</body>
</html>
<script type="text/javascript">
MultilayerMenu("#abc");
</script>
javascriptvar $pl = {
/**
* 事件绑定
* @param {Object} o 要绑定到的控件
* @param {String} ev 要绑定到的事件
* @param {Function} fn 要绑定到事件的方法
* return {Object} o 已绑定完成的控件
*/
bind: function(o, ev, fn){
if (document.all) {
o.attachEvent('on' + ev, fn);
}
else {
o.addEventListener(ev, fn, false);
}
return o;
}
};
/**
* 获取或判断目标的标签类型
* @param {Object} element 要获取类型的目标
* @param {Object} CompareTag 判定值(不区分大小写)
*/
var TagName = function(element, CompareTag){
if (CompareTag && typeof(CompareTag) === "string") {
return (element.tagName || element.nodeName).toLocaleLowerCase() === CompareTag.toLocaleLowerCase();
}
else {
return element.tagName || element.nodeName;
}
};/**
* IE FF 兼容工具
* @param {Object} element
*/
var tool = function(element, eType){ return new tool.fn.init(element, eType);
};
tool.fn = tool.prototype = { /**
* 包装初始化Element
* @param {Object} element element
* @param {Object} eType 节点类型
*/
init: function(element, eType){
if (eType === "e") {
this.context = this[0] = e = element || window.event;
this.srcElement = this.target = tool(e.srcElement || e.target);
}
else {
this.context = this[0] = element;
this.tagName = this[0].tagName || this[0].nodeName;
this.style = this[0].style;
}
return this;
},
parent: function(){
return tool(this[0].parentElement || this[0].parentNode);
},
child: function(index){
var childArray = this[0].children || this[0].childNode;
if (index) {
return tool(childArray[index] || childArray[index]);
}
else {
return childArray;
}
},
attribute: function(attributeName){
return tool(this[0][attributeName] || this[0].getAttribute(attributeName));
}
};
tool.fn.init.prototype = tool.fn;
/**
* 初始化多层UL列表为可伸缩列表
* @param {Object} menu 要初始化的UL(JQuery选择器)
*/
var MultilayerMenu = function(menu){
if (typeof(menu) === "string") {
menu = $(menu)[0];
Init(menu);
}
/**
* 初始化UL为可伸缩列表
* @param {Object} ul 要初始化的UL对象
* @param {Object} deep 当前列表深度,初始为0
*/
function Init(ul, deep){
var ul_items = ul.children;
if (deep && deep > 0) {
ul.style.display = "none";
}
else {
deep = 0;
}
//遍历ul内的子成员 li
for (var i = 0; i < ul_items.length; i++) {
var li_items = ul_items[i].children;
var childUl = 0;
//若当前li内子成员数为0
if (li_items.length === 0) {
$pl.bind(ul_items[i], "mouseover", hover);
$pl.bind(ul_items[i], "mouseleave", out);
$pl.bind(ul_items[i], "mouseout", out);
}
else {
//遍历li内的子成员
for (var j = li_items.length - 1; j >= 0; j--) {
$pl.bind(li_items[j], "mouseover", hover);
$pl.bind(li_items[j], "mouseleave", out);
$pl.bind(li_items[j], "mouseout", out);
if (TagName(li_items[j], "ul")) {
Init(li_items[j], deep + 1);
}
else {
var tmp = li_items[j];
$pl.bind(li_items[j], "mouseover", show);
if (childUl === 0) {
$pl.bind(ul_items[i], "mouseleave", hid);
$pl.bind(ul_items[i], "mouseout", hid);
childUl = 1;
}
}
}
}
}
}
/**
* 鼠标离开列表项触发事件
* @param {Object} e 事件参数
*/
function out(e){
var e = tool(e, "e");
e.target.style.backgroundColor = "#CCCCCC";
}
/**
* 鼠标悬停列表项触发事件
* @param {Object} e
*/
function hover(e){
var e = tool(e, "e");
e.target.style.backgroundColor = "#FFCCCC";
}
/**
* 展开子列表事件
* @param {Object} e
*/
function show(e){
var e = tool(e, "e");
var tt = e.target;
var pp = tt.parentNode;
var liItems = e.target.parent().child();
for (var i = 0; i < liItems.length; i++) {
liItems[i].style.display = "block";
}
}
/**
* 隐藏子列表事件
* @param {Object} e
*/
function hid(e){
var e = tool(e, "e");
var liItems = e.target.child();
for (var i = 0; i < liItems.length; i++) {
if (TagName(liItems[i], "ul")) {
liItems[i].style.display = "none";
}
}
}
};
下面是调用的页面<!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>
<script type="text/javascript" src="jquery-1.4.2.min.js">
</script>
<script type="text/javascript" src="page.js">
</script>
<style type="text/css">
#abc{
width:400px;
}
#abc li{
background:#CCC;
}
</style>
</head>
<body>
<ul id="abc">
<li>
<span>BBBBBBBBBBBBBBBBBBBB</span>
<ul>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAAAAAA
</li>
</ul>
</li>
</ul>
</body>
</html>
<script type="text/javascript">
MultilayerMenu("#abc");
</script>
IE下在离开span的时候,触发了2个事件, span的onmouseout,和 span上一级li的onmouseout但在FF下只触发了span的onmouseout,所以没有隐藏,可能要加入延迟处理` 检测鼠标是否还停留在ul中`