I have an MVC application and I am using a gif to indicate loading by using JQuery.
The code below works okay on Chrome.
// show loading
window.parent.loading(true);
$.get('#Url.Action("getUserAccounts")', function (data) {
$("#usersAccountsDiv").html(data);
window.parent.resizeIframe();
});
However, in Firefox, the loading indicator freezes along with the whole page. Since the operation is not taking too much time, I tried to mock this by using a sleep function like that and the results were the same on Chrome and Firefox. While Chrome keeps playing the gif, Firefox stops playing it:
window.parent.loading(true);
$.get('#Url.Action("getUserAccounts")', function (data) {
function (data) {
function sleepFor(sleepDuration) {
var now = new Date().getTime();
while (new Date().getTime() < now + sleepDuration) {
/* Do nothing */
}
}
sleepFor(10000);
$("#usersAccountsDiv").html(data);
window.parent.resizeIframe();
});
I used w3schools' editor to see the difference:
w3 try editor
I used this code below in both browsers for comparison:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$("#showMe").show();
$.get("demo_test.asp", function(data, status){
function sleepFor(sleepDuration) {
var now = new Date().getTime();
while (new Date().getTime() < now + sleepDuration) {
/* Do nothing */
}
}
sleepFor(10000);
});
});
});
</script>
</head>
<body>
<button>Send an HTTP GET request to a page and get the result back</button>
<div id="showMe" style="display:none">
<img src="https://media.giphy.com/media/3o7bu3XilJ5BOiSGic/giphy.gif" />
</div>
</body>
</html>
I tried to mock it that way because I could not reproduce this issue on my local. It only happens in QA environment. The operation takes longer in QA and that causes Firefox to freeze.
On Firefox, once the code hits to $("#usersAccountsDiv").html(data); function, the problem occurs. That's why I remove .html() function and replaced it with sleepFor function to make the JS engine wait on Firefox. My expectation was gif should keep playing as it does in Chrome while I wait for sleepFor function to end.
First, replace
sleepFor(10000);
$("#usersAccountsDiv").html(data);
window.parent.resizeIframe();
with
window.setTimeout(function() {
$("#usersAccountsDiv").html(data);
window.parent.resizeIframe();
}, 10000);
See https://developer.mozilla.org/en-US/docs/Web/API/setTimeout for usage of setTimeout().
Do not make busy-waiting loops like your function sleepFor() - this precisely bogs down the browser's JavaScript engine.
Then, I suggest to focus on the first code snippet (without sleepFor() nor setTimeOut()) and use the Firefox debug console (press F12 key) to figure out what kind of answer you get from the server on your get() request.
To do this, press F12, a sidebar opens, go to the "network" tab and look for the GET request that your code sends (each GET is a line, timing diagram to the right of it). Select it by clicking, another sub-window opens with details of the GET request - go to the "response" sub-window and inspect whether it is what you expect.
I have checked the response data returning from get action and I found the solution. Returned html data contains 18 lines of scripts.
$("#usersAccountsDiv").html(data);
After that, I debugged the JQuery html and append methods and realized that script tags are making Firefox freeze in a for loop (domManip function). I resolved the issue by reducing the included scripts to my response but it is still a weird problem. All those scripts are working fine on Chrome but not on Firefox.
Thanks!
Related
I've seen a couple similar questions on here already, but none that were close enough to what I want that actually had an answer.
I have a CF page. The query that generates most of the page has the potential, depending on the user, to go long and then we're staring at a blank page for a moment, thinking that it's unresponsive.
Basically, I've been tasked with having a loading gif of sorts on the page until it's ready so that the user doesn't think it's crashed.
I've tried the CFFLUSH method, and besides the fact that it doesn't really work as expected (we're using IE9 and IIS and apparently there are settings not playing nicely with each other) it also leaves the "loading" text/image on the screen once the main page loads. I want it to go away once the page loads.
I can't use jQuery
I can't really use native Ajax anymore than what I can access using CFAJAX calls, etc.
The other developer here has suggested using CFWINDOW like he does elsewhere to check if the session is timing out, etc., but I haven't figured out how yet. I'd be open to those if someone could guide me on that.
Thoughts?
cfdiv.
The other developer was racking his brains since he said he knew he did this somewhere before. In the end, he found it and it was a cfdiv.
Basically, you take the "offending" (i.e.: long lasting) code and cut it out into another file. Then, you add a <cfajaximport> to the head and then, in place where the code was you put:
<cfdiv id="divID" name="divName" bind="url:pageWithCode.cfm?(anyparameters)" bindonload="true" />
and be sure to refer to the parameters in the file as "url." and it all works perfectly!
Thanks all for your help!
Maybe i am missing something but the answer seems simple to me. Just spit up the page with executes the query and the page that shows the result. The page that executes the query can also contain the actual formatting. Below a simple example.
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<div id="body" style="width:100px">loading statement or loading images</div>
<script>
function load_url(url)
{
var obj;
if (window.XMLHttpRequest) obj = new XMLHttpRequest();
else if (window.ActiveXObject) obj = new ActiveXObject("Microsoft.XMLHTTP");
if (obj !== null)
{
obj.onreadystatechange = function()
{
if (obj.readyState === 4)
{
var response = obj.responseText;
alert(response);
document.getElementById('body').innerHTML = response;
}
};
obj.open("GET", url, true);
obj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
obj.send();
}
}
load_url('/loadActualdata.cfm?timestamp=' + new Date().getTime().toString());
</script>
</BODY>
</HTML>
HTML on loadActualdata.cfm
<table style="width:100%;border:1px solid red" border="0" cellpadding="0" cellspacing=""0">
<tr>
<td><b>test</b></td>
</tr>
</table>
Is it possible to see all javascript function calls as a tree in any web debugger?
UPDATE
I mean debugger could remember each function call, from which other function it was done, also it could remember stack frame per each call and entire DOM snapshot.
UPDATE 2
The following page code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Trace and log all javascript functions calling tree/graph?</title>
<script type="text/javascript">
function init() {
setDiv2("This div text was changed once");
setDiv2("This div text was changed twice");
};
function setDiv2(text) {
document.getElementById("div2").innerHTML = text;
}
window.onload = init;
</script>
</head>
<body>
<h1>Trace and log all javascript functions calling tree/graph?</h1>
<p>Stack Overflow Question #20910262</p>
<div id="div1">This div will not changed</div>
<div id="div2">This div text will change</div>
<div>
<h2>The call graph should be follows</h2>
</div>
</body>
</html>
Should give the following call graph
because setDiv2() function called twice.
In profiler's top-down view it is visible as
where setDiv2() function drawn once. This is good for profiling, but this is not call graph.
So the question persists.
UPDATE 3
Moreover, users should be able to step on each tree node and see the values of all variables and the state of entire DOM tree at the moment, represented by the node.
Your need is obviously a custom profiler. Chrome JS profiler is a good handy tool. but i don't think that is correct tool for you. Also among the others Firebug or Safari profiler (webkits) won't do the job for you. So you need to develop your own custom profiler. since the others are only interested/targeted with CPU time profiling or memory usage profiling or CSS selectors.
You can modify Object.prototype.constructor. so all the global functions you have defined can have special profile method. or borrowed method via Function.prototype.bind() you can populate all the data you need from executions into a special data object. which can be like in a tree hierarchy. Here is the places to start a custom profiler.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
and
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
Let us know if you can complete a custom profiler for javascript. it will be really useful tool for more people including me.
Yes, of course. Every browser has support to debug javascript code. You need to read about in specific browser you use. For example you can open developer tools in Mozilla Firefox by clicking Ctrl+Shift+K. In Internet Explorer you need to click F12 key. For Google Chrome Ctrl+Shift+I. After openning tools, you need to set up breakpoint at which you want to see stack trace, local variables and etc. After setting breakpoint you need to reload web-page, because when page is loaded all js is executed first time, and you can catch after loading, or make some event for catch breakpoint.
try console.trace() in your setDiv2 function , in this case you will see the both tree calls in chrome console.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Trace and log all javascript functions calling tree/graph?</title>
<script type="text/javascript">
function init() {
setDiv2("This div text was changed once");
setDiv2("This div text was changed twice");
};
function setDiv2(text) {
document.getElementById("div2").innerHTML = text;
console.trace()
}
window.onload = init;
</script>
</head>
.....
How can I show or hide the entire Firebug panel and its icon at runtime ?
I browsed through Firebug.chrome but could not find anything appropriate.
I tried the following snippet which did not have any apparent effect, Firebug Lite was still there.
Firebug.extend(function (FBL) {
alert('TEST'); // This is run
FBL.Firebug.chrome.deactivate(); // No errors but nothing happens
});
The anonymous callback function is definitely invoked.
Quite an old post, but still popping on google search for such a question.
I'm not even sure which version of Firebug Lite you were using, but the following works well with 1.4.0 (once the page has loaded):
Firebug.chrome.open();
Firebug.chrome.close();
Firebug.chrome.toggle();
Firebug-Lite is enabled through the javascript function in the bookmark, and from there it just loads the javascript hosted at getfirebug.com.
If you control the website you're looking at, and want firebug to pop-up for that website, then you can add this to your code:
<script type="text/javascript">
function bookmarklet(F,i,r,e,b,u,g,L,I,T,E){
if(F.getElementById(b))
return;
E=F[i+'NS']&&F.documentElement.namespaceURI;
E=E?F[i+'NS'](E,'script'):F[i]('script');
E[r]('id',b);
E[r]('src',I+g+T);E[r](b,u);
(F[e]('head')[0]||F[e]('body')[0]).appendChild(E);
E=new Image;
E[r]('src',I+L);
}
$(document).ready(function() {
bookmarklet(document,'createElement','setAttribute',
'getElementsByTagName','FirebugLite','4','firebug-lite.js',
'releases/lite/latest/skin/xp/sprite.png','https://getfirebug.com/','#startOpened');
});
</script>
Or, did you mean that when you're browsing you always want Firebug / Firebug-Lite at the bottom?
I have used Javascript onlaod like this:
function check()
{
var pic = new Image();
pic.src= "images/first.jpg";
pic.onload = function()
{
alert("Uploaded");
}
}
This is html code where the function is called.
<input type="button" onclick="check()" value="Check" />
It works for both safari and firefox. But with IE, first time it works but when I click on check Button next time it does not work. It also works when cache is cleared.
Can anyone help me what problem might occur here.
Thanks in advance
This should not be a problem in IE8.
IE6 (not sure about 7) is notoriously eager to use cached files, and when taking from the cache the load is not correctly calculated (I recall there being an interesting bug report on this, look for it on MS's site).
It can be solved by adding a [useless] parameter that forces a reload of the cached file:
pic.src= "images/first.jpg?nocache="+Math.random()
perhaps the onload() is too early?
jquery uses a function
$(document).ready(function(){}
that is executed when the page has finished loading.
Perhaps you need some similar function.
I have a website with a form that uses TinyMCE; independently, I use jQuery. When I load the form from staging server on Firefox 3 (MacOS X, Linux), TinyMCE doesn't finish loading. There is an error in Firefox console, saying that t.getBody() returned null. t.getBody(), as far as I understand from TinyMCE docs, is a function that returns document's body element to be inspected for some features. Problem doesn't occur when I use Safari, nor when I use Firefox with the same site running from localhost.
Original, failing JavaScript-related code looked like this:
<script type="text/javascript" src="http://static.alfa.foo.pl/json2.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.ui.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
tinyMCE.init({ mode:"specific_textareas", editor_selector:"mce", theme:"simple", language:"pl" });
</script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.jeditable.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.tinymce.js"></script>
<script type="text/javascript" charset="utf-8" src="http://static.alfa.foo.pl/foo.js"></script>
<script type="text/javascript">
$(document).ready(function(){
/* jQuery initialization */ });
</script>
I tried changing script loading order, moving tinyMCE.init() call to the <script/> tag containing $(document).ready() call—before, after, and inside this call. No result. When tinyMCE.init() was called from within $(document).ready() handler, the browser did hang on request—looks like it was too late to call the init function.
Then, after googling a bit about using TinyMCE together with jQuery, I changed tinyMCE.init() call to:
tinyMCE.init({ mode:"none", theme:"simple", language:"pl" });
and added following jQuery call to the $(document).ready() handler:
$(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); });
Still the same error. But, and here's where things start to look like real voodoo, when I added alert(i); before the tinyMCE.execCommand() call, alerts were given, and TinyMCE textareas were initialized correctly. I figured this can be a matter of delay introduced by waiting for user dismissing the alert, so I introduced a second of delay by changing the call, still within the $(document).ready() handler, to following:
setTimeout('$(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); });',1000);
With the timeout, TinyMCE textareas initialize correctly, but it's duct taping around the real problem. The problem looks like an evident race condition (especially when I consider that on the same browser, but when server is on localhost, problem doesn't occur). But isn't JavaScript execution single-threaded? Could anybody please enlighten me as to what's going on here, where is the actual problem, and what can I do to have it actually fixed?
The browser executes scripts in the order they're loaded, not written. Your immediate scripts -- tinyMCE.init(...) and $(document.ready(...)); -- can execute before the files finish loading.
So, the problem is probably network latency -- especially with 6 separate scripts (each requiring a different HTTP conversation between the browser and server). So, the browser is probably trying to execute tinyMCE.init() before tiny_mce.js has finished being parsed and tinyMCE is fully defined.
If don't have Firebug, get it. ;)
It has a Net tab that will show you how long it's taking all of your scripts to load.
While you may consider the setTimeout to be duct taping, it's actually a decent solution. Only problem I see is that it assumes 1 second will always fix. A fast connection and they could see the pause. A slow connection and it doesn't wait long enough -- you still get the error.
Alternatively, you might be able to use window.onload -- assuming jQuery isn't already using it. (Can anyone else verify?)
window.onload = function () {
tinyMCE.init(...);
$(document).ready(...);
};
Also, was that a direct copy?
<script type="text/javascript">
$(document).ready(function(){
/* jQuery initialization */ }
</script>
It's missing the ) ending ready:
<script type="text/javascript">
$(document).ready(function(){
/* jQuery initialization */ })
</script>
Missing punctuation can cause plenty of damage. The parser is just going to keep reading until it finds it -- messing up anything in between.
Since this is the first page which came in google when I asked myself the same question, this is what i found about this problem.
source
There's a callback function in tinyMCE which is fired when the component is loaded and ready. you can use it like this :
tinyMCE.init({
...
setup : function(ed) {
ed.onInit.add(function(ed) {
console.log('Editor is loaded: ' + ed.id);
});
}
});
If you are using jquery.tinymce.js then you don't need tiny_mce.js because TinyMCE will try to load it with an ajax request. If you are finding that window.tinymce (or simply tinymce) is undefined then this means that the ajax is not yet complete (which might explain why using setTimeout worked for you). This is the typical order of events:
Load jquery.js with a script tag (or google load).
Load TinyMCE's jQuery plugin, jquery.tinymce.js, with a script tag.
Document ready event fires; this is where you call .tinymce(settings) on your textareas. E.g.
$('textarea').tinymce({ script_url: '/tiny_mce/tiny_mce.js' })
Load tiny_mce.js this step is done for you by TinyMCE's jQuery plugin, but it could happen after the document ready event fires.
Sometimes you might really need to access window.tinymce, here's the safest way to do it:
$(document).tinymce({
'script_url': '/tiny_mce/tiny_mce.js'
'setup': function() {
alert(tinymce);
}
});
TinyMCE will go so far as to create a tinymce.Editor object and execute the setup callback. None of the editor's events are triggered and the editor object created for the document is not added to tinymce.editors.
I also found that TinyMCE's ajax call was interfering with my .ajaxStop functions so I also used a setTimeout:
$(document).tinymce({
'script_url': '/tiny_mce/tiny_mce.js'
'setup': function() {
setTimeout(function () {
$(document).ajaxStart(function(e) {/* stuff /});
$(document).ajaxStop(function(e) {/ stuff */});
}, 0);
}
});