javascript function not accessible from external file - javascript

This might be a stupid beginner's problem, but it's driving me mad. Simplified, the code is:
I have an index.php where in an inline script (located in the head element), some JS functions are defined.
<script type="text/javascript">
$(function(){
// other code
var popup = function(message,color){
$(".title").css({"color": "beige" });
$(".popup_alert").css({"background-color": color});
$( ".popup_alert" ).append(message);
$(".popup_alert").removeClass("offscreen").delay(800).queue(function(){
$(this).addClass("offscreen").dequeue();
$(this).empty();
$(".title").css({"color": "#444" });
});
};
};
</script>
At the very bottom of the <body>, I'm loading an external JS file where some JQuery happens:
<script src="ajaxToDB.js" type="text/javascript"></script>
JQuery is not the problem. It's loaded and the other functions inside this external file are working.
Inside this linked file, I can't call the function defined in the index.php.
popup("test",orange);
Will yield a console error "Uncaught ReferenceError: popup is not defined"
Is this normal? I already wrapped all the stuff in ajaxToDB.js inside a
$(function() { ... }); I read that this would force the page to load first, but to no avail...
What's the stupid detail I overlooked?!

Thanks to #guest271314, I learned a lesson in JS structure:
Previously, I had wrapped the entire code within the main document's script tag inside a $(function(){}; This I thought, was "necessary" as the script tag was placed inside the head element, and the document otherwise wouldn't have been ready.
When using another, external JS file however, this technique now prevented the external code from referring to functions declared inline, as these now "waited" for the rest of the document to be ready, including the external file (which then referred to a yet undeclared / "pending" main function).
Wow.
Removing the $(function(){}; wrap and moving the script element to the bottom of the body resolved the issue. I guess that's where it should've been in the first place... level up

Related

Alternative to hide/show content with JS?

is there a better way to replace this kind of js function by simply collapse/toggle a div and show/hide its content?
$(function() {
$('#destselect').change(function(){
$('.dest').hide();
$('#' + $(this).val()).show();
});
});
The reason this is happening is because your js file is called on the head of your page.
Because of this, when you document.getElementsByClassName('collapsible');, colls result in an empty array, as your elements in body are not yet created.
You could either create a separate js file and add it at the end of your body (in that way you make sure your colls are created when your javascript is executed), or just wrap your code on a DOMContentLoaded event listener that will trigger your code once the document has completely loaded.
My guess would be that you are loading your script before browser finishes loading dom conetent and so when it runs the elements it is trying to add event listeners to, don't yet exist.
Try wrapping all you javascript in that file in this:
document.addEventListener("DOMContentLoaded", function(event) {
// all your code goes here
});
The above makes sure that your script is run after loading all elements on the page.
You could add a script tag to the header of your HTML file, this will import the JS file into your current page as follows
<script src="File1.js" type="text/javascript"></script>
Then call the function either in onclick in a button or in another script (usually at the bottom) of your page. Something like this:
<body>
...
<script type="text/javascript">
functionFromFile1()
</script>
</body>
Seems like your script is not executing properly due to a missing variable.
In this script https://www.argentina-fly.com/js/scripts.js
Naves variable in function UpdateDetailsDestination() is not defined.
I think you should resolve this first and then check your further code is working on not.
Please take a look into Console when running page. You'll see all JavaScript related errors there.

Jquery loaded before the jquery-dependent script, but the latter still says "$ is not defined"

On my HTML page, I have the following way of loading JS files:
<script id="jjquery"></script>
<script id="jscookie"></script>
<script id="winx"></script>
<script>
(function(){
if(screen.width > 479)
document.querySelector("#jjquery").setAttribute("src", "/js/jquery-3.3.1.min.js");
document.querySelector("#jscookie").setAttribute("src", "/js/jscookie.js");
document.querySelector("#winx").setAttribute("src", "/js/winx.js");
}());
</script>
Basically I used the way described in this answer to only load certain scripts starting from the specific screen resolution. But the third script out of three, that relies on jquery, is not working and says $ is not defined. Even though if I enter $ in the console, it returns normal response. And when I see the order of the scripts in the HTML output, it is clear that jquery is loaded prior to two other scripts. What could be the issue here?
P.S. everything works comlpetely fine if I just load the scripts normally without the resolution check.
The problem is that the scripts are loaded asynchronously, so the order of your code isn't relevant.
You can see a MDN example of how you can properly import your scripts.
In your case, if some of your scripts depend on jquery, you can create an onLoadJquery function and append it as the onload attribute of the script, this function will be executed after the import.
<script>
(function(){
if(screen.width > 479) {
// add the callback that will be executed once jquery is loaded
document.querySelector("#jjquery").addEventListener("load", onLoadJquery);
document.querySelector("#jjquery").setAttribute("src", "/js/jquery-3.3.1.min.js");
document.querySelector("#jscookie").setAttribute("src", "/js/jscookie.js");
}
function onLoadJquery() {
// safely import the rest of the scripts
document.querySelector("#winx").setAttribute("src", "/js/winx.js");
}
}());
</script>

How to change the CSS of an HTML element with the output of a Javascript function? [duplicate]

In using CodePen, the JavaScript code in the JavaScript pane seems to execute just before the </body>. In my case I have some <script> tags embedded in my HTML where I refer to functions defined in the JavaScript pane. Since the JS pane is not evaluated until just before the </body>, I cannot refer to these JS functions in the <script> element.
Is there a way to tell CodePen to effectively, "put the contents of the JavaScript pane in the <head> rather than just before </body>"?
I originally wanted to be able to specify where the JS pane's content is included: In the <head> element or just prior to closing the </body>. By default, CodePen inserts your JS pane content just prior to the close of the </body> and there's nothing you can do about it for now (July, 2015).
There is something of a hack you can use to get around this though. Let's say your pen is at:
http://codepen.io/lanshen/pen/j7GB5q (I just made that up). Your JS pane has its own URL of:
http://codepen.io/lanshen/pen/j7GB5q.js
In the "Stuff for <head>" section in your pen's "Settings", add a tag that refers to your JS pane:
<script src="//codepen.io/lanshen/pen/j7GB5q.js"></script>
This will cause your JS pane's content to be included in the <head>. The obvious problem with this approach is that the JS pane's content will still be included just prior to the </body> (i.e., it will be included twice). To get around this problem, I structured my JS pane content into an if()/else() so that the if() piece will be loaded in <head> and the else piece will be loaded just prior to </body>. Below is the JS pane "template" I used. Again, make sure you reference the JS pane with a <script> tag in the HTML's "Stuff for <head>" section as I mentioned above.
var headLoad;
if(!headLoad) { // when loaded in HEAD, headLoad will be falsey
headLoad = {}; // when loaded before </body>, headLoad will be truthy
(function() {
// PUT YOUR JS TO BE EXECUTED IN HEAD HERE...
alert("I am executing in the HEAD!");
headLoad.doSomething = function(mssg) {
// ...
alert(mssg);
};
})();
} else { // this code is not executed until just prior to </body>
// PUT YOUR JS TO BE EXECUTED PRIOR TO </body> HERE...
alert("The BODY is about to close....");
doSomething = function(mssg) {
alert(mssg);
};
doSomething("789");
}
Here's a little HTML pane to test it out:
<p>ABC</p>
<script>
alert("I am in the HTML script tag.");
headLoad.doSomething("123"); // should alert
// The following will NOT execute because the "else" clause of the
// "if(!headLoad)" will not be executed until just prior to the </body>.
// the global doSomething() function is currently undefined.
doSomething("456"); // will NOT work, nor should it.
</script>
<p>XYZ</p>

Function is not found in Jquery, but is found in Javascript

I have an html document in which a function is called like this
<div id="mon" class="topbar" onclick="verd()">
This calls a jquery function inside the body tag that goes like this
<script src="jquery.js">
function verd(){
$("#stillmain").empty();
} </script>
This returns the error:
Uncaught ReferenceError: verd is not defined
at HTMLDivElement.onclick
When I change the script to pure Javascript without Jquery however like this
<script>
function verd(){
$("#stillmain").empty();
} </script>
it does recognize the function verd(), can anyone explain what is going on, and how I could still use Jquery?
I am using the newest version of Jquery(just changed the name, nothing else).
When you give a script tag a src attribute it's going to load that source file in place of the script contents. So any script tags with a src should be kept empty.
You need to load jQuery by calling a script tag with its source on it, and then in a separate tag you can make your own script tag and write your custom JavaScript there.
<script src="jquery.js"></script>
<script>
function verd(){
$("#stillmain").empty();
}
</script>
Make sure that your custom scripts are loaded after jQuery.
If you want to run this as a jQuery function you need to use the proper syntax. Try the link below.
How to Create a jQuery Function
Also, you need to load jQuery in a separate tag or else none of your code will be ran other than the source of that script!

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.

Categories

Resources