Hi I'd like some help please. I'm currently learning Ajax and Json so I don't have much experience on it.
I have followed this tutorial in order to fetch the data without page refresh, but I'm having some concerns on it.
The script works fine, the only problem I found is that if I hit refresh it takes a lot of time (about 5-10 seconds)to load the content again.
In Firebug I can see in the Console that it is continiously binding as it's sending requests all time.
Here's the code
HTML
<div class="ajax_results">
<ul id="results"></ul>
</div>
PHP script
$query = "SELECT `img_id`, `image_name`, `title` FROM `images` ORDER BY `img_id` DESC LIMIT 5 ";
$run = mysqli_query($connection, $query) or die(mysqli_error($connection));
$json = array();
while ($row = mysqli_fetch_array($run, MYSQLI_ASSOC)) {
array_push($json, array('image_name' => $row['image_name'],
'title' => $row['title']));
}
echo json_encode(array("json" => $json));
and the JS
$(document).ready(function() {
refresh();
});
function refresh() {
setTimeout(function() {
update_content();
refresh();
}, 200);
}
function update_content() {
$.getJSON("fetch_data.php", function(data) {
$("ul#results").empty();
$.each(data.json, function() {
$("ul#results").append("<li><img src=\"img/uploads/"+this['image_name']+"\" /><br />"+this['title']+"</li>");
});
});
}
Is this a problem?? Can I improve somehow the code?? Any help would be appreciated
To give some extra feedback. If the $.getJSON is directly placed in $(document).ready(function() the content loads more quickly, but if any updates occured eg in the title won't show without refreshing the page. What I actually want to achieve is load the content and if any changes happened to show them without refreshing the page.
Here's another approach to the issue
$(function() {
update_content();
});
function update_content() {
$.getJSON("fetch_data.php", function(data) {
$("ul#results").empty();
$.each(data.json, function() {
$("ul#results").append("<li><img src=\"img/uploads/"+this['image_name']+"\" /><br />"+this['title']+"</li>");
});
setTimeout(function(){
update_content();
}, 1000);
});
}
Here I've moved the setTimeout call into the update_content() function, and increased the timeout to give the browser a bit more breathing room, personally I wouldn't call this every second but it's just an example, I'd probably go with 10 seconds or even longer.
If you don't want it to fire off repeatedly remove the entire setTimeout block.
$(function() {
update_content();
});
function update_content() {
$.getJSON("fetch_data.php", function(data) {
$("ul#results").empty();
$.each(data.json, function() {
$("ul#results").append("<li><img src=\"img/uploads/"+this['image_name']+"\" /><br />"+this['title']+"</li>");
});
});
}
Related
So I have been working on this for hours now, I have read a bunch of StackOverflow posts and I am still having no luck.
I have a page that has 2 sections to it, depending on the int in the database will depend on which section is being displayed at which time.
My goal is to have the page look to see if the database status has changed from the current one and if it has then refresh the page, if not then do nothing but re-run every 10 seconds.
I run PHP at the top of my page that gets the int from the database
$online_status = Online_status::find_by_id(1);
I then use HTML to load the status into something that jquery can access
<input type="hidden" id="statusID" value="<?php echo $online_status->status; ?>">
<span id="result"></span>
So at the bottom of my page, I added some jquery and ajax
$(document).ready(function(){
$(function liveCheck(){
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST',
success:function(data){
if(!data.error){
$newResult = $('#result').html(data);
window.setInterval(function(){
liveCheck();
}, 10000);
}
}
});
});
liveCheck();
});
this then goes to another PHP page that runs the following code
if(isset($_POST['search'])){
$current_status = $_POST['search'];
$online_status = Online_status::find_by_id(1);
if($current_status != $online_status->status){
echo "<script>location.reload();</script>";
}else{
}
}
the jquery then loads into the HTML section with the id of "result" as shown earlier. I know this is a very bad way to do this, and as a result, it will work at the beginning but the longer you leave it on the page the slower the page gets, till it just freezes.
If anyone is able to point me towards a proper method I would be very grateful.
Thank you!!
js:
(function(){
function liveCheck(){
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST',
success:function(data){
if(data.trim() == ''){
location.reload();
}else{
$('#result').html(data);
window.setTimeout(function(){
liveCheck();
}, 10000);
}
}
});
}
$(function(){
liveCheck();
});
})(jQuery)
php:
<?php
if(isset($_POST['search'])){
$current_status = $_POST['search'];
$online_status = Online_status::find_by_id(1);
if($current_status != $online_status->status){
$data = '';
}else{
$data = 'some html';
}
echo $data;
}
Your page is slowing down because you are creating a new interval every time you call the liveCheck function. Over time, you have many intervals running and sending requests to your PHP file concurrently. You can verify this behavior by opening the developer console in your browser and monitoring the Network tab.
What you should do instead is set the interval once, and perform the $.ajax call inside that interval. Additionally, it's good practice to not send a new request if a current request is pending, by implementing a boolean state variable that is true while an request is pending and false when that request completes.
It looks like the intended behavior of your function is to just reload the page when the $online_status->status changes, is that correct? If so, change your PHP to just echo true or 1 (anything really) and rewrite your JS as:
function liveCheck() {
if (liveCheckPending == true)
return;
liveCheckPending = true;
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST'
}).done(function(data){
if (!data.error)
location.reload();
}).always(function(data){
liveCheckPending = false;
});
}
var liveCheckPending = false;
setInterval(liveCheck, 10000);
I've recently started learning jQuery and I'm trying to make a little messaging system, I've gotten the messages to update every 2 seconds. However, I don't want the messages to update if there aren't any new messages. This is my current message updating code.
$(document).ready(function () {
setInterval(function() {
$.get("get_messages.php", function (result) {
if ($('.messages').html() != result){
$('.messages').html(result);
}
});
}, 2000);
});
The if statement doesn't seem to be working even though the div and result should be the same.
I hope that you have timestamp or messageID on server that could tell your script if there are new messages after last check.
ex.
var lastMessageID = 0;
function checkMessages(){
$.ajax(url,{
data:{
last_message_id:lastMessageID
},
success:function(data){
// Count new messages
if (Object.keys(data).length > 0){
$.each(data,function(index, item){
$('.messages').prepend("<span class='message'>"+item.message+"</span>");
});
// We suggest that this is our last message
lastMessageId = data[Object.keys(data).length-1].id;
}
}
});
}
var intervalM = setInterval(function(){
checkMessages();
},2000);
And please save some trees by using gziped JSON data. :)
I've written the following Jquery to send a Heartbeat back to PHP every 3 seconds and it works fine. The reason I'm doing this is to understand what users are currently logged in and using the site.
setInterval(function () {
$.post('includes/heartbeat.php', {'heartBeatConfirmation': '1'});
},3000);
The catch I'm finding is it continues to heartbeat when users aren't looking at the site - eg: they still have the browser open but are looking at other pages or doing something else.
Is there a way to update this so it only sends the AJAX heartbeat if the user is using the site?
You can check if window is focused and only heartbeat if it's focused.
Try this:
$(window).focus(function() {
heartbeat = setInterval(function () {
$.post('includes/heartbeat.php', {'heartBeatConfirmation': '1'});
},3000);
})
.blur(function() {
clearInterval(heartbeat);
});
$(window).focus();
$(document).ready(function(){
heartBeatInterval = null;
$(window).focus(function() {
if(heartBeatInterval == null){
heartBeatInterval = setInterval(function () {
$.post('includes/heartbeat.php',
{'heartBeatConfirmation': '1'}
);
console.log('We have the fouces of the active tab');
},1000);
}
});
$(window).blur(function() {
heartBeatInterval = null;
console.log('We have the lost the focus of the active tab');
});
});
It is just a matter of taste I guess:
$(window)
.on('mouseleave', function(){
clearInterval(inside);
})
.on('mouseenter', function(){
inside = setInterval(function () {
$.post('includes/heartbeat.php', {'heartBeatConfirmation': '1'})
}, 3000)
})
JSFIDDLE ( Reminder: window is "Result" Frame ).
I have this code on my page...
the jQuery
window.setInterval( function(){
$.get("php/get_posts.php", function(data) {
$('.post-container').prepend(data);
});},10);
This is the get_posts.php
<?php
include('dbconnect.php');
session_start();
$uid= $_SESSION['uid'];
$get_ids=mysql_query("SELECT * FROM posts ORDER BY id DESC LIMIT 1");
while($row = mysql_fetch_array($get_ids)){
$id=$row['id'];
$sm=$row['message'];
}
$get_lpid=mysql_query("SELECT * FROM users WHERE uid='$uid'");
while($row_o = mysql_fetch_array($get_lpid)){
$l_pid=$row_o['lastviewed'];
}
if($id!=$l_pid){
$insert=mysql_query("UPDATE users SET lastviewed='$id' WHERE uid='$uid' ");
if($insert){?>
<div class='media'><img src='img/profile_pictures/thumbs/thumb_13718921232_119055628287843_1500172795_n.jpg' class='img-circle post-circle pull-left'><div class='media-heading'><a href='#'>Pratik Sonar</a><div class='pull-right'><small>12.00PM</small></div></strong></div><div class='media-body'><?php echo $sm ?></div></div>
<?php } else{
}
}
else{
}?>
This technique seems to work on every browser except chrome. I have tested ie, safari, firefox and opera all are working. Can anyone enlighten me on this thing? Is there something I don't know or am I missing?
Try to wrap your code into this function:
$(document).ready(function() { ... });
Like:
$(document).ready(function() {
window.setInterval( function(){
$.get("php/get_posts.php", function(data) {
$('.post-container').prepend(data);
});},10);
});
You're probably better off using setTimeout() too.
Now the code runs when the DOM is fully loaded.
Why are you using window.setInterval?
It's simply setInterval(), without any parent.
Try
$(document).ready(function() {
setInterval(function(){
$.get("php/get_posts.php", function(data) {
$('.post-container').prepend(data);
});
},10);
});
Thank You guys for all your concerns. Well at last the bug got fixed by this chunk of code. I guess setTimeout gain gains victory over setInterval
$(document).ready(function() {
window.setTimeout(function(){
$.ajax({
type: "GET",
url: "php/get_posts.php",
}).done(function( data ) {
$('.post-container').prepend(data);
});
},10);
});
this is my PHP code_
if(isset($_REQUEST['show']))
{
$con=mysqli_connect("localhost","root","","server_name");
$show = mysqli_query($con, "SELECT * FROM name1 ORDER BY date DESC");
$html='';
while($showE = mysqli_fetch_array($show))
{
$html.= '<h3>'.$showE['un_name'].'</h3>';
$html.= '<div>'.$showE['un_name_dec'].'</div>';
}
echo $html;
//End of while loop
}
this is jquery code_
$.post('preprocessor.php', '&show=', function(data) {
$("#accordion").html(data);
$("#accordion").accordion({
collapsible: true,
icons: {
activeHeader: "ui-icon-triangle-1-s",
header: "ui-icon-triangle-1-e"
}
});
});
this is body_
<div id='accordion'>
</div>
i am not getting real time updates, everything is working, but the Ajax thing is not working... it works if i refresh or reload the page but not itself
What you are looking for is setTimeout.
$("#accordion").accordion({
collapsible: true,
icons: {
activeHeader: "ui-icon-triangle-1-s",
header: "ui-icon-triangle-1-e"
}
});
setInterval(makePostCall, 15000); // decide interval to fetch new updates. 15 sec for example
function makePostCall(){
$.post('preprocessor.php', '&show=', function(data) {
$("#accordion").html(data);
});
}
But this is not the proper way of doing this kind of stuff. Consider using Ajax Push Engine
it works if i refresh or reload the page but not itself
For this you need to use setInterval(); function which will check every specific time period which is given:
setInterval(function(){
$.post('preprocessor.php', '&show=', function(data) {
$("#accordion").html(data);
$("#accordion").accordion({
collapsible: true,
icons: {
activeHeader: "ui-icon-triangle-1-s",
header: "ui-icon-triangle-1-e"
}
});
});
},5000); //<---- runs every 5000 ms
This will run every 5 seconds and will update the #accordion div.
try:
$.post('preprocessor.php', {show:''}, function(data) {
$("#accordion").html(data);
$("#accordion").accordion({
collapsible: true,
icons: {
activeHeader: "ui-icon-triangle-1-s",
header: "ui-icon-triangle-1-e"
}
});
},'html');
Are you setting interval to call the code in certain intervals? All you need to do is,
on JavaScript add:
setinterval(function(){/* do the post here */ },1000 /*this is time */);