Cannot get declared variables in javascript - javascript

Consider a javascript file script.js which contains the code alert(theVar);
Now, i linked the js file to the document like
<script type="text/javascript">
var theVar= 'a alert';
</script>
<script type="text/javascript" src="script.js"></script> //Contains alert(theVar);
The variable theVar is used and i get a alert. This works fine.
When,
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript">
var theVar= 'a alert';
</script>
is used, i am not getting a alert.
I know the problem is because of the variable, which is declared after loading the js file.
But is there any way to get the variable declared anywhere in the document ?

in script.js do
window.onload = function() { alert ( theVar ) }
Or your favorite library dom ready fn, so it invokes the callback after a certain event instead of immediately.
Though, this really depends on what kind of functionality script.js has, which you have not specified thus far.

The important bit is that code gets executed in the appropriate order. You should delay the call to alert(theVar) until the document gets fully loaded. For instance, you can attach an onload event handler to the window object.
It's also worth noting that calling external *.js files does not affect the way code gets run.

The simple solution:
Move the script.js inclusion to the last row of the body. That way a variable declared at any point in the document can be used.
The technical solution:
Inside script.js, hook on to the window.onload event before doing any evaluating. The result is the same as with the simpler solution, but allows you to keep you script tags in the head (or anywhere for that matter).

Related

Access HTML element later in document through JavaScript

I am just starting out with JavaScript and I have a simple code that sends a value to an element with id p. I am currently declaring this function in a <script> in the <head> element of my document.
function writeP(resultSet) {
document.getElementById('p').innerHTML = resultSet.length;
};
writeP(results);
When I have this listed within the <head> element and run the webpage, firebug throws this error at me: TypeError: document.getElementById(...) is null.
However, if I move the code block into a <script> tag beneath the element and then reload the webpage, no problems and the script works as it should. Is there any reason for this, and a way I could make this work so I wouldn't have to define my functions beneath the element or include a onload on my body element?
Thanks for your help
Reason is that by the time your launch js code, DOM is not yet prepared, and JS can't find such element in DOM.
You can use window.onload (docs on W3schools) trigger to fire your functions after all elements are ready. It's same as having onload property on body element, but is more clear, as you can define it in your js code, not in html.
JS evaluates syncronically. Therefore, it does matter WHEN you declare the function. In this case, you're declaring it before the element actually exists.
Second, when you declare a function with that syntax, it does get eval'd inmediately. If you declared, instead
var writeP=function(resultSet) {
document.getElementById('p').innerHTML = resultSet.length;
};
you could save just the call to the end of the Doc, and leave the declaration at the beggining.
However, I would advise you to read a few jQuery tutorials to learn easier ways to deal with dom manipulation. Nobody runs raw JS for that task anymore.
jQuery includes an useful call to document ready event, which will save you a lot of headaches and is -IMHO- more efficient than the onload event. In this case, you would include the jQuery library somewhere in your code
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
and then add
<script>
jQuery(document).ready(function() {
var writeP=function(resultSet) {
jQuery('#p').html(resultSet.length);
};
writeP(resultSet);
});
</script>
just about anywhere in your document or an external js file, as it suits you.

Variable on Phonegap application

I am developing a Phonegap application on every platform. Everything goes well except the declaring of variable. Here is my code:
<script type="text/javascript" src="phonegap.js"></script>
<script type="text/javascript">
var something = "Sth";
document.addEventListener('deviceready',startsth(),false);
function startsth(){document.write(something);}
....
</script>
When I try to check if there is internet, the application outputs "undefined". It works fine if I do not check the network. How can I fix the problem?
You are connecting the deviceready handler in a wrong way:
document.addEventListener('deviceready',startsth(),false);
^------ REMOVE THIS PARENS
when you connect to startsth() you are using the return value of the startsth function, instead of a pointer to the function itself, which is just startsth
Use this:
<script type="text/javascript" src="phonegap.js"></script>
<script type="text/javascript">
var something = "Sth";
document.addEventListener('deviceready',startsth,false);
function startsth(){document.write(something);}
....
</script>
You were calling the function startsth immediately with the parentheses afterwards, i.e. startsth(), rather than merely passing it as a function reference to be registered as a listener, to be called later upon the deviceready event.
UPDATE:
Other things to try:
Make sure you have the path for src="phonegap.js" correct.
Move the scripts to near the top of the document so that you don't miss any events.
Switch the order of the scripts in case the event is being fired very quickly and you're missing it.
Don't use document.write(...) - it overrides the page contents if called after the DOM has loaded, resulting a mostly blank page.

