js中的计时器
在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中的计时器的更多相关文章
- JS中的计时器事件
JS可以实现很多java代码不易完成的功能.这里学习一些js中的计时器事件. JavaScript 一个设定的时间间隔之后来执行代码,称之为计时事件. 主要通过两个方法来实现: 1.setInterv ...
- js中的计时器事件`setTimeout()` 和 `setInterval()`
js中的计时器事件 在js中,通常会有一些事件,我们需要让它 间隔一段时间之后再发生,或者 每隔一段时间 发生一次,那就需要用到我们js中的计时事件 计时事件主要有两种: setTimeout() - ...
- 【转】JS中setTimeout和setInterval的最大延时值详解
前言 JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.而这篇文中主要给大家介绍的是关于JS中setTi ...
- JS中的函数节流throttle详解和优化
JS中的函数节流throttle详解和优化在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(mousemove),这种事件有一个特点,在一个正常的操作中,有可能在一个短的 ...
- Node.js中Process.nextTick()和setImmediate()的区别
一.Webstrom使用node.js IDE的问题 在区别这两个函数之前来说一下Webstrom使用node.js IDE的问题,在配置Node.js的IDE了,但setImmediate().re ...
- Node.js中setTimeout和setInterval的使用
Node.js和js一样也有计时器,超时计时器.间隔计时器.及时计时器,它们以及process.nextTick(callback)函数来实现事件调度.今天先学下setTimeout和setInter ...
- 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?
https://segmentfault.com/a/1190000012806637 https://www.jianshu.com/p/93d756db8c81 首先,请牢记2点: (1) JS是 ...
- js中的this介绍
今天跟大家一起简单的来了解一下js中一个有趣的东西,this. 在js中我们用面向对象的思想去编写的时候,各个模块之间的变量就不那么容易获取的到了,当然也可以通过闭包的方式拿到其他函数的变量,如果说每 ...
- javascript基础入门之js中的结构分支与循环语句
javascript基础入门之js中的结构分支与循环语句 程序的结构①顺序结构:自上而下:②选择(分支)结构:多条路径,根据不同的条件,只执行其中一个:③循环结构:重复某些代码④配合特定的语句实现选择 ...
随机推荐
- iOS之Xcode8 Auto Layout新特性
目录 1.Incrementally Adopting Auto Layout 2.Design and Runtime Constraints 3.NSGridView 4.Layout Feedb ...
- php核心知识要点
Php:脚本语言,网站建设,服务器端运行 PHP定义:一种服务器端的 HTML 脚本/编程语言,是一种简单的.面向对象的.解释型的.健壮的.安全的.性能非常之高的.独立于架构的.可移植的.动态的脚本语 ...
- Objective-C ,ios,iphone开发基础:快速实现一个简单的图片查看器
新建一个single view 工程: 关闭ARC , 在.xib视图文件上拖放一个UIImageView 两个UIButton ,一个UISlider ,布局如图. 并为他们连线, UIImage ...
- AVL树的插入操作(旋转)图解
=================================================================== AVL树的概念 在说AVL树的概念之前,我们需要清楚 ...
- DAG的动态规划 (UVA 1025 A Spy in the Metro)
第一遍,刘汝佳提示+题解:回头再看!!! POINT: dp[time][sta]; 在time时刻在车站sta还需要最少等待多长时间: 终点的状态很确定必然是的 dp[T][N] = 0 ---即在 ...
- Python_sklearn机器学习库学习笔记(五)k-means(聚类)
# K的选择:肘部法则 如果问题中没有指定 的值,可以通过肘部法则这一技术来估计聚类数量.肘部法则会把不同 值的成本函数值画出来.随着 值的增大,平均畸变程度会减小:每个类包含的样本数会减少,于是样本 ...
- Asp.net MVC 4 Html帮助类 II
Html Helpers @Html.AntiForgeryToken It generates a hidden form field (anti-forgery token) that is va ...
- AngularJS Tabular Data with Edit/Update/Delete
效果 首先,我们先建立一些数据,当然你可以从你任何地方读出你的数据 var app = angular.module('plunker', ['ui.bootstrap']); app.control ...
- Service通信详解
1.使用Intent进行异步通讯 在Service任务一旦完成后,就发送广播.开发者只需要实现一个BroadcastReceiver来监听响应既可. Activity.startService启动in ...
- JAVA计算器算法实现
import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import ...