我想根据时间和持续时间显示json中的元素,并且时间间隔被settimeout插值 [英] I want to display elements from json based on their time and duration and interval is interupted by settimeout

查看:105
本文介绍了我想根据时间和持续时间显示json中的元素,并且时间间隔被settimeout插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a json file that has a structure like this:

[{"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提取的字符串填充它.但是有一个条件-我想在分配给它的时间和分配给它的持续时间内显示第一个文本. 因此,根据我的示例,我想在2015-10-07 23:25:29上显示aaaaa秒钟15秒,依此类推. 我写了一个jQuery脚本:

I have a div on my webpage user-text and I want to fill it with strings taken from this json. But there's a condition - I want to display the first text at the time assigned to it and for the period of duration assigned to it. So based on my example I want to display aaaaa for 15 seconds at 2015-10-07 23:25:29, etc. I wrote a jquery script:

    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) {匹配项,它也不会在整个持续时间内显示在屏幕上,因为它将被此中断:

but somehow it doesn't work. What happens is that the inside loop that goes every second is disturbed by the set timeout of the whole function. So even if we find a match here if (currentDate - dateOfText ==0) { - it won't appear on the screen for its all duration, because it will be interupted by this:

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

我现在不确切地知道如何继续进行以及如何使逻辑起作用,以便每个文本都在其整个播放过程中播放.你能帮我吗?

I don't know exactly how to proceed at this point and how to make the logic work so that each text is played for its whole duration. Could you help me with that?

推荐答案

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

Because you have the else condition inside check to hide the text. I'm assuming these messages to display are going to arrive well in advance, so you're going to have three instances of check running all at the same time by the time the messages are ready to be displayed.

由于else条件中的每个消息都将每秒显示没有文本要显示"消息,即使第一个check最终决定显示第一个消息,其他两个消息也会迅速将其覆盖,不说任何消息.

Since each one of those in the else condition is going to show the "there is no text to display" message every second, even when the first check finally decides to show the first message, the other two are going to quickly overrun it and say no messages.

您也许可以将setTimeout调用printNext移到if的真实分支中的check函数内部.

You might be able to just move the setTimeout calling printNext to inside the check function in the true branch of the if.

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

I've built a small demo with an alternate approach: http://jsfiddle.net/nauzilus/rqctam5r/

它不会遍历messages数组,而是仅关注第一个数组,并在完成后将其移开.

Rather than iterating over the messages array, it will just focus on the first one, and shift it off once done.

您可以将新条目推送到messages中,它们将在适当的时候排队显示.

You can push new entries into messages and they'll be queued to display when appropriate.

此外,这还假定始终总是要预先加载邮件;具有过去日期的所有邮件都将被处理,就像现在可以立即查看一样.

Also, this assumes messages are always going to be loaded in advance; any messages with dates in the past will be processed as though they're ready to be viewed right now.

我没有使用jQuery,只是使用了普通的JavaScript,但您应该能够轻松地对其进行调整. 另外,我每500毫秒检查一次,并显示消息在计划的1000毫秒内的时间,以免由于浏览器滞后或阻塞而丢失任何消息.不能保证计时器和时间表会在您认为正确的时间准确运行,因此,如果时间花费1001毫秒而不是1000毫秒,那么您将错过一条消息!

I haven't used jQuery, just vanilla JavaScript but you should be able to adapt it easily enough. Also, I'm checking every 500ms, and displaying when message is within 1000ms of schedule just to avoid any missed messages due to browser lag or blocking. Timers and schedules aren't guaranteed to run exactly when you think they will, so if a time takes 1001ms instead of 1000ms, you're going to miss a message!

这篇关于我想根据时间和持续时间显示json中的元素,并且时间间隔被settimeout插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