JavaScript Timer实今世码_时间日期_脚本之家

2019-11-26 16:07栏目:竞技宝竞猜
TAG:

ok,不废话了,实现一个javascript的Timer吧 比起as3的Timer类,功能上略有改动 timer2.src.js 复制代码 代码如下: /** * Timer 模型 * * @author rainsilence * @version 2.0 */ { /** * TimerEvent constructor 构造器 * * @param type 事件类型 * @param bubbles 是否毛票 * @param cancelable 是否可取消 */ TimerEvent = function(type, bubbles, cancelable) { this.type = type; this.bubbles = bubbles; this.cancelable = cancelable; }; /** * Event 时间事件声明 * * @event TIMER * @event TIMER_COMPLETE */ extend(TimerEvent, { TIMER : "timer", TIMER_COMPLETE : "timerComplete" }); /** * Event 方法 * * @method toString */ extend(TimerEvent.prototype, { toString : function() { return "[TimerEvent type=" + this.type + " bubbles=" + this.bubbles + " cancelable=" + this.cancelable +"]"; } }); /** * Extend 扩展类,对象的属性或者方法 * * @param target 目标对象 * @param methods 这里改成param也许更合适,表示承载着对象,方法的对象,用于target的扩展 */ function extend { if { target = {}; } for { target[prop] = methods[prop]; } return target; } /** * Timer 构造器 * * @param delay 延时多少时间执行方法句柄 * @param repeatCount 重复多少次,如果不设置,代表重复无限次 */ Timer = function { var listenerMap = {}; listenerMap[TimerEvent.TIMER] = []; listenerMap[TimerEvent.TIMER_COMPLETE] = []; extend(this, { currentCount : 0, running : false, delay : delay, repeatCount : repeatCount, // true:Interval,false:Timeout repeatType : repeatCount == null || repeatCount < 1 ? true : false, handler : listenerMap, timerId : 0, isCompleted : false }); }; // 事件对象初始化 var timerEvent = new TimerEvent(TimerEvent.TIMER, false, false); var timerCompleteEvent = new TimerEvent(TimerEvent.TIMER_COMPLETE, false, false); /** * Timer 计时器方法 * * @method addEventListener 增加一个方法句柄 * @method removeEventListener 移除一个方法句柄 * @method start 开始计时器 * @method stop 结束计时器 * @method reset 重置计时器 */ extend(Timer.prototype, { addEventListener : function(type, listener, useCapture) { if (type == TimerEvent.TIMER || type == TimerEvent.TIMER_COMPLETE) { if { alert; } if { this.handler[type].splice; } else { this.handler[type].push; } } }, removeEventListener : function { if (type == TimerEvent.TIMER || type == TimerEvent.TIMER_COMPLETE) { if { this.handler[type] = []; } else { var listeners = this.handler[type]; for (var index = 0; index < listeners.length; index++) { if (listeners[index] == listener) { listeners.splice; break; } } } } }, start : function() { var timerThis = this; if (this.running == true || this.isCompleted) { return; } if (this.handler[TimerEvent.TIMER].length == 0 && this.handler[TimerEvent.TIMER_COMPLETE].length == 0) { alert; return; } if { this.timerId = setInterval { dispachListener(timerThis.handler[TimerEvent.TIMER], timerEvent); timerThis.currentCount++; }, this.delay); } else { this.timerId = setTimeout {delayExecute(timerThis.handler[TimerEvent.TIMER]);}, this.delay); } this.running = true; function delayExecute { dispachListener(listeners, timerEvent); timerThis.currentCount++; if (timerThis.currentCount < timerThis.repeatCount) { if { timerThis.timerId = setTimeout {delayExecute;}, timerThis.delay); } } else { timerThis.running = false; } if (timerThis.running == false) { if (!timerThis.isCompleted) { dispachListener(timerThis.handler[TimerEvent.TIMER_COMPLETE], timerCompleteEvent); } timerThis.isCompleted = true; } } function dispachListener { for (var prop in listeners) { listeners[prop]; } } }, stop : function() { this.running = false; if { return; } if { clearInterval; } else { clearTimeout; } if { var listeners = this.handler[TimerEvent.TIMER_COMPLETE]; for (var prop in listeners) { listeners[prop]; } } this.isCompleted = true; }, reset : function() { this.currentCount = 0; this.isCompleted = false; } }); })(); 接下来测试吧,大家见过新浪网上的滚动显示吗?用setTimeout写的,真叫牛叉。。。。。。换成Timer重构,简单易懂 timerTest.html 复制代码 代码如下:

jq里面有一个data的方法,给dom元素绑定相关的数据的。当给dom用jq的方法绑定了事件,会生成对应的时间列表
可以看下面的例子(请在firefox中查看 因为firefox中对象支持toSource())

Insert title here

复制代码 代码如下:

1

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
</head>
<body>
<div id="test"></div>
<script type="text/javascript" src=";
<script type="text/javascript">
window.onload = function(){
alert($.data($('#test')[0],'events'));//null
alert($.data($('#test')[0],'handle'));//null
$('#test')
.bind('click',function(){
alert(1)
})
.bind('mouseover',function(){
alert(2)
})
.bind('click',function(){
alert(3)
})
.bind('click',function(){
alert(4)
})
alert($.data($('#test')[0],'events').toSource());//时间列表
alert($.data($('#test')[0],'handle').toSource());//执行的函数
}
</script>
</body>
</html>

2

data是给元素绑定数据的
数据源是 cache对象
当元素绑定数据的时候 会给元素添加一个属性 jQueryxxx xxx为执行jq的时间戳
这里要说明一下,有一个uuid 他是累加的
jQueryxxx的值就是这个uuid
cache 的 key就是这个 uuid
value就是要存的数据
data对于事件的绑定是很重要的................................

3

复制代码 代码如下:

4

function now(){
return +new Date;
};
var win = this,
expando = "jQuery" + now(),
uuid = 0,
cache = {};
win.data = function(elem, name, data){
var id = elem[expando];
if(!id)
id = elem[expando] = ++uuid;
if(name&&!cache[id])
cache[id] = {};
if(data !== undefined)
cache[id][name] = data;
return name
? cache[id][name]
: id;
}
win.removeData = function(elem, name){
var id = elem[expando];
if (name){
if (cache[id]) {
delete cache[id][name];
name = "";
for ( name in cache[ id ] )
break;
if ( !name )
removeData(elem);
}
}else{
try {
delete elem[expando];
} catch(e){
if ( elem.removeAttribute )
elem.removeAttribute( expando );
}
delete cache[id];
}
}
win.each = function( object, callback, args ) {
var name, i = 0, length = object.length;
if ( args ) {
if ( length === undefined ) {
for ( name in object )
if ( callback.apply( object[ name ], args ) === false )
break;
} else
for ( ; i < length; )
if ( callback.apply( object[ i++ ], args ) === false )
break;
} else {
if ( length === undefined ) {
for ( name in object )
if ( callback.call( object[ name ], name, object[ name ] ) === false )
break;
} else
for ( var value = object[0];
i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
}
return object;
}

addEventListener的useCapture参数本为捕获阶段触发之意,现在改成如果true,则在其他句柄之前触发,如果false,则在其他句柄之后触发。 后记: 现在貌似大家比较流行评论说明书的用法。。。比如struts+spring+hibernate。而忽略了编程的实质。希望大家多看源码,多讨论源码,那样才会有所谓的思想。否则人家今天用这个framework,明天换了。你又要从头开始了。

接着实现添加事件
jq里面是在 jQuery.event里面的add方法
在add方法里面实现了一下一些功能
取元素的events,handle这2个data绑定的数据
events存放的是事件列表
格式如下
{
click: [{handler:function(){},type:"click",guid:'xx'}.......],
mouse:[......]
}
handle是执行的函数
(所有的执行函数都是一样的 他们遍历事件列表 执行对应的事件)
然后遍历types 因为可以绑定多个事件
回调函数也会给几个属性
假设回调函数是handler
handler.guid = gevent.guid++
handler.type = name
name应该算一个特殊的命名 方便删除用的
比如
$('#xx')
.bind('click',function(){})
.bind('click.d',handler)
name就是d了
删除的时候可以只删除d那个事件 不删除上面的那个 click事件
最后是给元素绑定事件 但是执行的函数都是
function(){
gevent.handle.apply(arguments.callee.elem, arguments);
});

复制代码 代码如下:

win.gevent = {
guid : 1,
add : function (elem, types, handler){
if ( elem.nodeType == 3 || elem.nodeType == 8 )
return;
if ( elem.setInterval && elem != window )
elem = window;
//给函数一个唯一标识的索引 方便后面删除该事件
if ( !handler.guid )
handler.guid = this.guid++;
//获得该元素的events handle 下的数据
var events = data(elem, "events") || data(elem, "events", {}),
handle =data(elem, "handle") || data(elem, "handle", function(){
//gevent.handle才是各种行为触发后会执行的函数
gevent.handle.apply(arguments.callee.elem, arguments);
});
handle.elem = elem;
//遍历事件名 因为可以是 click mouseover
each(types.split(/s+/), function(index, type) {
var namespaces = type.split(".");
//获得事件名
type = namespaces.shift();
//去掉点后面的东西 是个特殊的命名 在删除的时候可以指定删除他 如 click.d
//用事件的type 记录住这个特殊的命名
handler.type = namespaces.slice().sort().join(".");
//获得该事件是否已经存在events 这个对象里面了
var handlers = events[type];
//如果不存在该事件 给元素绑定该事件
if (!handlers) {
handlers = events[type] = {};
if (elem.addEventListener)
elem.addEventListener(type, handle, false);
else if (elem.attachEvent)
elem.attachEvent("on" + type, handle);
}
//吧函数放到元素的该事件的列表里面
handlers[handler.guid] = handler;
});
elem = null;
}
}

版权声明:本文由龙竞技官网发布于竞技宝竞猜,转载请注明出处:JavaScript Timer实今世码_时间日期_脚本之家