为什么我的代码在Safari或Opera中不起作用?
在js
中有一个功能,它向该表显示消息(消息存储在json
中)。在谷歌浏览器中,它可以工作,但Safari,Opera或Microsoft Edge - 不行! 与setTimeout (callback, 5000)
调用相关的代码中存在错误(没有任何内容会发送到回调函数)。因此,从respond === undefined
开始,For (var i = 0; i <respond.length; i ++)
将不起作用。为什么我的代码在Safari或Opera中不起作用?
但是它为什么如此呢?
callback(
[{
"time": "1500303264",
"user": "qwe",
"message": "we",
"id": 1
},
{
"time": "1500303987",
"user": "Max",
"message": "q",
"id": 2
}
]);
function smile(mess) {
var smile = ":)";
var graficSmile = "<img src = './image/Smile.png' alt='Smile' align='middle'>";
var string_with_replaced_smile = mess.replace(smile, graficSmile);
var sad = ":("
var graficSad = "<img src = './image/Sad.png' alt='Smile' align='middle'>";
var string_with_replaced_smile_and_sad = string_with_replaced_smile.replace(sad, graficSad);
return string_with_replaced_smile_and_sad;
}
$.getJSON('data/messages.json', callback);
var exists = [];
function callback(respond) {
var timeNow = Date.now();
for (var i = 0; i < respond.length; i++) {
var data = respond[i];
if (exists.indexOf(data.id) != -1) continue;
var timeInMessage = data.time * 1000;
var diff_time = (timeNow - timeInMessage);
if (diff_time <= 3600000) {
var rowClone = $('.mess_hide').clone().removeClass('mess_hide');
var newDate = new Date(timeInMessage);
var dateArray = [newDate.getHours(), newDate.getMinutes(), newDate.getSeconds()]
var res = dateArray.map(function(x) {
return x < 10 ? "0" + x : x;
}).join(":");
$('#messages').append(rowClone);
$('.time', rowClone).html(res);
$('.name', rowClone).html(data.user);
$('.message', rowClone).html(smile(data.message));
$('.scroller').scrollTop($('#messages').height());
exists.push(data.id);
}
}
setTimeout(function(){callback(respond)}, 5000);
}
.scroller {
width: 490px;
height: 255px;
max-height: 255px;
overflow-y: auto;
overflow-x: hidden;
}
table#messages {
min-height: 260px;
width: 100%;
background: #fffecd;
border: none;
}
table#messages::-webkit-scrollbar {
width: 1em;
}
table#messages::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
table#messages::-webkit-scrollbar-thumb {
background-color: darkgrey;
outline: 1px solid slategrey;
}
tr {
height: 20%;
display: block;
}
td.time,
td.name {
width: 70px;
max-width: 75px;
text-align: center;
}
td.name {
font-weight: bold;
}
form#text_submit {
display: inline-flex;
align-items: flex-start;
}
input#text {
width: 370px;
height: 30px;
margin-top: 20px;
background: #fffecd;
font-family: 'Montserrat';
font-size: 16px;
border: none;
align-self: flex-start;
}
input#submit {
padding: 0;
margin-left: 21px;
margin-top: 21px;
height: 30px;
width: 95px;
background: #635960;
border: none;
color: white;
font-family: 'Montserrat';
font-size: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scroller">
<table id="messages">
<tr class="mess_hide">
<td class="time"></td>
<td class="name"></td>
<td class="message"></td>
</tr>
</table>
</div>
<form method="POST" id="easyForm">
<input type="text" name="text" id="text">
<input type="submit" value="Send" id="submit">
</form>
</div>
- 因为它假定
var exists
- 阵列,但数组的值([]
)仅在稍后调用$.getJSON(...)
后才会分配给它。所以,当callback
被称为首次值[]
不是为exists
。我们设置只需要移动var exists
的callback.
- 当
callback
由定时器称为第一通话以上,没有传递给它。但计时器需要重新读取文件中的消息并将其显示在屏幕上。因此,取而代之的是setTimeout(function(){callback(respond)}, 5000);
,我们需要setTimeout(function(){$.getJSON('data/messages.json', callback);}, 5000);
。
var exists = [];
$.getJSON('data/messages.json', callback);
function callback(respond) {
var timeNow = Date.now();
for (var i = 0; i < respond.length; i++) {
var data = respond[i];
if (exists.indexOf(data.id) != -1) continue;
var timeInMessage = data.time * 1000;
var diff_time = (timeNow - timeInMessage);
if (diff_time <= 3600000) {
var rowClone = $('.mess_hide').clone().removeClass('mess_hide');
var newDate = new Date(timeInMessage);
var dateArray = [newDate.getHours(), newDate.getMinutes(), newDate.getSeconds()]
var res = dateArray.map(function(x) {
return x < 10 ? "0" + x : x;
}).join(":");
$('#messages').append(rowClone);
$('.time', rowClone).html(res);
$('.name', rowClone).html(data.user);
$('.message', rowClone).html(smile(data.message));
$('.scroller').scrollTop($('#messages').height());
exists.push(data.id);
}
}
setTimeout(function() {
$.getJSON('data/messages.json', callback);
}, 5000);
}
由于callback
需要作为参数传递的数组,setTimeout
必须确保当它调用callback
,它p评估阵列。
变化
setTimeout(callback, 5000);
到
setTimeout(function(){callback(respond)}, 5000);
允许回调与参数作为一个匿名函数将被setTimeout
调用的身体被调用。
此外,作为一个侧面说明,如果你使用的respond.forEach()
代替计数for
循环中,代码会更清洁:
respond.forEach(function(data) {
if (exists.indexOf(data.id) != -1) continue;
var timeInMessage = data.time * 1000;
var diff_time = (timeNow - timeInMessage);
if (diff_time <= 3600000) {
var rowClone = $('.mess_hide').clone().removeClass('mess_hide');
var newDate = new Date(timeInMessage);
var dateArray = [newDate.getHours(), newDate.getMinutes(), newDate.getSeconds()]
var res = dateArray.map(function(x) {
return x < 10 ? "0" + x : x;
}).join(":");
$('#messages').append(rowClone);
$('.time', rowClone).html(res);
$('.name', rowClone).html(data.user);
$('.message', rowClone).html(smile(data.message));
$('.scroller').scrollTop($('#messages').height());
exists.push(data.id);
}
});
我介绍你的编辑,但现在的代码已经停止在所有显示信息。虽然错误是没有) –
但“响应”的值应该来自哪里?在问题代码的当前状态中,'setTimeout()'传递'respond',但它没有在任何地方定义。 (它看起来应该是从'$ .getJSON()'调用返回的,所以我不确定超时事件甚至会如何计算。 – Pointy
@Pointy是的,但是如果没有出现什么错误? –
你能否解释一下你的答案不适合任何一个人,只是说你增加了一个时间和原因。 –
@MartinBarker是的。寻找新的答案。 –