executing javascript function from HTML without event

I wish to call a javascript function from an HTML page and I do not want it dependent on any event. The function is in a separate .js file since I wish to use it from many web pages. I am also passing variables to it. I've tried this:
HTML:
<script type="text/javascript" src="fp_footer2.js">
footerFunction(1_basic_web_page_with_links, 1bwpwl.html);
</script>
The function in fp_footer2.js:
function footerFunction(path, file) {
document.write("<a href=" + path + "/" + file + " target='_blank'>Link to the original web page for this assignment.</a>");
return;
}
(I have also tried putting the fp_footer2.js file reference in the header, to no avail. I'm not sure if I can put it 'inline' like I did in this example. If not, please let me know.
PS: I know I can do this with a simple 'a href=""' in the HTML itself. I wanted to see if this could work, for my own curiosity.
If a <script> has a src, then the external script replaces the inline script.
You need to use two script elements.
The strings you pass to the function also need to be actual strings and not undefined variables (or properties of undefined variables). String literals must be quoted.
<script src="fp_footer2.js"></script>
<script>
footerFunction("1_basic_web_page_with_links", "1bwpwl.html");
</script>
JavaScript will run while your page is being rendered. A common mistake is to execute a script that tries to access an element further down the page. This fails because the element isn't there when the script runs.
So includes in the <head> will run before any DOM content is available.
If your scripts are dependent on the existence of DOM elements (like a footer!) try to put the script includes after the DOM element. A better solution is to use the document ready event ($(document).ready() in jQuery). Or window.onload.
The difference between documen ready and window onload is that document ready will fire when the DOM has been rendered; so all initial DOM elements will be available. Where as window onload fires after all resources have loaded, like images. window onload is useful if you're doing things with those images. Usually document ready is the right one.
Maybe I misunderstand your question, but you should be able to do something like this:
<script type="text/javascript" src="fp_footer2.js"></script>
<script type="text/javascript">
footerFunction(1_basic_web_page_with_links, 1bwpwl.html);
</script>
Have you tried calling it from a document.ready?
<script type="text/javascript">
$(document).ready(function() {
footerFunction(1_basic_web_page_with_links, 1bwpwl.html);
});
</script>

How to add Javascript code using jQuery and setTimeout()

I have some tracking code that the provider (WebTraxs) says should be placed at the bottom of the tag. The problem is that this same code is causing everything on the page (including my jQuery code) to run AFTER the WebTraxs is executed. This execution sometimes takes long enough where images rollovers, etc aren't working because the user is mousing over images before WebTraxs has finished.
Therefore, I'm trying to add the needed tags (from WebTraxs) to the body after the page is loading in the document ready handler, using the following:
setTimeout(function(){
var daScript = '<script language="JavaScript" type="text/javascript" src="/Scripts/webtraxs.js" />';
var daOtherScript = '<noscript><img alt="" src="http://db2.webtraxs.com/webtraxs.php?id=company&st=img" />';
$('body').append(daScript);
$('body').append(daOtherScript);
},
5000);
I have two problems with the above:
In Firefox, after 5 seconds, it page goes completely blank.
In IE, there's no errors thrown, but normally you can see the WebTraxs code trying to load a tracking image in the status bar. This is not occurring with the above code.
Is there a better way to accomplish my objective here? I'm basically just trying to make sure the WebTraxs code is executed AFTER the document ready handler is executed.
Why don't you use the .getScript function:
setTimeout(function(){
$.getScript("http://path.to/Scripts/webtraxs.js");
},
5000);
What it's really curious about your code is that you add a <noscript> tag using JavaScript... it does not make any sense. If the user does not have JavaScript the setTimeout won't be fired, thus it <noscript> content won't be displayed.
I'm basically just trying to make sure the WebTraxs code is executed AFTER the document ready handler is executed.
In that case, you just have to do this:
$(document).ready(function(){
$.getScript("http://path.to/Scripts/webtraxs.js");
});
You don't have to use jQuery's DOMReady event handler. The reason people use DOMReady is that it allows the full DOM to load before firing up scripts that manipulate the page. If you call your scripts too early, parts of your page may not be accessible -- for example, if you call them before <div id="footer">...</div>, they won't be able to see $('div#footer') because it's not been pulled into the DOM yet. And that's great, except that your DOMReady methods will always execute after any in-page scripts have executed first. That's why your webtrax code is getting executed first.
But you can get the same benefits of DOMReady and still control the order of execution by calling your page scripts at the end of your document, when there's nothing left but HTML closing tags. They will be executed in the order they appear.
So try this instead:
<html>
<head>
<script type="text/javascript" src="myPageScripts.js"></script>
</head>
<body>
<div id="pagesection1"></div>
<div id="pagesection2"></div>
<div id="pagesection3"></div>
<!--NO MORE CONTENT BELOW THIS LINE-->
<script type="text/javascript">//<![CDATA[
runMyPageInitializerScripts();
//]]></script>
<script language="JavaScript" type="text/javascript" src="/Scripts/webtraxs.js" ></script>
</body>
</html>
In this script, runMyPageInitializerScripts() would still have complete access to #pagesection1, pagesection2 and pagesection3, but would not see the final script tag. So the page isn't in exactly the same condition as when DOMReady is fired, but for most scripts usually there is no downside.
<script> tags cannot use a shortcut like <script/>.
You have to use <script></script>
Anyways, I don't understand where the difference is on executing those scripts on DOMready or after a specific amount of time. If it blocks the UI it will do the same after 5 seconds no?
You are missing the closing </script> and </noscript> tags.
If you want to keep the <script> tag you may need to escape it (not sure if this persists on newest browsers, but as far as i remember you can't have <script> tags inside a script tag), take old google analytics code as example:
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
Splitting the script tag also works:
document.write("<scr"+"ipt src='somescript.js'></sc"+"ript>");
But since you're using jQuery, .getScript() is your best option.

Best way to signal my JS script is loaded

I have a JS script that will be hosted on my server and that others will embed in their html, i.e.
...<code for http://yoursite.example.com />
<script type="text/javascript" src="http://mysite.example.com/awesome.js" />
...<code for http://yoursite.example.com />
My script declares an object with a bunch of properties accessible for use as a Javascript Object(), i.e.
<script type="text/javascript">
//From http://mysite.example.com/awesome.js
alert(Awesome.Name);
</script>
Due to the load time variance, it seems I need to signal that the "Awesome" object in my script is ready. I need this to stand on its own, so no dependencies on specific JS frameworks.
Do I need to publish my own custom JS event, or does the simple fact that my script is loaded get captured by one of the existing page-level events? How else should I be doing this?
UPDATE: as a point of reference, if I include the JS in an HTML page running from http://mysite.example.com, the Awesome object is available and populated. When the JS file is included from another domain, the object is undefined at runtime.
The javascript content of <script> tags is executed procedurally, so this
<script type="text/javascript" src="http://mysite.com/awesome.js" />
<script type="text/javascript">
alert(Awesome.Name);
</script>
will only alert the contents of Awesome.Name if found in any previous script tag.
To understand if everything has been fully loaded on the page, you have to use the DOMContentLoaded, for firefox, and "onreadystatechange" for ie. Also you can simply check the load event on the window object if you don't care about checking the DOM (could be easier).
if ( document.addEventListener ) {
document.addEventListener( "DOMContentLoaded", function(){
doSomething();
}, false );
} else if ( document.attachEvent ) { // IE
document.attachEvent("onreadystatechange", function(){
if ( document.readyState === "complete" ) {
doSomething();
}
});
}
If your script needs the DOM to be loaded before your object is instantiated, you should look at some frameworks and see how they handle this, then implement it in your code. If you don't need the DOM to be loaded, then I would let the user worry about the timing of using your object based on when it is loaded. Generally, your object should be available to be be used as soon as your script has been loaded, which means that the object ought to be available right after the script tag that includes it.
Anything accessible in the global scope can be accessed through the window scope. Hence, you could use this:
if (window["Awesome"] != null) { /* do something */ }
A). You realise that script requests are blocking? Are you ok with this or do you want to work around that, because the answer to your question depends on it.
B). Bare bones bulletproof and simple mechanism is to call a specified method which you can guarantee exists on the page. Let that methods implementation be up to the user to do what it will. Lots of other ways exist but we'd need to know what exactly the lifecycle and intent of your code is to recommend anything.
you can simply use it like this:
<script type="text/javascript" src="myfunction.js"></script>
<script type="text/javascript" src="iwannaloadthis.js?onload=executeThis"></script>
remember as pointed out earlier, execute this must be defined in myfunction.js (or before trying to load iwannaloadthis.js.
Hope this helps!!

Categories

Resources