我希望根据时间和持续时间显示json中的元素,并且间隔由settimeout中断

时间:2015-10-07 21:40:21

标签: javascript jquery json logic

我有一个json文件,其结构如下:

[{"text_content":"aaaaa","text_duration":15,"start_time":"2015-10-07 23:25:29"},
{"text_content":"aawwaaaaa","text_duration":15,"start_time":"2015-10-07 23:25:44"},
{"text_content":"bbaawwaaaaa","text_duration":15,"start_time":"2015-10-07 23:25:59"}, etc.

我的网页user-text上有一个div,我想用这个json中的字符串填充它。但是有一个条件 - 我希望在分配给它的时间和分配给它的持续时间内显示第一个文本。 因此,根据我的示例,我想在aaaaa15秒显示2015-10-07 23:25:29,等等。 我写了一个jquery脚本:

    var results =[];
    var cursor = 0;

    function myFunction () {
        $.getJSON('get_json.php', function(json) {
            results = json;
            cursor = 0;

            // Now start printing
            if(results.length == 0){
                $('#user-text').hide('fast', function() {
                    $('#user-text').html("there is no text at the moment");
                    $('#user-text').show('fast');
                });
            }else{
                printNext();
            }
        });
    }

    function printNext(){
        if(cursor == results.length){
            // Reset the cursor back to the beginning.
            cursor = 0;
        }

        var textDate = results[cursor].start_time;
        var textMsg = results[cursor].text_content;
        var dateOfText = new Date(textDate).setMilliseconds(0);
        var duration = results[cursor].text_duration;
        //now we're checking every second if there is any text to display at that time
        var myInterval = setInterval(check, 1000);

        function check() {

            var currentDate = new Date().setMilliseconds(0);

            if (currentDate - dateOfText ==0) {
            clearInterval(myInterval);
                $('#user-text').hide('fast', function() {
                    $('#user-text').html(textMsg);
                    $('#user-text').show('fast');
                });

            } else{

                $('#user-text').html("there is no text to display at the moment");
            }
        }

        // Set a delay for the current item to stay
        // Delay is key2 * 1000 seconds
        setTimeout(function(){
            printNext();
        }, results[cursor].text_duration * 1000);

        // Advance the cursor.
        cursor++;
    }

但不知怎的,它不起作用。发生的事情是每秒内部循环受到整个函数的设置超时的干扰。 因此,即使我们在此处找到匹配项if (currentDate - dateOfText ==0) { - 它也不会在屏幕上显示所有持续时间,因为它会被此插入:

setTimeout(function(){
            printNext();
        }, results[cursor].text_duration * 1000);

我不确切知道如何继续这一点,以及如何使逻辑工作,以便每个文本在整个持续时间内播放。你能帮帮我吗?

3 个答案:

答案 0 :(得分:1)

因为else内有check条件来隐藏文字。我假设要显示的这些消息将提前到达,因此在消息准备好显示时,您将有三个check实例同时运行。

由于else条件中的每一个都会每秒显示“没有要显示的文本”消息,即使第一个check最终决定显示第一条消息,另外两个是快速超越并且没有留言。

您或许可以将setTimeout调用printNext移至check的真正分支中的if函数内。

我使用替代方法构建了一个小型演示:http://jsfiddle.net/nauzilus/rqctam5r/

不是迭代messages数组,而是只关注第一个数组,并在完成后将其移除。

您可以将新条目推送到messages,并在适当的时候排队等候。

此外,这假设消息总是预先加载;任何包含过去日期的邮件都会被处理,就好像它们已经准备好立即查看一样。

我没有使用过jQuery,只使用了vanilla JavaScript,但你应该能够轻松地适应它。 此外,我每隔500毫秒检查一次,并显示消息是否在计划的1000毫秒内,以避免因浏览器滞后或阻塞而丢失任何错过的消息。定时器和时间表不能保证在你认为它们的时候完全运行,所以如果一个时间需要1001ms而不是1000ms,你就会错过一条消息!

答案 1 :(得分:0)

对setTimeout的调用非常糟糕。放

    setTimeout(printNext, results[cursor].text_duration * 1000);

在与{}相同的clearInterval(myInterval);代码块中,即停止间隔计时器,显示文本,然后启动计时器以回拨printNext以删除文本并检查新。

替换printNext中的这段代码:

    setTimeout(function(){
        printNext();
    }, results[cursor].text_duration * 1000);

只是

     check();

确保在回调中删除文本。

答案 2 :(得分:0)

另一种方法:

html,
body,
#page  {
height: 100%;
}

#page-wrapper {
min-height: 100%;
min-width: 960px;
}