我想根据它们的时间和持续时间显示json中的元素,并且间隔被settimeout打断
I want to display elements from json based on their time and duration and interval is interupted by settimeout
我有一个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中的字符串填充它。但有一个条件——我想在指定的时间和指定的持续时间内显示第一个文本。因此,基于我的示例,我希望在2015-10-07 23:25:29
处显示aaaaa
达15
秒,等等。我写了一个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);
我不知道在这一点上该如何进行,也不知道如何使逻辑工作,以便在整个持续时间内播放每个文本。你能帮我吗?
因为check
中有else
条件来隐藏文本。我假设这些要显示的消息会提前到达,所以当消息准备好显示时,您将有三个check
实例同时运行。
由于else条件下的每一个都会每秒显示一条"没有文本可显示"消息,即使第一个check
最终决定显示第一条消息,其他两个也会迅速超过它并拒绝消息。
您可以将调用printNext
的setTimeout
移动到if
的真正分支中的check
函数内部。
我用另一种方法构建了一个小型演示:http://jsfiddle.net/nauzilus/rqctam5r/
与其在messages
数组上迭代,不如只关注第一个数组,并在完成后将其偏移。
您可以将新条目推送到messages
中,它们将在适当的时候排队显示。
此外,这假设消息总是要提前加载;任何日期在过去的消息都将被处理,就好像它们现在就可以查看一样。
我没有使用jQuery,只是使用了普通的JavaScript,但您应该能够很容易地对其进行调整。此外,我每500毫秒检查一次,并在消息在计划的1000毫秒内显示,以避免由于浏览器滞后或阻塞而错过任何消息。计时器和时间表并不能保证在你认为的时候准确运行,所以如果一个时间需要1001毫秒而不是1000毫秒,你就会错过一条消息!
对setTimeout的调用位置不正确。放入
setTimeout(printNext, results[cursor].text_duration * 1000);
在与clearInterval(myInterval);
相同的{}
代码块中,即停止间隔计时器,显示文本,并启动计时器以回调printNext
以擦除文本并检查新的。
在printNext
:中替换此代码块
setTimeout(function(){
printNext();
}, results[cursor].text_duration * 1000);
只有
check();
以确保在回调中删除文本。
另一种方法:
//global variable used to generate the element id for each new message
var message_index = 0;
function get_schedule() {
$.getJSON('get_json.php', function(json) {
schedule_messages(json);
});
}
function schedule_messages(schedule) {
var current_time = new Date();
//iterate through each message event
for(var i = 0; i < schedule.length; i++) {
var start_time = new Date(schedule[i].start_time);
//make sure the scheduled message time has not passed
if(start_time > current_time) {
var duration = schedule[i].text_duration * 1000;
//calculate time until message placement and removal
var display_delay = start_time - current_time;
var remove_delay = start_time - current_time + duration;
//schedule placement of the message
(function(delay, message, index) {
setTimeout(function() {
display_message(message, index);
}, delay);
})(display_delay, schedule[i].text_content, message_index);
//schedule removal of the message
(function(delay, index) {
setTimeout(function() {
remove_message(index);
}, delay);
})(remove_delay, message_index);
//increment global message index to use for next message
message_index++;
}
}
}
//do your fancy jQuery effect(s) in here...
function display_message(message, index) {
$('#user-text').append(
$("<p>")
.html(message)
.attr("id", "message-" + index)
);
}
//... and here
function remove_message(index) {
$("#message-" + index).remove();
}
- CKEditor Widget-阻止编辑可编辑元素本身
- 如何设置html元素填充的动画
- 如何将HTML id分配给元素,以及如何将JavaScript应用于元素
- 使用 jQuery 的 .on 函数如何获取事件的原始元素
- 使用clickToggle并在单击另一个元素时关闭元素
- 单击时将焦点更改为元素
- 表追加而不附加最后一个元素
- 如何在jQuery中获取元素的形式
- 我可以获得相对于被点击元素的确切点击位置吗
- 在函数中添加数组元素的数值
- 在单击任何位置时隐藏元素,而不检查每次DOM单击
- 将视口底部滚动到元素底部
- 是否有任何snippet或jQuery插件可以列出easylist.txt模式匹配的DOM中的所有元素
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 如何使用jquery处理php循环通过元素
- Ckeditor-plugin:插入虚假元素add不情愿<p>标签前后
- JQuery添加元素需要在我的js之前再次添加JQuery脚本
- 在Jquery detachment()和appendTo()之后定位元素
- 避免在创建新元素时由于文本值而打断字符串
- 我想根据它们的时间和持续时间显示json中的元素,并且间隔被settimeout打断