I use setInterval to update a table every 5 seconds which works great except that it creates a "blinking" effect since the Div refreshes as if I pressed F5.
Is it possible to hide it with example fadeIn() function? I have tried but without any luck so far. Does anyone have any experience with this?
var append_increment = 0;
setInterval(function() {
$("#_change tr").remove();
$.ajax({
type: "GET",
url: "{% url 'tables' %}",
data: {
' tables ': append_increment
}
})
.done(function(response) {
$('#_change').append(response).fadeIn("milliseconds", "linear");
append_increment += 0;
});
}, 5000)
flickering happen because you update the content before the ajax call completes not after it
you can try this
var append_increment = 0;
var Di = setInterval("clearInterval(Di);GetData();", 5000);
function GetData(){
$.ajax({
type: "GET",
url: "{% url 'tables' %}",
data: {' tables ': append_increment}
})
.done(function(response) {
$('#_change tr').html(response).fadeIn(500, "linear");
Di=setInterval("clearInterval(Di);GetData();",5000);
append_increment += 0;
});
}
Also let the html response from server be without <tr></tr>
One thing you can do is make all the changes in memory before issuing a DOM refresh (an expensive process). This can be done with the detach() event:
var append_increment = 0;
setInterval(function() {
$.ajax({
type: "GET",
url: "{% url 'tables' %}",
data: {
' tables ': append_increment
}
})
.done(function(response) {
let $table = $('#_change')
let $parent = $table.parent()
$table.detatch()
$table.find('tr').remove();
$table.append(response);
$parent.append($table);
append_increment += 0;
});
}, 5000)
More than likely, it wouldn't solve flickering. For that, a closer example would need to be given. Some of that could be the amount of painting to the screen, some might be the delay of the AJAX. You are removing and creating elements, so a "flicker" is expected -- this is also where a library like React, which uses a virtual DOM, would excel.
There will always be some flicker (most of the time negligible) when content is updated. A way to reduce this even more is to have two tables and as soon as the background table is filled, then swap it to the front and continue exchanging the two views, but is probably unnecessary.
To minimize the flicker time in this case, I would suggest to move the .remove() function into the .done() in the line right before the .append(). Even though code acts fast, sometimes our eyes can see small delays.
This solution should make sure that the data is not being removed until the AJAX call has completed a return. I would also go one step further and check the response to make sure the call returned successfully just for robustness.
var append_increment = 0;
setInterval(function() {
$.ajax({
type: "GET",
url: "{% url 'tables' %}",
data: {
' tables ': append_increment
}
})
.done(function(response) {
if (/* response['statusCode'] == 200 */) {
$("#_change tr").remove();
$('#_change').append(response);
append_increment += 0;
}
});
}, 5000)
Related
I want to dynamically change the Ajax URL, this is what I have done so far :
var size=1;
var from = 1;
window.addEventListener('mousewheel', function(e){
if(e.wheelDelta<0 && from<5){
from++;
}
else if(e.wheelDelta>0 && from>1){
from--;
}
console.log(from)
});
$.ajax({
type: 'GET',
url: "/api/v1/users?f="+from+"&s="+size,
data: { get_param: 'value' },
dataType: 'json',
With the mousewheel event I change the value of "from", with this variable I can concatenate the string /api/v1/users?f="+from+"&s="+size, to form a URL.
The variable works fine when I give mousewheel event-listener, but doesn't change the Ajax URL.
Any tips?
Your understanding is not right, your scroll code block change the value of from when scrolling is done. But when page loads the ajax call initiates with the initial value of from.
So to solve this you have to call ajax inside event handler.
If i understand you correctly i think following will help you.
You need to move the ajax call inside the event listner to get the values of from in ajax call
Here is my solution based on the code you provided.
var size = 1;
var from = 1;
window.addEventListener('mousewheel', function(e) {
if (e.wheelDelta < 0 && from < 5) {
from++;
} else if (e.wheelDelta > 0 && from > 1) {
from--;
}
$.ajax({
type: 'GET',
url: "/api/v1/users?f=" + from + "&s=" + size,
data: {
get_param: 'value'
},
dataType: 'json',
success: function() {}
})
});
Note: simplified example..
I've got a page with 1000 table rows. For each row, i need to "do some work" on the server via an AJAX call, then in the callback, update that table row saying done.
Initially i tried just firing off the 1000 ajax requests inside the .each selector, but the browser was locking up.
So i changed it to try and use an internal ajax counter, so only ever fire off 50 at a time.
Here's the code:
$('#do').click(function () {
var maxAjaxRequests = 50;
var ajaxRequests = 0;
var doneCounter = 0;
var toDo = $('#mytable tr').length;
$.each($('#mytable > tr'), function (i, v) {
while (doneCounter < toDo) {
if (ajaxRequests <= maxAjaxRequests) {
ajaxRequests++;
doAsyncStuff($(this), function () {
ajaxRequests--;
doneCounter++;
});
} else {
setTimeout(function() {
}, 1000);
}
}
});
});
function doAsyncStuff(tr, completeCallback) {
$.ajax({
url: '/somewhere',
type: 'POST',
dataType: 'json',
data: null,
contentType: 'application/json; charset=utf-8',
complete: function () {
completeCallback();
},
success: function (json) {
// update ui.
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
// update ui.
}
});
}
But the browser is still being locked up. It never goes into the $.ajax complete callback, even though i can see the request coming back successfully (via Fiddler). Therefore its just sleeping, looping, sleeping, etc because the callback is never returned.
I've got a feeling that the entire doAsyncStuff function needs to be asynchronous?
Any ideas on what i am doing wrong (or how i can do this better)?
You are doing a while loop inside the .each callback function, so there is much more ajax request than 1000, the worst is 1000*1000.
You could delay each ajax request with different time.
$('#do').click(function () {
$('#mytable > tr').each(function (i, v) {
var $this = $(this);
setTimeout(function () {
doAsyncStuff($this, function () {
console.log('complete!');
});
}, i * 10);
});
});
The browser gets locked because of the WHILE... You are creating an endless loop.
The while loops runs over and over waiting for the doneCounter to be increased, but the javascript engine cannot execute the success call of the ajax since it is stuck in the while...
var callQueue = new Array();
$('#mytable > tr').each(function(key,elem){callQueue.push($(this));});
var asyncPageLoad = function(){
var tr = callQueue.splice(0,1);
$.ajax({
url: '/somewhere',
type: 'POST',
dataType: 'json',
data: null,
contentType: 'application/json; charset=utf-8',
complete: function () {
completeCallback();
asyncPageLoad();
},
success: function (json) {
// update ui.
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
// update ui.
}
}
};
asyncPageLoad();
This will call the requests one by one. If you want, simply do a for() loop inside to make maybe 5 calls? And increase the amount if the browser is fine.
Actually, I prefer to send new request when current request is done. I used this method to dump db tables (in this work). Maybe it gives an idea.
See this link, check all check boxes and click Dump! button. And you can find the source codes here (see dumpAll function).
I have a function which calls itself with a pause of 2 seconds until the ajax call returns 0. Now it can go on for a long time, hence i wish to pause it or stop it with an external event like a button click.
function create_abcd()
{
var dataString = 'action=create_abcd&type=' + $('#abcd_type').val() + '&count=100';
$.ajax({
type: "POST",
url: "backend.php",
data: dataString,
success: function(msg){
if(msg != "0")
{
$("#abcd_output").append('<p>' + msg + '</p>')
setTimeout(create_abcd, 2000);
}
else
return false;
}
});
}
any help would be greatly appreciated!
Something like:
var needStop = false;
function create_abcd()
{
var dataString = 'action=create_abcd&type=' + $('#abcd_type').val() + '&count=100';
$.ajax({
type: "POST",
url: "backend.php",
data: dataString,
success: function(msg){
if(needStop) {
needStop = false;
return;
}
if(msg != "0")
{
$("#abcd_output").append('<p>' + msg + '</p>')
setTimeout(create_abcd, 2000);
}
else
return false;
}
});
}
$('#button').click(function() {
needStop = true;
});
=)
I think you're trying to solve your problem in a wrong way. You're obviously want to gen notified when some long-running process finishes on the server, so you poll every 2 secs. This will cause a lot of unnecessary requests.
Instead use push mechanism.
Consider using COMET, since you're PHP:
http://www.zeitoun.net/articles/comet_and_php/start
Create a global variable (or even a hidden input on the page).
Create a 'stop' button on the page.
When you click the 'stop' button you just set that input or variable to a special value.
At the top of your create_abcd just check that variable or input before proceeding. If the special value is set, just exit before setting the timeout again.
Look at this code please - how could I kill / update or restart an ajax call (not content that Ajax calls) after the content has already been called?
I mean the $('#posting_main') is called onclick and animated - how to stop ajax and make it another $('#posting_main') on another click?
$(document).ready(function() {
$("#img_x_ok").click(function(e){
e.preventDefault();
var post_text = $.trim($("#main_text_area").val());
var data_text = 'post_text='+ post_text;
if (post_text === "") return;
var xhr = $.ajax({
type: "POST",
url: "comm_main_post.php",
data: data_text,
cache: false,
success: function (data){
//content
$("#posting_main").fadeIn();
$("#posting_main").load("pull_comm.php");
$("#main_text_area").attr("value", "");
$("#posting_main").animate({
marginTop: "+=130px",
}, 1000 );
}
}); //ajax close
}); }); //both functions close
You can abort the current request with:
xhr.abort();
After having done that, you can run another $.ajax(...) to make a second request.
You could implement it like the following. Note that indenting code makes it a lot more readable!
$(document).ready(function() {
var xhr; // by placing it outside the click handler, you don't create
// a new xhr each time. Rather, you can access the previous xhr
// and overwrite it this way
$("#img_x_ok").click(function(e){
e.preventDefault();
var post_text = $.trim($("#main_text_area").val());
var data_text = 'post_text='+ post_text;
if (post_text === "") return;
if(xhr) xhr.abort(); // abort current xhr if there is one
xhr = $.ajax({
type: "POST",
url: "comm_main_post.php",
data: data_text,
cache: false,
success: function (data){
//content
$("#posting_main").fadeIn();
$("#posting_main").load("pull_comm.php");
$("#main_text_area").attr("value", "");
$("#posting_main").animate({
marginTop: "+=130px",
}, 1000 );
}
});
});
});
I am not sure I fully understand your question, however:
xhr.abort() will kill the AJAX request. After calling abort(), you could modify and resend the request, if desired.
$("#posting_main").stop() will stop the fadeIn animation. (And I think you might need to follow that with $("#posting_main").hide() to be sure it isn't left partially visible.)
I'm using jQuery to load html content which contains images, the problem is that i don't want the effect of blinking on images due to loading, to achieve that i need to pre load images inside the response body before inserting it to guarantee a smooth update.
Current Code:
$.ajax({
url: 'hello.php',
method: 'GET',
data:'id='+id,
success: function(data) {
$('#section').html(data);
}
});
Any Solutions?
Thanks
I use the the jQuery onImagesLoad plugin for this.
You could try something like this (untested):
var imagesLoading = 0;
$.ajax({
url: 'hello.php',
method: 'GET',
data: 'id=' + id,
success: function(data) {
imagesLoading = 0;
$(data).filter('img').each(function() {
imagesLoading++;
var image = new Image();
image.onload = function() {
imagesLoading--;
if(imagesLoading == 0) {
$('#section').html(data);
}
};
image.src = $(this).attr('src');
});
}
});
Works fine when I tried it.