Freeing DOM element memory / resources created by ajax request - javascript

I have created a web page that displays data retrieved from a database via a jQuery $.ajax call. The web page is part of a digital signage system that will be displayed continuously.
The $.ajax response is formatted HTML generated server side. This HTML is then inserted into a div element after removing any existing HTML from the div.
I then attach a jQuery marquee plugin (http://aamirafridi.com/jquery/jquery-marquee-plugin) to some of the newly created div elements with the .marquee class.
var marqueeCounter = 0;
var appBusy = false;
function update() {
if (appBusy == false) {
$.ajax({
url: '/get/html/from/server',
cache: false,
success: function (response) {
$('#div-container').empty();
$('#div-container').html('');
$('#div-container').html(response);
$('.marquee').each(function () {
$(this).width($(this).parent().width());
});
$('.marquee').bind('beforeStarting',function () {
appBusy = true;
marqueeCounter++;
}).bind('finished', function () {
$(this).marquee('pause');
marqueeCounter--;
if (marqueeCounter < 1) {
appBusy = false;
}
}).marquee({
duration: 3500,
allowCss3Support: true,
duplicated: false
});
}
});
}
setTimeout(update, 5000);
}
The problem I am facing is that after hours of running this app, the marquees gradually slow down and eventually the browser (firefox) crashes.
Looking at the memory usage in firefox and chrome, the elements that are replaced with each $.ajax call don't seem to be freed from memory and the eventually choke the browser.
The DOM element count goes up and up as does memory usage.
I'm probably doing something fundamentally wrong here but cannot figure out how to free these resources up.
Thanks.
EDIT 1:
I have tried using the plugins destroy method as per the example on the developers page but it didn't help.
I have removed references to the plugin which results in the following code:
function update() {
if (appBusy == false) {
$.ajax({
url: '/get/html/from/server',
cache: false,
success: function (response) {
$('#div-container').empty();
$('#div-container').html(response);
}
});
}
setTimeout(update, 5000);
}
The number of nodes continues to grow and never decreases.
EDIT 2:
I have re-written this function in native javascript and the problem seems to have gone away.
function update()
{
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById("div-container").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "/get/html/from/server", true);
xmlhttp.send();
setTimeout(update, 5000);
}
Why would jQuery be returning different results?

Related

Executing a url without opening it on the browser in Javascript / Jquery

I have a local page that pulls data from a database and sends out a message. So I'm trying to have this page executed using javascript on "success" of another function. The problem is everything I've tried doesn't seem to execute that page, while the only success I've had on executing that page is using a window pop up, which is not desired.
This is the pop up code (undesired):
function sendMsg(){
var wnd = window.open("http://localhost/url");
if(wnd){
setTimeout(function () { wnd.close();}, 4000);
}
}
sendMsg();
And these are the codes I've tried but didn't execute the url:
$.get("http://localhost/url")
And this one which is from another answer here on SO.
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
var response = xmlhttp.responseText; returned value
}
}
xmlhttp.open("GET","http://localhost/url",true);
xmlhttp.send();
How can I have this URL executed without opening it on the browser in any way?
Just to be clear, I know the other two codes didn't work because I would have received a message.
if you really need a return data/page from get
you should do something like this.
$.get( "url", function( data ) {
console.log(data); // return data/page
alert( "Done load." );
});
# use ajax
$.ajax({
url: "url",
type: "GET",
success : function( data ){
console.log(data); // return data/page
alert("Done LOad");
}
});
anything else can refer : https://api.jquery.com/jquery.get/
I believe jQuery's load() method may be useful for this. For example, have a div in your HTML and just set it to hidden in the CSS.
jQuery load() Method
HTML:
<div id='myHiddenPage'></div>
CSS:
#myHiddenPage {
display: none;
}
jQUERY:
$(funtion() {
$('#myHiddenPage').load('www.myurl.com');
});

DOM Elements created with jQuery AJAX call not freed from memory

