Максим Буяков Максим Буяков - 3 years ago 65
Javascript Question

Why does my code not work in Safari or Opera?

There is a function in

js
which displays messages to the table (messages are stored in
json
). In Google Chrome, it works, but Safari, Opera or Microsoft Edge - no!
There is a mistake in code which is associated with the call to
setTimeout (callback, 5000)
(nothing is sent to the callback).So,
For (var i = 0; i <respond.length; i ++)
will not work since
respond === undefined
.

But why is it so?



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

Answer Source
  1. Since it is assumed that the var exists - array, but the value of the array ([]) is assigned to it only later, after the call $.getJSON(...). So, when callback is called for the first time value [] is not set for exists.We just need to move var exists above the first call of callback.
  2. When callback is called by the timer, nothing is passed to it. But timer needs to reread the messages from the file and display them on the screen.So, instead setTimeout(function(){callback(respond)}, 5000); we need 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);
}

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download