- 浏览: 91817 次
- 性别:
- 来自: 深圳南山
最新评论
-
ccc17638:
发现一个js replace正则相关的诡异问题 -
libmw:
我觉得我大学四年很苦,但是发现有人跟我一样苦,只是我干得太杂了 ...
我的大学四年,留给学弟学妹 -
libmw:
哎,剑光学长牛啊,刚刚在js讨论区看帖子,看着看着有个链接说正 ...
发现一个js replace正则相关的诡异问题 -
imuma:
通过Google搜索到了这篇文章,确实是非常好用的脚本。目前我 ...
分享一个自己写的httpWatch自动化测试工具 -
zcy860511:
。。。。。摇 头 丸替代品,牛叉
自己写了个《聊天颈椎保健小工具》
前几天帮erricwang写一个js计时器,发现可以用有很多种方式实现相同的功能。现将它写下来,和大家一起探讨分析比较。
实现一:
<body>
<div id="time1">time1</div>
<div id="time2">time2</div>
</body>
<script>
function Timer(id){
this.id = id;
this.begin = function(count){
this.show(this.id, count)();
setInterval(this.show(this.id, count-1),1000);
}
this.show = function(id, count){
return function(){
document.getElementById(id).innerHTML = count<0 ? "over" :count;
count--;
}
}
}
t1 = new Timer("time1");
t1.begin(50);
t2 = new Timer("time2");
t2.begin(10);
</script>
且看第一种实现,显然这里有一个很不好的地方,计时完成之后,setInterval没有被clear,严重影响了性能。
实现二:
function Timer(id){ this.id = id; this.timer = null; this.count = 0; this.begin = function(count){ this.count = count; this.show(this)(); this.timer = setInterval(this.show(this),1000); } this.show = function(obj){ return function(){ if(obj.count < 0){ document.getElementById(obj.id).innerHTML = "over"; clearInterval(obj.timer); return ; } document.getElementById(obj.id).innerHTML = obj.count; obj.count--; } } }
实现二解决了实现一的setInterval未被clear的问题,看上去也很“完美”,且看下面:
alert(t1.show == t2.show) //结果false alert(t1.begin == t2.begin) //结果false
很明显这里Timer每个实例都复制了一份show和begin,二不是共享同一份的,所以t1.showt和2.show所指向的并非同一份实现,这样对性能多少会有些影响。
实现三:
function Timer(id){ this.id = id; this.timer = null; this.count = 0; this.begin = function(count){ this.count = count; Timer.show(this)(); this.timer = setInterval(Timer.show(this),1000); } Timer.show = function(obj){ return function(){ if(obj.count < 0){ document.getElementById(obj.id).innerHTML = "over"; clearInterval(obj.timer); return ; } document.getElementById(obj.id).innerHTML = obj.count; obj.count--; } } }
这里实现了让所有实例共享一份show函数:
alert(t1.begin == t2.begin) //结果true
实现四:
function Timer(id){ this.id = id; this.timer = null; this.count = 0; this.begin = function(count){ this.count = count; this.show(this)();//注意和实现三的区别:这里不是Timer.show(this)(); this.timer = setInterval(this.show(this),1000);//注意和实现三的区别:这里不是Timer.show(this)(); } } Timer.prototype.show = function(obj){ return function(){ if(obj.count < 0){ document.getElementById(obj.id).innerHTML = "over"; clearInterval(obj.timer); return ; } document.getElementById(obj.id).innerHTML = obj.count; obj.count--; } }
实现三和实现四很有意思:二者都实现了让所有实例共享一份show方法。
区别是:实现三show作为Timer对象的一个属性,这里有点类似与java的静态方法,show方法是属于Timer对象本身的,而不是其实例(t1、t2...)的,所以需要用Timer.show(..)来调用;而实现四采用了“原型”prototype方式来实现,这里show方法不是Timer对象本身,而是其实例(t1、t2...)的,所以使用this.show(..)或者t1.show(...)来调用,这里很有意思“原型”创建的属性是属于其实例的,而且所有实例共享同一份实现(不知道我这里的理解是否正确,欢迎大家拍砖)。这多少有些让学java等面向对象语言的人难以理解,而这也正式js有意思的地方。
那么这两种实现方式那种更优呢?欢迎各位讨论。
实现五:
function Timer(id){ this.id = id; this.timer = null; this.count = 0; } Timer.prototype.begin = function(count){ this.count = count; this.show(this)();//注意这里不是Timer.show(this)(); this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)(); } Timer.prototype.show = function(obj){ return function(){ if(obj.count < 0){ document.getElementById(obj.id).innerHTML = "over"; clearInterval(obj.timer); return ; } document.getElementById(obj.id).innerHTML = obj.count; obj.count--; } }
这里将begin也使用原型实现,可能这种写法让你看起来不太舒服,那我们换一种。
实现六:
function Timer(id){ this.id = id; this.timer = null; this.count = 0; } Timer.prototype = { begin : function(count){ this.count = count; this.show(this)();//注意这里不是Timer.show(this)(); this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)(); }, show : function(obj){ return function(){ if(obj.count < 0){ document.getElementById(obj.id).innerHTML = "over"; clearInterval(obj.timer); return ; } document.getElementById(obj.id).innerHTML = obj.count; obj.count--; } } }
或者,再换一种。
实现七:
function Timer(id){ this.id = id; this.timer = null; this.count = 0; Timer.prototype.begin = function(count){ this.count = count; this.show(this)();//主要这里不是Timer.show(this)(); this.timer = setInterval(this.show(this),1000);//主要这里不是Timer.show(this)(); } Timer.prototype.show = function(obj){ return function(){ if(obj.count < 0){ document.getElementById(obj.id).innerHTML = "over"; clearInterval(obj.timer); return ; } document.getElementById(obj.id).innerHTML = obj.count; obj.count--; } } }
这方式,看起来是不是更优雅一些呢。以上都采用面向对象的方式来实现的。那我们是否还可以采用其他方式实现呢?
实现八:
var Timer = { begin : function(id,count){ var obj = {}; obj["id"] = id; obj["count"] = count; Timer.show(obj)(); obj["timer"] = setInterval(Timer.show(obj),1000);//注意这里不是Timer.show(this)(); }, show : function(obj){ return function(){ if(obj["count"] < 0){ document.getElementById(obj["id"]).innerHTML = "over"; clearInterval(obj["timer"]); return ; } document.getElementById(obj["id"]).innerHTML = obj["count"] ; obj["count"]--; } } } Timer.begin("time1", 30); Timer.begin("time2", 60);
这里采用了对象字面量的方式来实现的。对象字面量其实是一种单例模式,用在这里其实很变扭,本文这里引入只是引入一种js实现方式而已,仅供大家探讨。下一例也一样。
实现九:
var Timer = (function(){ var items = {}; function begin(id,count){ var obj = {}; obj["id"] = id; obj["count"] = count; Timer.show(obj)(); obj["timer"] = setInterval(Timer.show(obj),1000);//注意这里不是Timer.show(this)(); Timer.items[id] = obj; }; function show(obj){ return function(){ if(obj["count"] < 0){ document.getElementById(obj["id"]).innerHTML = "over"; clearInterval(obj["timer"]); return ; } document.getElementById(obj["id"]).innerHTML = obj["count"] ; obj["count"]--; } } return { items : items, begin : begin, show : show } })() Timer.begin("time1", 30); Timer.items["time1"]["count"] = 80;//重新从80开始计时 Timer.begin("time2", 60);
这里其实也是采用的对象字面量的方式来实现的,只是采用了闭包而已,应用闭包可以真正的实现属性私有化(不过这里没有体现出来)。这里还加了items属性,让其所有实例保存起来,以便后面还可以调用。
平常用的比较多的还有最后一种闭包结合对象字面量的方式(不过在这个场景个人觉得用面向对象方式来实现更好一些)。对象字面量的方式其实也是js的单例模式,在js里应用很广泛,不过在这里应用好像不太合适,看这里的最后两个实现都觉得很牵强。
从一个小小的计时器,可以衍生出如此多的方式来实现,真让人惊叹于js表现形式之丰富。如此众多实现方式,都有其优点和缺点,在不同的场合也有不同的应用。这里只是表达了一下个人的理解和观点,欢迎大家一起讨论js各种实现方式的优缺点及其适用场合。也欢迎拍砖,或者提供更好的实现方法。
【本人发帖抛砖引玉,希望能够引出更多的“玉”来,希望所写的每一段代码都能够得到一种最“优雅”的实现方式。以后本人会抛出更多的“砖”,希望能引来更多的“玉”,以供大家一起学习进步】
-------------------------------------------------------2009.08.17------------------------------------------------------------
到目前为止,个人觉得3楼zbm2001 的实现最优,让我学到了不少,希望能有更多的牛人来提供更优的实现。
function Timer(id){ this.element = document.getElementById(id); this.timer = null; this.count = 0; } Timer.prototype = { begin : function(count){ this.count = count; this.show(); var _this = this; this.timer = setInterval(function(){_this.show();}, 1000); } , show : function(){ this.element.innerHTML = this.count < 0 ? clearInterval(this.timer) || "over" : this.count--; } }
-------------------------------------------------------2009.08.21------------------------------------------------------------
继续收集评论中的实现方式,优劣请读者自评
var Timer = function(id) { var _step = 500, _count = 0, _ticktark = 0, _element = document.getElementById(id); function __clear() { if (_ticktark != null) clearInterval(_ticktark); } return { begin: function(count, step) { if (_element && count > 0) { // 看看起始值多少,主要看看有没有被污染 console.log('on start:', 'count:', _count, 'step:', _step); __clear(); _step = step; _count = count; // 再看看 console.log('on set:', 'count:', _count, 'step:', _step); _ticktark = setInterval(this.show, _step) } return this; }, show: function() { _element && (_element.innerHTML = _count > 0 ? _count-- : 'over'); if (_count <= 0) { console.log(_count); __clear(); } return this; } } } Timer('time1').begin(20, 100); Timer('time2').begin(30, 200);
function Timer(id) { this.container = document.getElementById(id); } Timer.prototype = { constructor: Timer, begin: function(count) { var container = this.container; setTimeout(function() { container.innerHTML = count > 0 ? count-- : "over"; if(count + 1) { setTimeout(arguments.callee, 1000); } }, 1000); } }; new Timer("time1").begin(10);
评论
以前写的……现在看起来好丑-_-#
this.timer = null;
设计模式的问题,二楼已给出提示,你也注意到了,不再赘述。
我给的一些修改,只是顺带提醒一下javascript编程中的需要注意的地方:
1.节约使用DOM获取元素,尽可能的避免重复获取;
2.巧用javascript表达式/运算符和内置的类型转换,为程序提速,同时也使得代码内敛;
3.合理利用闭包。
代码很到位,欢迎继续拍砖!javaeye果然人才出没,欢迎继续提供更优雅的实现方式!
function Timer(id){
this.id = id;
this.timer = null;
this.count = 0;
if(Timer.prototype.initialization !== true){
Timer.prototype.initialization = true;
Timer.prototype.begin = function(count){
this.count = count;
this.show(this)();//主要这里不是Timer.show(this)();
this.timer = setInterval(this.show(this),1000);//主要这里不是Timer.show(this)();
}
Timer.prototype.show = function(obj){
return function(){
if(obj.count < 0){
document.getElementById(obj.id).innerHTML = "over";
clearInterval(obj.timer);
return ;
}
document.getElementById(obj.id).innerHTML = obj.count;
obj.count--;
}
}
}
}
this.timer = null;
设计模式的问题,二楼已给出提示,你也注意到了,不再赘述。
我给的一些修改,只是顺带提醒一下javascript编程中的需要注意的地方:
1.节约使用DOM获取元素,尽可能的避免重复获取;
将DOM元素保存在实例对象的hash中。
2.巧用javascript表达式/运算符和内置的类型转换,为程序提速,同时也使得代码内敛;
this.element.innerHTML = this.count < 0 ? clearInterval(this.timer) || "over" : this.count--;
三元表达式 + 短路运算
3.合理利用闭包。
var _this = this;
this.timer = setInterval(function(){_this.show();}, 1000);
每次执行只需获取一个实例的环境变量this,而不是每次通过返回一个新的函数来获取变量(实例对象)
function Timer(id){ this.element = document.getElementById(id); this.timer = null; this.count = 0; } Timer.prototype = { begin : function(count){ this.count = count; this.show(); var _this = this; this.timer = setInterval(function(){_this.show();}, 1000); } , show : function(){ this.element.innerHTML = this.count < 0 ? clearInterval(this.timer) || "over" : this.count--; } }
这里setInterval没有被clear
function Timer(id){ this.element = document.getElementById(id); this.timer = null; this.count = 0; } Timer.prototype = { begin : function(count){ this.count = count; this.show(); var _this = this; this.timer = setInterval(function(){_this.show();}, 1000); } , show : function(){ this.element.innerHTML = this.count < 0 ? clearInterval(this.timer) || "over" : this.count--; } }
Timer.prototype = {
6. begin : function(count){
7. this.count = count;
8. this.show(this)();//注意这里不是Timer.show(this)();
9. this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)();
10. }
11. show : function(obj){
12. return function(){
13. if(obj.count < 0){
14. document.getElementById(obj.id).innerHTML = "over";
15. clearInterval(obj.timer);
16. return ;
17. }
18. document.getElementById(obj.id).innerHTML = obj.count;
19. obj.count--;
20. }
21. }
22. }
这个超大的对象怎么能写到构造函数里啊,虽然没产生多余的副本,但是被构造2次也是非常不爽的.
发表评论
-
写了个chrome的QQ会员扩展
2010-02-10 15:25 1784今天在公司放羊,没事干,玩了下chrome的插件开发, ... -
IE6下动态加载JS数据不执行的诡异问题
2009-12-07 19:00 1443最近遇上个非常诡异的问题:在ie6下,从地址栏直接输入网址,或 ... -
自己写了个《聊天颈椎保健小工具》
2009-11-29 22:59 3168和亲爱的聊天的时候,你有没想过去关心下她的健康呢,用这个工具可 ... -
jWidget:js slide轮播、tab页签
2009-10-31 22:13 2827jWidget: a mini javascript widg ... -
IE6下gif动画静止的问题
2009-09-09 23:32 2114今天hairetzhang做头像设置的时候遇到gif动画被点击 ... -
对js运算符“||”和“&&”的总结
2009-09-04 22:31 46098首先出个题: 如图: 假设对成长速度显示规定如下: ... -
从帖子《可输入的select下拉框》的优化,总结js键盘事件的兼容性
2009-08-23 23:41 3803本文源起javaeye的论坛帖子《可输入的select下拉框 ... -
答复: js 实现下拉列表的重复利用
2009-08-21 23:23 1058原帖《js 实现下拉列表的重复利用 》 可以优化一下代码: ... -
【JS优化系列】一个通用公告系统的实现
2009-08-17 22:22 1305之前一篇《【JS优化系列】从一个计时器的写法探讨 ... -
制作IE扩展
2009-06-20 20:29 1361上周终于把有我全权负 ... -
分享一个自己写的httpWatch自动化测试工具
2009-06-20 21:02 56572009-04-22 分享一个自己写的httpWatch ... -
发现一个js replace正则相关的诡异问题
2009-07-17 09:43 5012最近做会员个人身份页的时候遇上如下问题: 测试的 ... -
表单元素命名需要注意的一个地方:不要使用与form属性同名的name或id
2009-07-31 20:21 3348最近做官方点充值入口的时候遇到个奇怪的问题。 直接 ...
相关推荐
"JavaScript实现计时器"这个主题涉及到JavaScript编程中的一个常见任务:创建一个可以随着时间流逝更新的计时器。计时器在各种网页应用中都有广泛的应用,如倒计时、实时显示时间等。下面我们将深入探讨如何使用...
"js计时器数字卡片翻转秒表计时器网页特效"就是一个利用JavaScript实现的动态计时功能,它结合了数字卡片翻转的效果,使得秒表计时更为直观且具有视觉吸引力。这种效果常见于体育竞赛、健身应用或者任何需要实时计时...
总结,这款“css3圆形进度条时分秒计时器js特效”充分利用了CSS3的高级特性,结合JavaScript的时间管理和DOM操作,实现了动态的、可视化的计时功能。这样的特效不仅可以提升用户体验,也可以在各种应用场景中增加...
在JavaScript中,实现一个秒表计时器涉及到定时器(setTimeout和setInterval)以及DOM操作。下面我们将详细探讨这些知识点: 1. **定时器:** - `setInterval` 函数用于每隔一定时间执行一次指定的函数。在这个...
在本项目"JS CSS3实现苹果iwatch计时器.zip"中,我们主要探讨的是如何使用JavaScript(JS)和CSS3技术来模拟苹果iWatch的计时器功能,包括开始、暂停以及重置操作,并能记录计时次数。这个项目对于前端开发者来说,...
本文将详细探讨如何利用这两者来实现一个圆形的时分秒计时器动画特效。 首先,我们需要了解JavaScript(JS)的基础。JavaScript是一种解释型的、面向对象的、弱类型的脚本语言,常用于网页和网络应用开发。它能够...
JavaScript(简称JS)是网页开发中的重要脚本语言,它提供了丰富的功能,其中之一就是计时器功能。在JavaScript中,计时器常用于实现动画效果、执行定时任务、或者跟踪时间流逝等。本文将深入探讨JavaScript计时器的...
自己实现的简单的倒计时器,发现网上关于这方面的代码有...我自己用js手写了一个分享给大家,界面比较简洁,后面会再写一个比较酷炫的。如果没有积分还想下载的小伙伴可以加qq邮箱联系我,我发给你:1343121616@qq.com
总结来说,计时器在各种编程语言和应用领域都有着广泛的应用,其实现方式多种多样,从简单的循环检查到复杂的事件驱动,都需要根据具体需求和环境来选择合适的方法。理解并掌握计时器的原理和实现技巧,对于提升软件...
接下来,我们将深入探讨如何使用JavaScript来实现一个基本的秒表计时器功能。在上述提供的代码示例中,我们能够看到创建一个秒表计时器所依赖的关键元素和方法。 首先是HTML部分,这是用户界面的基础。在`<body>`...
以下是一个简单的JavaScript秒表计时器的实现: ```javascript let startTime = null; let elapsedTime = 0; let timerInterval = null; function startTimer() { startTime = new Date(); timerInterval = ...
总的来说,这个"简单清新的纯JS实现的计时特效电子计时效果"源码提供了一个学习和实践JavaScript计时器功能的平台。通过理解和研究源码,开发者不仅可以掌握基本的计时器实现,还能进一步了解JavaScript与DOM的交互...
本篇文章将详细介绍如何利用JavaScript编写一个网页倒计时功能,并结合提供的`index.html`和`js`文件进行解析。 首先,我们需要理解JavaScript中的时间处理。JavaScript使用`Date`对象来表示日期和时间,它提供了...
javascript实现倒计时
"多功能计时器-倒计时器"这款应用程序,正如其标题所示,旨在提供一种高效且灵活的计时解决方案,适应多种场景的需求。 首先,我们来详细探讨倒计时器的核心功能。倒计时器是一种能够从预设时间开始向零倒数的计时...
"JS系列计时器资料.rar"这个压缩包包含了关于JavaScript计时器的详细文档,名为"5.JS计时器.doc"。以下将深入探讨JavaScript中的计时器机制及其应用。 1. **setTimeout()和setInterval()** - `setTimeout()`: 这个...
通过上述代码实现,我们能够构建一个既能够在不同客户端间保持同步,又具备防刷新、防关闭和自校正功能的理想Web倒计时器。这种方式不仅提高了用户体验,也为Web开发者提供了更为灵活可靠的解决方案。
在这个项目中,我们将深入探讨如何使用jQuery实现一个倒计时器。 首先,我们需要理解jQuery的基本使用。jQuery通过简洁的语法来处理DOM操作、事件处理和动画效果。例如,我们可以使用`$`符号来选择元素,然后对这些...
本文将深入探讨如何在Android中实现计时器功能,主要以`HLQCountDownTimer`为例,这是一个自定义的倒计时计时器类。 ### 一、Android计时器基础 在Android中,有多种计时器实现方式,包括`java.util.Timer`、`...
本文将详细探讨“DJS倒计时器”,一种小巧而实用的计时工具,以及它的功能、实现原理和使用方法。 首先,DJS倒计时器的核心功能在于设定并显示一个特定时间点前的剩余时间。用户可以根据自己的需求,设定一个未来的...