在JS中做二级菜单时,被一个鼠标移出时隐藏的小问题困扰了很久.

<script>
function Menu(id){
var _this=this;
this.obj=document.getElementById(id);
this.trigger=getFirstChild(this.obj);
this.menuOne=getLastChild(this.obj);
this.menuOneLi=getChildren(this.menuOne);
this.menuOneLiA=[];
this.menuTwo=[]; for(var i=0;i<this.menuOneLi.length;i++){
this.menuOneLiA.push(getFirstChild(this.menuOneLi[i]));
this.menuTwo.push(getLastChild(this.menuOneLi[i]));
}
//隐藏一级菜单
this.menuOne.style.display='none';
//隐藏二级菜单
for(var i=0;i<this.menuTwo.length;i++){
this.menuTwo[i].style.display='none';
}
//为每一个一级菜单的li添加事件
for(var i=0;i<this.menuOneLiA.length;i++){ this.menuOneLiA[i].onmouseover=function(){
//清除计时器
clearTimeout(_this.timer);
//隐藏所有的二级菜单
for(var j=0;j<_this.menuTwo.length;j++){
_this.menuTwo[j].style.display='none';
}
//显示此li对应的二级菜单
getNextElement(this).style.display='block';
}
}
//一级菜单的鼠标移出事件
this.menuOne.onmouseout=function(){
_this.menuOneClear();
}
this.trigger.onmouseover=function(){
_this.showMenuOne();
} }
Menu.prototype.showMenuOne=function(){
clearTimeout(this.timer);
this.menuOne.style.height='auto';
this.menuOne.style.display='block'; }
Menu.prototype.menuOneClear=function(){
var _this=this;
    //关键在于这一句,在开启一个计时器的时候,要清除掉已经开启的上一个计时器,因为计时器是会叠加的
    //如果没有在清掉原有计时器的情况下,开启新的计时器,会导致菜单无论如何都会消失.
clearTimeout(this.timer);
this.timer=setTimeout(function(){
_this.menuOne.style.display='none';
},500);
}
window.onload=function(){
new Menu('header_menu');
}

HTML我就不贴了,主要是看JS的逻辑.
算了,还是贴一下吧!

<div class="header_nav_mid_handler" id="header_menu">
<a href="#" class="header_nav_mid_handler_all" id="header_btn">全部商品分类</a>
<!--隐藏的一级菜单-->
<ul class="header_nav_mid_menu">
<li class="header_nav_mid_menu_li bedroom">
<a href="#" class="header_nav_mid_menu_a">卧室</a>
<ul class="header_nav_mid_list">
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
</ul>
</li>
</ul>
</div>

在上面的JS中我是用的是自己封装的一些获取元素的方法,也贴上来共同讨论

//在IE6下,不支持getElementsByClassName()方法,此方法可以进行兼容处理
function hasClass(node,className){
var class_names=node.className.split(/\s+/);
for(var i=0;i<class_names.length;i++){
if(class_names[i]==className){
return true;
}
}
return false;
} function getByClassName(className){
if(document.getElementsByClassName){
return document.getElementsByClassName(className);
}
var nodes=document.getElementsByTagName('*');
var arr=[];
for(var i=0;i<nodes.length;i++){
if(hasClass(nodes[i],className)){
arr.push(nodes[i]);
}
}
return arr;
}
//获取第一个子元素的兼容方法 OK
function getFirstChild(obj){
if(obj.firstElementChild){
return obj.firstElementChild;
}else{
return obj.firstChild;
}
}
//获取最后一个子元素的兼容方法 OK
function getLastChild(obj){
if(obj.lastElementChild){
return obj.lastElementChild;
}else{
return obj.lastChild;
}
}
//获取preiousSibling的兼容方法 OK
function getPrevElement(obj){
if(obj.previousElementSibling){
return obj.previousElementSibling;
}else{
return obj.previousSibling;
}
}
//获取nextSibling的兼容方法 OK
function getNextElement(obj){
if(obj.nextElementSibling){
return obj.nextElementSibling;
}else{
return obj.nextSibling;
}
}
//获取子元素的方法 OK
function getChildren(obj){
var nodes=obj.childNodes;
var arr=[];
for(var i=0;i<nodes.length;i++){
if(nodes[i].nodeType==1){
arr.push(nodes[i]);
}
}
return arr; }
// ajax的get方法
function Ajax(url,fnSuccess,fnFailed){
var xhr=null;
if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}else{
xhr=new ActiveXObject('Microsoft.XMLHTTP');
}
xhr.open('GET',url,true);
xhr.send();
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
fnSuccess(xhr.responseText);
}else{
if(fnFailed){
fnFailed();
}
}
}
}
}

