为什么我的代码在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>

Chrome

歌剧 Opera

  1. 因为它假定var exists - 阵列,但数组的值([])仅在稍后调用$.getJSON(...)后才会分配给它。所以,当callback被称为首次值[]不是为exists。我们设置只需要移动var existscallback.
  2. 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); 
 
}

+0

你能否解释一下你的答案不适合任何一个人,只是说你增加了一个时间和原因。 –

+1

@MartinBarker是的。寻找新的答案。 –

由于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); 
    } 
    }); 
+0

我介绍你的编辑,但现在的代码已经停止在所有显示信息。虽然错误是没有) –

+0

但“响应”的值应该来自哪里?在问题代码的当前状态中,'setTimeout()'传递'respond',但它没有在任何地方定义。 (它看起来应该是从'$ .getJSON()'调用返回的,所以我不确定超时事件甚至会如何计算。 – Pointy

+0

@Pointy是的,但是如果没有出现什么错误? –