`
uncoseason
  • 浏览: 1947 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
最近访客 更多访客>>
社区版块
存档分类
最新评论

Web界面无人操作时触发事件 onNobodyEvent

阅读更多
灵感源于一个投射展示型项目,代码很简单并包含注释就不做累述了。
/*
 * nobody.js
 * @author Yimo
 * @version v1.0
 */
(function(){
	// 人为操作事件支持,以下事件触发将被认定为当前页面存在人为操作
	var events = ['mousemove','keypress','mousedown','mousewheel'];
	
	// 添加事件
	function addEvent(type,handler){
		if (window.addEventListener){
			window.addEventListener(type, handler, false);
        } else if (window.attachEvent){
        	window.attachEvent("on" + type, handler);
        } else {
        	window["on" + type] = handler;
        }
	}
	
	// 移除事件
	function removeEvent(type,handler){
		if (window.removeEventListener){
			window.removeEventListener(type, handler, false);
        } else if (window.detachEvent){
        	window.detachEvent("on" + type, handler);
        } else {
        	window["on" + type] = null;
        }
	}
	// 按ID缓存对应nobody事件的内部对象用于后续事件销毁
	var cache = {};
	
	/*
	 * 无人操作事件
	 * 
	 * @param func 事件触发时的回调函数
	 * @param timeout 无人操作事件触发延迟时间
	 * @param onlyonce 是否仅触发一次
	 * 
	 * @return 事件定时器ID
	 */
	window.onNobody = function(func,timeout,onlyonce){
		// 域内独立对象,保证onNobody每次调用都有一个属于自己的detail对象
		var detail = {
			 counter : 0,
			 lastTime : new Date().getTime(),
			 reset : function(){
				 detail.counter = 0;
			 }
		}
		for(var i = 0; i < events.length; i++){
			addEvent(events[i],detail.reset);
		};
		var id = setInterval(function(){
			if(detail.counter >= timeout){
				func();
				if(!onlyonce){
					detail.counter = 0;
				}else{
					window.clearNobody(id);
				}
			}
			var time = new Date().getTime();
			detail.counter += time - detail.lastTime;
			detail.lastTime = time;
		},1);
		cache[id] = detail;
		return id;
	}
	
	/*
	 * 移除无人操作事件
	 * 
	 * @param id 添加无人操作事件时返回的ID
	 */
	window.offNobody = function(id){
		clearInterval(id);
		for(var i = 0; i < events.length; i++){
			removeEvent(events[i],cache[id].reset);
		};
	}
})();
2
1
分享到:
评论
2 楼 uncoseason 2014-02-20  
Jack_ljk 写道
window.clearNobody = function(id){
    cache[id] && (clearInterval(id), delete cache[id]);
}

考虑一下setInterval(fn, 1); // 每1毫秒执行一次是否太频繁,1000应该也是在可接受的范围内吧?


setInterval本身在浏览器端的native实现中根据不同浏览器实现平均大概会在10-20ms调用一次进行校验当满足interval执行时间则执行interval回调,例如setInterval(fn,1000)同样会在后台每10-20ms左右调用一次校验的。根据浏览器单线程的特性这个函数调用实际不会那么频繁的并且实际执行时间在毫秒级是不能够确认的,间隔时候尽可能的设小是为了尽可能的贴合间隔时间精准度。如果没有那么高的时效性要求是可以考虑将这个时间加大的
1 楼 Jack_ljk 2014-02-20  
window.clearNobody = function(id){
    cache[id] && (clearInterval(id), delete cache[id]);
}

考虑一下setInterval(fn, 1); // 每1毫秒执行一次是否太频繁,1000应该也是在可接受的范围内吧?

相关推荐

Global site tag (gtag.js) - Google Analytics