2017-07-18 181 views
13

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

回答

13
  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是的。尋找新的答案。 –

5

由於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是的,但是如果沒有出現什麼錯誤? –

相關問題