js中的计时器的更多相关文章

  1. JS中的计时器事件

    JS可以实现很多java代码不易完成的功能.这里学习一些js中的计时器事件. JavaScript 一个设定的时间间隔之后来执行代码,称之为计时事件. 主要通过两个方法来实现: 1.setInterv ...

  2. js中的计时器事件`setTimeout()` 和 `setInterval()`

    js中的计时器事件 在js中,通常会有一些事件,我们需要让它 间隔一段时间之后再发生,或者 每隔一段时间 发生一次,那就需要用到我们js中的计时事件 计时事件主要有两种: setTimeout() - ...

  3. 【转】JS中setTimeout和setInterval的最大延时值详解

    前言 JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.而这篇文中主要给大家介绍的是关于JS中setTi ...

  4. JS中的函数节流throttle详解和优化

    JS中的函数节流throttle详解和优化在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(mousemove),这种事件有一个特点,在一个正常的操作中,有可能在一个短的 ...

  5. Node.js中Process.nextTick()和setImmediate()的区别

    一.Webstrom使用node.js IDE的问题 在区别这两个函数之前来说一下Webstrom使用node.js IDE的问题,在配置Node.js的IDE了,但setImmediate().re ...

  6. Node.js中setTimeout和setInterval的使用

    Node.js和js一样也有计时器,超时计时器.间隔计时器.及时计时器,它们以及process.nextTick(callback)函数来实现事件调度.今天先学下setTimeout和setInter ...

  7. 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?

    https://segmentfault.com/a/1190000012806637 https://www.jianshu.com/p/93d756db8c81 首先,请牢记2点: (1) JS是 ...

  8. js中的this介绍

    今天跟大家一起简单的来了解一下js中一个有趣的东西,this. 在js中我们用面向对象的思想去编写的时候,各个模块之间的变量就不那么容易获取的到了,当然也可以通过闭包的方式拿到其他函数的变量,如果说每 ...

  9. javascript基础入门之js中的结构分支与循环语句

    javascript基础入门之js中的结构分支与循环语句 程序的结构①顺序结构:自上而下:②选择(分支)结构:多条路径,根据不同的条件,只执行其中一个:③循环结构:重复某些代码④配合特定的语句实现选择 ...

随机推荐

  1. Python Virtualenv 虚拟环境

    在python2和python3共存的机器上做开发,要想互不干扰,虚拟环境很重要. Debian7 默认是python2.7.3,装好python3.4.1后怎么建立虚拟环境呢? $ pyvenv m ...

  2. 求可能组合VB源码代写

    输入1-20的整数n,把从1到n的n个整数摆成一个环,使得该环上任意相邻的两个数之和为素数.求出所有可能组合. 专业程序代写c++程序代写

  3. iaas,paas,saas理解

    IaaS.PaaS.SaaS多次看到这几个单词,今天仔细看看来, ​这几个词和云计算相关:1,iaaS,Hardware-as-a-Service,信息,硬件服务,服务器,存储和网络硬件,网络存储,带 ...

  4. [Yii2]Unable to verify your data submission(你提交的资料无法被验证)

    Yii2中,使用form提交数据,会提示: [yii\web\HttpException:400] exception 'yii\web\BadRequestHttpException' with m ...

  5. css3 颜色记

    css3 颜色 opacity 使元素呈现出半透明效果. opacity:alphavalue || inherit alphavalue:默认值为1,可以取0~1任意浮点数.取值为1时,元素完全不透 ...

  6. 软谋在线教育诚招php,java,.net,设计师讲师(可兼职)

    软谋教育专注软件在线教育,依托腾讯课堂.yy课堂授课,在线教授计算机知识,现因业务发展,招聘php,java,.net,设计师讲师各两名,如果您满足以下条件,即可联系我们应聘: 1.相关专业工作经验3 ...

  7. C# 计算文件的 Hash 值

    /// <summary> /// 提供用于计算指定文件哈希值的方法 /// <example>例如计算文件的MD5值: /// <code> /// String ...

  8. Android Wi-Fi基本操作

    从用户角度看,Android Wi-Fi模块自下向上可以看为5层:硬件驱动程序,wpa_suppplicant,JNI,WiFi API,WifiSettings应用程序. 1.wpa_supplic ...

  9. Android简单计算器

    这是很久之前做的,方法很简单,都是一些基础的,不足的是还有很多功能不够. activity_main.xml布局: <LinearLayout xmlns:android="http: ...

  10. IOS TextField设置大全

    //初始化textfield并设置位置及大小  //设置边框样式,只有设置了才会显示边框样式     text.borderStyle = UITextBorderStyleRoundedRect; ...