I'm having an 'end of day brain fart' & cannot get this simple piece of code to work. All I want to do is reuse a function in another script I am using.
For example, in javascript A I have:
function rollLink(){
//code that does something amazing
};
rollLink();
In another JS file (let's call it B), I am trying to reuse the rollLink function as part of a simple AJAX call:
$.ajax({
url: bla,
data: bla,
success:function(data) {
$('#hero').append( data );
rollLink();
}
});
But I get an error saying rollLink() is not defined. Please can someone point out the error in my ways?
EDIT:
Ah sorry for the insufficient information. I shall elaborate:
Script A is my main JS file. It runs on every page of my WP theme & is enqueued via the functions.php file.
Script B is located within a WP plugin I am building.
Here is an example of the footer that is output:
<script type='text/javascript' src='http://localhost/wordpress/wp-content/themes/mytheme/javascripts/script_a.js'></script>
<script type='text/javascript' src='http://localhost/wordpress/wp-content/plugins/myplugin/script_b.js'></script>
</body>
</html>
If the page a size is much greater than page b, it will take longer to download and execute. Worse, if you place your function at the button of the file, then page b will be ready, run and execute before even page a finishes loading.
Just in case, try to validate if rollLink(); is a function before calling it.
if(typeof rollLink === "function")
{
//true;
}
else{
//false;
}
if true, mean the function is ready, otherwise, it doesn't exist (yet).
Easy fix is to call your ajax function from the end of script where you make sure all required files are loaded.
A non efficient solution will be is to have recursive call to ajax function waiting for rollLink to load.
if(typeof rollLink === "function")
{
//do ur work
}
else{
//call again after one sec;
setTimeout(function (){callSelfAjaxFunction();} , 1000);//every one sec
}
So if you like that approach, you might want to pass a counter as a parameter increasing on each call and terminates when a exceeded so you won't have the function calling it self forever of the server is not available.
if(counter < 10 ){
setTimeout(function (){
callSelfAjaxFunction(counter++);
} , 1000);//every one sec
}
Perhaps try wrapping script_b.js in a $(document).ready, like so:
$(document).ready(function(){
$.ajax({
url: bla,
data: bla,
success:function(data) {
$('#hero').append( data );
rollLink();
}
});
}
This may be because the file that uses the function is loaded before the file that is defining that function. I had gone through the same problem when i was trying to load Image file and showing it on canvas the reason is that the file that is to be used is too large that it take much time for loading and the other file load before that file hence it says that the variable are not defined.
Solution:
What you can do is to make a Boolean variable funcionReady and initialize it as false and turn it value true inside the function's definition and before using that function check for the variable whether it is true or not if true then execute else wait.
you should load both files on your page and file where you defined rollLink must be loaded before your ajax call. that's all in basic case.
Related
I'm trying to convert the pieces of php code on my website that access an sql database to ajax, so I don't have to refresh the page, and am having some problems getting things to work.
I've written an ajax jquery function (getLatestData()) that sets the values of html elements to the ones returned from the request to the php page. This function is stand alone (i.e. isn't triggered by an action on an element, it is just a function on its own) and works completely fine, retrieving the data from the database and correctly putting it in the fields.
However, I am unable to call the function manually. This is supposed to happen every minute (using javascript's setInterval() and a check to see if the current second is 2), so new data is loaded in every minute (the second setInterval() section in my code). This also works fine, as I have tried alerting from it. But, if I swap that statement with a call to my ajax function, nothing happens. Why is this? How do you call an ajax jquery function?
Also, my ajax function keeps getting called whenever the page loads (this is the only reason I know the function works), despite there being absolutely no other calls to it other than the one I am trying to get working (and it still happens even when this call is removed). Is this a function of ajax itself or is there something wrong with my code? How can I stop this happening?
Code:
<html>
<head>
<title>Remote Latest Data Warwick</title>
<link rel="icon" type="image/jpeg" href="favicon.jpg">
<link rel="stylesheet" type="text/css" href="styles/defaultstyles.css">
<link rel="stylesheet" type="text/css" href="styles/globalstyles.css">
<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>
<script src="scripts/globalscripts.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(function getLatestData() {
alert("success1");
$.ajax({
type: "get",
url: "retrieve/getlatestreport.php",
dataType: "json",
success: function(response) {
alert(response[1]);
document.getElementById("fAmbientTemperature_DryThermometer").innerHTML = response[0];
document.getElementById("fAmbientTemperature_ExposedThermometer").innerHTML = response[1];
document.getElementById("fSoilTemperature_10CentimetresDown").innerHTML = response[2];
}
});
});
});
</script>
<script type="text/javascript">
function onLoad() {
updateCurrentSystemTime();
// Update number of seconds to data refresh
setInterval(function() {
seconds = 60 - new Date().getSeconds() + 3;
if (seconds > 59) {
seconds = seconds - 60;
}
document.getElementById(
"timeToUpdate").innerHTML = seconds;
}, 100);
// Refresh page on third second of minute
setInterval(function() {
current = new Date();
if (current.getSeconds() == "2") {
//location.reload();
//alert("t3");
getLatestData();
}
}, 1000);
}
</script>
</head>
...
Your first snippet of code runs on page load, and causes an AJAX request. You have $(document).ready(function() { ... });, which means: wait until the HTML has loaded, then call the function. Then you have $(function getLatestData() { ... });, which means: wait until the HTML has loaded, then call getLatestData. So overall, this means wait until it's loaded, then check to make sure it's loaded, then call getLatestData. This is why it does the AJAX request on page load.
(Needless to say, you don't have to do the waiting for HTML part twice. In fact, I don't think it's necessary at all for an inline script - it's only for when the script is in its own file, like globalscripts.js, when there's a danger that it could load and try to run the script before the page has loaded.)
As for why the AJAX call doesn't happen when you try to trigger it, you haven't said where/whether you're setting the handler. For instance, you could have <button id="reload-button">Reload</button> and $('#reload-button').click(onLoad);.
If you're already doing something like this, or if you add these two lines, you should see an error message in the console saying that it can't call getLatestData because it's undefined. If you don't know what I mean by the "scope" of a variable, look it up. getLatestData is declared and defined in the scope of the anonymous function in the $(document).ready call. Therefore, it can only be used inside that function. I've already pointed out that you can get rid of the document.ready part. If you do that, then getLatestData will be declared and defined in the global scope, and the AJAX call should work.
In summary, you should replace your first inline script with function getLatestData() { ... }.
I'm building a dynamic website that loads all pages inside a "body" div via jquery's load(). The problem is I have a script looped with setInterval inside the loaded PHP page, the reason being I want the script loaded only when that page is displayed. Now I discovered that the scripts keep running even after "leaving" the page (loading something else inside the div without refresh) and if I keep leaving / returning the loops stack up flooding my server with GET requests (from the javascript).
What's a good way to unload all JS once you leave the page? I could do a simple dummy var to not load scripts twice, but I would like to stop the loop after leaving the page because it's causing useless traffic and spouting console errors as elements it's supposed to fill are no longer there.
Sorry if this has already been asked, but it's pretty hard to come up with keywords for this.
1) why don't you try with clearInterval?
2) if you have a general (main) function a( ) { ... } doing something you can just override it with function a() { }; doing nothing
3) if you null the references to something it will be garbage collected
no code provided, so no more I can do to help you
This really sounds like you need to reevaluate your design. Either you need to drop ajax, or you need to not have collisions in you method names.
You can review this link: http://www.javascriptkit.com/javatutors/loadjavascriptcss2.shtml
Which gives information on how to remove the javascript from the DOM. However, modern browsers will leave the code in memory on the browser.
Since you are not dealing with real page loads/unloads I would build a system that simulates an unload event.
var myUnload = (function () {
var queue = [],
myUnload = function () {
queue.forEach(function (unloadFunc) {
undloadFunc();
});
queue = [];
};
myUnload.add = function (unloadFunc) {
queue.push(unloadFunc);
};
return myUnload;
}());
The code that loads the new pages should just run myUnload() before it loads the new page in.
function loadPage(url) {
myUnload();
$('#page').load(url);
}
Any code that is loaded by a page can call myUnload.add() to register a cleanup function that should be run when a new page is loaded.
// some .js file that is loaded by a page
(function () {
var doSomething = function () {
// do something here
},
timer = setInterval(doSomething, 1000);
// register our cleanup callback with unload event system
myUnload.add(function () {
// since all of this code is isolated in an IIFE,
// clearing the timer will remove the last reference to
// doSomething and it will automatically be GCed
// This callback, the timer var and the enclosing IIFE
// will be GCed too when myUnload sets queue back to an empty array.
clearInterval(timer);
});
}());
I want to start out by saying I have found other similar question, but I don't understand how to execute with with my code as it isn't a function I created myself.
I have the following code:
$("#dataset").load('/hemaexplorerbeta/php/getDataset.php');
This loads some data and puts in in a dropdown.
Afterwards I'm calling the following to see if it's loaded when I need the list:
document.getElementById('dataset').value
Bot of these are in my document on load, and I need them to be. How can I make sure to get a value from "#dataset" AFTER the data has been downloaded? Yes, the data is fetched from a MySQL database.
You could pass function as second parameter.
Example:
$("#dataset").load('/hemaexplorerbeta/php/getDataset.php', function() {
var x = document.getElementById('dataset').value;
});
Use the callback function for .load:
$("#dataset").load('/hemaexplorerbeta/php/getDataset.php', function() {
// This gets executed when the content is loaded
$(this).show();
});
I understand that JS is single threaded and synchronously executed. Therefore when i add a file to my browser head tag that file is executed as soon as its encountered. Then it goes to the next script tag & executes that file. My question is when I add a js file dynamically to an HTML head tag. How does the browser executes that file?
Is it like that the file is executed as soon as the file is loaded wherever the current execution is. Or is it that we can control how that file is executed?
When the script is loaded, it will be executed as soon as possible. That is, if some other javascript function is executing, like a clickhandler or whatever, that will be allowed to finish first - but this is a given because, as you say, in browsers JavaScript normally execute in a single thread.
You can't control that part of the script loading, but you could use this pattern - heavily inspired by JSONP:
inserted script:
(function () {
var module = {
init: function () {
/* ... */
}
}
ready(module); // hook into "parent script"
}());
script on main page:
function ready(o) {
// call init in loaded whenever you are ready for it...
setTimeout(function () { o.init(); }, 1000);
}
The key here is the ready function that is defined on your page, and called from the script you insert dynmaically. Instead of immediately starting to act, the script will only tell the parent page that it is loaded, and the parent page can then call back to the inserted scripts init function whenever it wants execution to start.
What happens when a JavaScript file is dynamically loaded ( very simplified, no checks ):
the file is loaded;
if there is function call e.g. doSomething() or (function(){...})(), the code is executed(of course you must have the definitions);
if there are only function definitions, nothing is happening until the function call.
See this example: 3 files are loaded, 2 are executed immediately, 1 is waiting the timeout.
Edit:
The script tag can be placed anywhere in the page. Actually it is better to be placed at the end of the page if the onload event is not used (yahoo speed tips).
With HTML5 JavaScript has web workers MDN MSDN wikipedia.
Considering a way to do this is
var js=document.createElement('script')
js.setAttribute("type","text/javascript")
js.setAttribute("src", filename)
document.getElementsByTagName("head")[0].appendChild(js);
// ^ However this technique has been pointed to be not so trusworthy (Read the link in the comment by Pomeh)
But answering your question
How does the browser executes that file?
As soon as the script is added to the DOM
Is it like that the file is executed as soon as the file is loaded wherever the current execution is?
Yes
Or is it that we can control how that file is executed?
Its better if you attach an onload event handler, rather than a nasty tricks.
Here is some code you can try to get an answer to your question.
<script>
var s = document.createElement('script'), f = 1;
s.src="http://code.jquery.com/jquery-1.7.2.js";
document.head.appendChild(s)
s.onload = function(){
console.log(2);
f = 0
}
while(f){
console.log(1);
}
</script>
This code should ideally print a 2 when the script loads, but if you notice, that never happens
Note: This WILL kill you browser!
I have following js code:
clientData.reloadTable( "CreateCSV", "/create/file" );
$("#downloadFrame").attr("src","/download/download");
In above code. first statement is creating an csv file on disk. And 2nd statement is downloading it(Using iframe to download file because of error when using AJAX request ). It is downloading file but with previous content. It means that it prompts me to download file before it finish updating that file.
How can I force my 2nd statement to not execute before 1st statement finished its work??
Thanks
The best way to do something like this in Javascript is to use callback functions.
If it is possible to change the reloadTable function such that >
var callback = function () { $("#downloadFrame").attr("src", "/download/download") }
clientData.reloadTable("CreateCSV", "create/file", callback);
and then inside the reloadTable function, call the callback function once everything is done.
This is the true beauty of Javascript.
Otherwise you can also use setTimeout() if you have an idea how much time the reloadTable takes.
e.g. if it is to take 1 second. to complete, you can >
clientData.reloadTable( "CreateCSV", "create/file" );
var func = function () { $("#downloadFrame").attr("src","/download/download");}
setTimeout(func, 1000);
It doesn't sound very robust. But anyway:
function start() {
doFirstThing();
setTimeout('doSecondThing();', 1000); // execute the secondthing in 1000 ms
}
function doSecondThing() {
...
}
clientData.reloadTable( "CreateCSV", "/create/file" );
if it's an ajax call. call your download function from it's callback.