2017-07-18 16 views
13

Có chức năng trong js hiển thị thông báo cho bảng (tin nhắn được lưu trữ trong json). Trong Google Chrome, nó hoạt động, nhưng Safari, Opera hoặc Microsoft Edge - không! Có lỗi trong mã được liên kết với lệnh gọi tới setTimeout (callback, 5000) (không có gì được gửi đến gọi lại) .So, For (var i = 0; i <respond.length; i ++) sẽ không hoạt động kể từ respond === undefined.Tại sao mã của tôi không hoạt động trong Safari hoặc Opera?

Nhưng tại sao lại như vậy?

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 Chrome

Opera Opera

Trả lời

13
  1. Kể từ khi nó được giả định rằng var exists - mảng, nhưng giá trị của mảng ([]) chỉ được gán cho nó sau, sau khi gọi $.getJSON(...). Vì vậy, khi callback được gọi là giá trị thời gian đầu tiên [] không được thiết lập cho exists Chúng tôi chỉ cần di chuyển var exists trên lệnh gọi đầu tiên của callback.
  2. Khi callback được gọi bởi bộ đếm thời gian, không có gì được truyền cho nó. Nhưng bộ hẹn giờ cần phải đọc lại các tin nhắn từ tập tin và hiển thị chúng trên màn hình. Thay vào đó, thay vào đó, setTimeout(function(){callback(respond)}, 5000); chúng ta cần 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

Bạn có thể giải thích câu trả lời của bạn cho bất kỳ ai không chuyên nghiệp, chỉ cần nói rằng bạn đã thêm thời gian và lý do tại sao. –

+1

@MartinBarker Yes.Look câu trả lời mới. –

5

Kể từ callback đòi hỏi một mảng để được thông qua như một cuộc tranh cãi, setTimeout phải đảm bảo rằng khi nó gọi callback, nó p lừa mảng.

Thay đổi

setTimeout(callback, 5000);

để

setTimeout(function(){callback(respond)}, 5000);

cho phép gọi lại được gọi với một cuộc tranh cãi như cơ thể của một chức năng vô danh mà sẽ được gọi bởi setTimeout.

Ngoài ra, như một mặt lưu ý, nếu bạn sử dụng respond.forEach() thay vì một vòng lặp đếm for, mã sẽ được nhiều bụi:

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

tôi giới thiệu nội dung chỉnh sửa, nhưng bây giờ các mã đã ngừng hiển thị tin nhắn nào cả. mặc dù lỗi là không có) –

+0

Nhưng giá trị của 'đáp ứng' phải đến từ đâu? Trong trạng thái hiện tại của mã trong câu hỏi, 'setTimeout()' chuyển 'response' nhưng nó không được định nghĩa ở bất kỳ đâu. (Có vẻ như nó được cho là quay trở lại từ một cuộc gọi '$ .getJSON()', vì vậy tôi không chắc chắn làm thế nào thời gian chờ điều thậm chí con số. – Pointy

+0

@Pointy Có, nhưng những gì là sai nếu điều này không xuất hiện? –

Các vấn đề liên quan