I asked this yesterday but have added more information and restructured the question.
I have built a web app for a digital signage system that will be constantly running.
There is a jQuery AJAX call that retrieves html from the server and replaces the content of a div with the response so that there is no visible ugly page refresh.
The problem is that the browser is running out of memory and crashing after several hours of operation. Looking at the timeline in Chrome, it seems that although the HTML elements are replaced, they are somehow kept in the DOM.
The following jQuery code produces the following timeline:
function loadDiary()
{
if ((diaryBusy == false) && (navigatorOnline))
{
diaryBusy = true;
$.ajax (
{
url : '/get/data/from/server',
cache : false,
success : function(response)
{
$('#diary').empty();
$('#diary').html(response);
diaryBusy = false;
loadDiaryTimer();
},
error : function()
{
diaryBusy = false;
loadDiaryTimer();
}
}
);
}
}
The following javascript produces the following timeline:
function loadDiary()
{
if ((diaryBusy == false) && (navigatorOnline))
{
diaryBusy = true;
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById('diary').innerHTML = '';
document.getElementById('diary').innerHTML = xmlhttp.responseText;
diaryBusy = false;
loadDiaryTimer();
}
}
xmlhttp.open('GET','/get/data/from/server',true);
xmlhttp.send();
}
}
You can see that with the jQuery the number of nodes growing to 358278 in the short test when only 1835 are required.
This is forcing garbage collection sooner yet the memory usage increases over time.
In the second example, the maximum number of nodes is 1835 and garbage collection was never needed.
The second piece of code would be fine, but I need to attach a jQuery plugin to some of the dynamic content so a non jQuery solution isn't an option.
Any suggestions why this may be happening and how to stop the number of elements growing?
Thanks for reading.

If iframe refresh failed, then X

I'm using the following script to refresh my <iframe> every 60 seconds.
<script type=text/javascript>
setInterval(function() {
document.getElementById("tracker").src += "";
}, 60000);
</script>
I would like to show a different page/<iframe> if the refresh fails. For example, if I'm not connected to any network, then obviously any page refresh will show the "page not found" error.
Instead, I would like to display a different <iframe> (e.g. tracker2) or different page/message/image to say "Offline". Of course the <iframe> will keep refreshing itself until there's internet connection.
I'm pretty sure that's not possible, however I may be wrong. Is it possible?
If the <iframe> you're loading is on a different domain, then no, it's not possible. Otherwise, you can use Ajax to check the status:
var rq = new XMLHttpRequest();
rq.open('GET', document.getElementById('tracker').src, true);
rq.onreadystatechange = function() {
if(rq.readyState === 4) {
if(rq.status === 200) {
// All is well
} else {
// Show your backup element
}
}
};
rq.send(null);
You can check http code of your iframe and depending on that you can render another page
You can use Jquery ajax to load page content and check page status. For example:
<script type=text/javascript>
setInterval(loadIframe, 60000);
function loadIframe()
{
$.ajax({
type: 'GET',
url: 'document.getElementById('tracker').src',
success: function(data){
alert('horray! 200 status code!');
document.getElementById("tracker").src += "";
},
error: function(data){
//get the status code
if (code == 400) {
alert('400 status code! user error');
}
if (code == 500) {
alert('500 status code! server error');
}
},
});
}
</script>

ajax - javascript function to refresh a div

