0

当我在寻找一个仅使用 Javascript 实现的模拟时钟的好例子时,我发现了这个由 Emanuele Feronato 编写的有趣时钟,它使用了一个非常强大的 Javascript 库,名为Raphaël

我玩了一段时间,然后我想在这些时钟上有多个不同时间的时钟,可能是根据不同的时区,但这里不是这种情况。

所以我所做的是创建单独的时钟对象并设置不同的时间。它起作用了,但是当脚本遇到 setInterval() 函数时问题就来了,它并没有真正起作用,时钟的指针没有旋转。

我不太擅长 Javascript 内置函数,也找不到防止此问题的解决方案,无论如何我在这里发布我的代码。

function createClocks(){
     /* for the time being assume these Date objects are unique */
     var diffDate_01 = new Date();
     var diffDate_02 = new Date();

     /* create separate clock Objects */ 
     var clok_01 = new clock(diffDate_01);
     var clok_01 = new clock(diffDate_02);

     /* calling update_clock function wrapped within setInterval to make the clock's hand rotatable */ 
     setInterval("clok_01.update_clock(diffDate_01)", 1000);
     setInterval("clok_01.update_clock(diffDate_02)", 1000);

}


function clock(diffDate){
        /* this is the place where the base implementation of the clock stands I removed the setInterval("update_clock()",1000); because I want to call it from outside as per Object separately */

        function update_clock(diffDate){
            var now = diffDate;
            var hours = now.getHours();
            var minutes = now.getMinutes();
            var seconds = now.getSeconds();
            hour_hand.rotate(30*hours+(minutes/2.5), 100, 100);
            minute_hand.rotate(6*minutes, 100, 100);
            second_hand.rotate(6*seconds, 100, 100);

        }
 }

对于 HTML 部分,我正在创建动态时钟<div>标签,并将所有这些标签附加到<div>HTML 文档正文中存在的标签中。

谢谢。

4

2 回答 2

5

请,请永远不要使用字符串setInterval()。这会导致范围问题和潜在的其他问题。

当您使用字符串时,该字符串会eval()在全局范围内进行评估。因此,它无法访问您的任何局部变量。还有许多其他问题,包括您没有使 update_clock 成为时钟对象的方法这一事实。

这是一个工作、重写和清理的代码版本,它更加面向对象并支持几种新方法:http: //jsfiddle.net/jfriend00/wKVC7/

而且,这是代码:

function clock(id, initialTime) {
    // we store each clock in global map clock.clocks
    // create global clock map if it doesn't already exist
    clock.clocks = clock.clocks || {};
    // store this newly created clock in the map
    clock.clocks[id] = this;
    this.id = id;

    // canvas for this clock (remembered as an instance variable)
    this.canvas = Raphael(id, 200, 200);

    // draw clock face
    var clockFace = this.canvas.circle(100,100,95);
    clockFace.attr({"fill":"#f5f5f5","stroke":"#444444","stroke-width":"5"})  

    // draw clock tick marks
    var start_x, start_y, end_x, end_y;
    for(i=0;i<12;i++){
        start_x = 100+Math.round(80*Math.cos(30*i*Math.PI/180));
        start_y = 100+Math.round(80*Math.sin(30*i*Math.PI/180));
        end_x = 100+Math.round(90*Math.cos(30*i*Math.PI/180));
        end_y = 100+Math.round(90*Math.sin(30*i*Math.PI/180));    
        this.canvas.path("M"+start_x+" "+start_y+"L"+end_x+" "+end_y);
    }

    // draw the three hands (hour, minutes, seconds)
    // save each path as an instance variable
    this.hour_hand = this.canvas.path("M100 100L100 50");
    this.hour_hand.attr({stroke: "#444444", "stroke-width": 6});
    this.minute_hand = this.canvas.path("M100 100L100 40");
    this.minute_hand.attr({stroke: "#444444", "stroke-width": 4});
    this.second_hand = this.canvas.path("M100 110L100 25");
    this.second_hand.attr({stroke: "#444444", "stroke-width": 2}); 

    // draw center pin
    var pin = this.canvas.circle(100, 100, 5);
    pin.attr("fill", "#000000");    

    // update with the actual time
    this.drawTime(initialTime);
 }

clock.prototype = {
    // start the clock running automatically
    start: function() {
        // we have just one global timer running
        // check to see if it is going - if not start it
        if (!clock.timer) {
            clock.timer = setInterval(function() {
                var clocks = clock.clocks;   // get global map
                for (var i in clocks) {
                    if (clocks.hasOwnProperty(i)) {
                        if (clocks[i].running) {
                            clocks[i].update();
                        }
                    }
                }
            }, 1000);
        }
        // if we weren't already running, start this clock
        if (!this.running) {
            var now = new Date();
            this.timeOffset = now - this.currentTime;
            this.update();
            this.running = true;
        }

        return(this);
    },

    // stop the clock
    stop: function() {
        this.running = false;
    },

    destroy: function() {
        this.stop();
        delete clock.clocks[this.id];
    },

    // update the clock according to time of day
    update: function() {
        var now = new Date();
        this.drawTime(new Date(now - this.timeOffset));
    },   

    // update the clock - if no time is passed in, then it will use the current time
    drawTime: function(customDate) {
        var now = customDate || new Date();
        var hours = now.getHours();
        var minutes = now.getMinutes();
        var seconds = now.getSeconds();
        this.hour_hand.rotate(30*hours+(minutes/2.5), 100, 100);
        this.minute_hand.rotate(6*minutes, 100, 100);
        this.second_hand.rotate(6*seconds, 100, 100);
        this.currentTime = now;
    }
};
​
于 2012-08-18T17:11:13.253 回答
0

这是行不通的,因为您diffDate以错误的方式通过。

要实际传递您的变量,请使用以下命令:

var update_clock=(function (diffDate)
    {return function{
        var now = diffDate;
        var hours = now.getHours();
        var minutes = now.getMinutes();
        var seconds = now.getSeconds();
        hour_hand.rotate(30*hours+(minutes/2.5), 100, 100);
        minute_hand.rotate(6*minutes, 100, 100);
        second_hand.rotate(6*seconds, 100, 100);

    }
})(diffDate);

然后你可以这样称呼它:

window.setInterval(update_clock,1000)
于 2012-08-18T17:14:24.970 回答