I'm trying to have a div refresh after a callback using ajax functions. Basically, I want /includes/view_game/achievements.inc.php to be reloaded in the div #achievements_tab. The callback (I didn't include it in codes below) works well and triggers the AchievementRefresh function found below (the opacity of the div changes to 0.5, but it remains like this and the refresh is not made).
Those two functions are used for another similar ajax refresh on my site that works well. So I tried to modify the code, but since it's for a slightly different purpose, maybe I have the wrong approach.
function AjaxPost(url, success_function) {
xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
alert("Your browser doesn't support AJAX. You should upgrade it!")
return
}
xmlHttp.onreadystatechange = success_function;
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
This AjaxPost function is used in the other function below:
function AchievementRefresh() {
div('achievements_tab').style.opacity = 0.5;
div('highscore_pages').innerHTML = '<img src="'+site_url+'/images/loader.gif" />';
AjaxPost(site_url+"/includes/view_game/achievements.inc.php?", '',
function () {
div('achievements_tab').innerHTML = xmlHttp.responseText;
div('achievements_tab').style.opacity = 1;
}
)
}
Use load
$('#achievements_tab').load('/includes/view_game/achievements.inc.php');
See: http://api.jquery.com/load/
Edit
E.g.
function AchievementRefresh() {
$('#achievements_tab').css('opacity', 0.5);
$('#highscore_pages').html('<img src="'+site_url+'/images/loader.gif" />');
$('#achievements_tab').load('/includes/view_game/achievements.inc.php')
.success(function() {
$('#achievements_tab').css('opacity', 1);
});
}
Try this.
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
div('achievements_tab').innerHTML = xmlHttp.responseText;
div('achievements_tab').style.opacity = 1;
}
}
};`
Name and id is example.
Also, some changes:
AjaxPost(site_url+"/includes/view_game/achievements.inc.php");
var params= 'name'+encodeURIComponent(name)+'&id='+encodeURIComponent(id)
Parameters shouldn't be in URL.
xmlhttp.send(params);

Simple AJAX request using jQuery not working on IE

This is my code, which sometimes works and sometimes doesn't.
var resolve_ajax_login=function(){
$.ajaxSetup({cache:false });
var loginvar=$("#inputlogin").attr("value");
var senhavar=$("#inputsenha").attr("value");
$.post("../model/php/login_ajax.php",
{login:loginvar, senha:senhavar},
function(responseText){
if (responseText=="ok"){
window.location="areatrab.php";
}else{
$("#inputlogin").attr("value","");
$("#inputsenha").attr("value","");
$("#divmensagem").html("<span style='color:red;font-size:70%;'>"+responseText+"</span>");
}
}
);
return false;
};
Ok. It's in portuguese but I think you get the general picture. Sometimes this works, no problem, but some other times (only in IE, no problem whatsoever in Firefox) it throws a javascript error in my jquery.js file (minified). The error description is as follows:
Object doesn't support this property or method: jquerymin.js line 123 character 183..
which amounts to...
{return new A.XMLHttpRequest}
somewhere in the middle of the jquery.js file. It seems to be very IE-specific, as I had no such problems on Firefox. This guy apparently had the same problem as I did, but got no responses yet.
Has anyone else seen this? Thanks in Advance
P.S.: I run IE 8
Have you tried using a full URL instead of ../model...? For example: http://www.mysite.com/model/login_ajax.php
Also, maybe try modifying the 'xhr' property using jQuery's .ajax method... something like:
var loginvar = $("#inputlogin").val();
var senhavar = $("#inputsenha").val();
var ajax_obj = null;
var resolve_ajax_login = function() {
if(ajax_obj !== null) {
try {
ajax_obj.abort();
} catch(e) {
}
}
ajax_obj = $.ajax({
type: 'POST',
cache: false,
url: '../model/php/login_ajax.php',
data: {login:loginvar, senha:senhavar},
dataType: 'text',
timeout: 7000,
success: function(data)
{
if(response == 'ok') {
alert("right on!");
} else {
alert("not ok");
return;
}
},
error: function(req, reqStatus, reqError)
{
alert("error");
return;
},
'xhr': function() {
if(ajax_obj !== null) {
return ajax_obj;
}
if($.browser.msie && $.browser.version.substr(0,1) <= 7) {
return new ActiveXObject("Microsoft.XMLHTTP");
} else {
return new XMLHttpRequest();
}
}
});
}
It's something to do with the order in which you try all the different types of browsers in order to create the right kind of XMLHTTP REQUEST object.. I'll explain it in more detail in the following page:
AJAX inconsistency in IE 8?

Categories

Resources