So, I have three js files. All three files are attached to html page without defer:
1)jquery
2)file with the following content
ugu={
temp:function(s){
alert(s);
}
};
3)file with the following content
$.ajax(....) //line1
ugu.temp("hello");//line2
So we see, that third file uses objects from 1 and 2. It doesn't have problems with line1. However line2 has errors if I attach 3 js script to html page without "defer", otherwise it throws error that the browser can't find variable ugu.
The question - how can I make work file 3 without "defer"?
What is the order of including your files? In HTML file you should first include jQuery, then file with ugu definition, and the third one at last.
If you are trying to declare ugu in the global namespace you should use var.
var ugu={
temp:function(s){
alert(s);
}
};
File 2 will have to be loaded before file 3 will run. You might consider looking into require.js it is handy for this.
Related
I am compressing a js file like this:
mix.scripts('resources/assets/js/pages/login.js', 'public/js/login.js');
My pre-compressed file contains this function:
function zoomInForm() {
$('#login-page').toggleClass('zoom animated');
........ ........
}
But in my compressed file the function zoomInForm is renamed so I can never call the zoomInForm(); function on my page.
How can I just compress a js file to one line without removing functions?
If the minifier renames the function, it also renames every place that you call it within the JS files.
Generally, you should NEVER have JavaScript outside of your JS files. Not in a script tag, not in an onclick attribute.
If you want to fx. listen to button click, you should create the listener in the JS:
$('#login-page').click(function(){
zoomInForm();
);
While cssBlaster21895 provides you with a real solution to your specific problem, I believe a more correct solution would be to move your JavaScript logic to your JS files.
You can prevent function from being renamed. You can pass uglify options into mix options.
mix.options({
uglify: {
"mangle": {
"except": ["zoomInForm"]
}
}
});
Maybe it can help,but maybe there something wrong with your whole script at all, even double declaring same function, just a guess...
Or try declaring a function the other way:
var zoomInForm = function(){...}
Then call it when you need with zoomInForm() later in the script and see whats happening.
I have an HTML page with multiple attached js files that include functions that are used on that page.
For functions that are included on the base HTML page they are successfully re-assigned. FunctionA = FunctionB.
The problem comes when I try to reassign a function that is part of one of the attached js files. The normal reassignment doesn't work. Say FunctionC is on attached js file more functions.js .
I try FunctionC = FunctionD. FunctionC runs as it would normally - WITHOUT the reassignment to FunctionD. I know the reassignment to FunctionD 'should' occur before the FunctionC runs because it fires when I check with console.log.
Any ideas as to why this isn't working would be appreciated.
You have to make your reassignments after included file.
For example (Disclamer: don't do this in real projects - this is for demo purposes only) the code below includes jQuery library, but then overwrites jQuery function with a custom one:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
jQuery = function(s) {
alert(s);
}
</script>
<script>
jQuery('aaa');
</script>
when this runs it produces alert (demo), but if you reverse the order of first two script tags - original "attached" jQuery function will take over.
I have two functions of the same name; let's say foo().
One in the HTML file and one in the JS file, which is included in the HTML file. The problem is I want to give preference to the JS file function rather than the HTML file function.
Is there any way to do that, or is there any syntax in JavaScript like [JSFileName].foo(), that may perhaps call the function in the JS file?
Not sure why you want to have two identically-named functions.
The snarky answer is: Just remove the reference to the function you don't want. (If you have control over your html, such a situation shouldn't exist.)
The answer you're looking for: Place the external script tag after the inline script tag.
Make sure the script tag for the js file is after the HTML script tag in which foo is declared.
It's not clear from your question why you have two functions named foo, but based on your [JSFileName].foo() attempt at a solution, I might suggest using objects as namespaces. In your script you could do:
var myScriptFunctions = {
foo: function() {
// do foo stuff
}
}
You can call it with myScriptFunctions.foo() and you won't have two functions competing for the global name foo.
I've got a file notifications.js containing one event bound to an element, and a function updateNotification(). This function uses jQuery to update certain elements on the page when a JSON object is passed as a parameter.
The problem:
I'm attempting to call this function within the page (via <script> tags), however rather than calling it, it breaks the page. I did some digging around within the Chrome Developer Console (not sure of the name), and an error is flagged:
/pleaseshare/views/install/:50 Uncaught ReferenceError:updateNotification is not defined
However, when I pan within the console, I can clearly see the file notifications.js listed under scripts, and the function is defined there. If I define the function within the current scope (e.g. the line above the call), it works fine.
What I've tried
The function contains some javascript that requires jQuery, so I've attempted both with and without encasing it in $(document).ready( function() {});, with neither seeming to have any affect.
I'm pretty stumped.
For good measure, here's a link to show the structure of my javascript and html: http://snippi.com/s/znk6xe9
Any help in figuring out why this is happening, or explanations of why javascript functions cannot be called cross-file (although I'd hope this isn't the case), would be greatly appreciated ;)!!
A function cannot be called unless it was defined in the same file or one loaded before the attempt to call it.
A function cannot be called unless it is in the same or greater scope then the one trying to call it.
You code looks like the structure should work, but is clearly a reduced test case that has been reduced to the point where it won't.
Got it working. The issue was definitely multi-faceted, but I figured it out.
First off the use of RequireJS had an impact on updateNotification(), in that it couldn't be called cross-file, and was therefore considered undefined. I assume this because of how RequireJS loads files, and I'll look into the documentation later (and post an edit if I find anything relevant).
Secondly, updateNotification() would again be considered undefined when encased within jQuery's DOM ready loader $(document).ready(function(){}). However updateNotification() contains executions which require jQuery, so I had to encase the contents of the function in $(document).ready(function(){}).
This is an issue very unique to RequireJS/jQuery, hence why in most use cases this wouldn't occur.
Side note: The tags are edited to reflect this.
you need to import your script into your page:
<script type="text/javascript" language="javascript" src="path/to/notifications.js"></script>
This needs to be added above the <script> tag that calls updateNotification()
Functions do not need to be declared in the same file. In fact, avoiding having every declaration dumped into the global namespace is usually a concern in JavaScript.
In the sample code in the link you provided, updateNotification is declared as a global, so there should not be a scoping problem.
However, in the same sample, you don't show notifications.js being included. You need to import it using a <script></script> element and that element must come before the script element that includes the call to updateNotification. You also must include jQuery before notifications.js, since it uses jQuery. So you need something like:
<body>
// One or two elements
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="notifications.js"></script>
<script type="text/javascript">
$(document).ready( function() {
var json = {status : 'ok', message: 'Hello'};
updateNotification(json);
});
</script>
// All other elements
</body>
I am making use of constructors (classes) extensively and would like each constructor to be in a separate file (something like Java). Suppose I have constructors say Class1, Class2, ... Class10 and I only want to use Class1 and Class5 I need to use script tags to include Class1.js and Class2.js into the HTML page. Later if I also need to use Class3 and Class6 I again need to go to the HTML page and add script tags for them. Maintenance with this approach is too poor.
Is there something in JavaScript similar to include directive of C? If not, is there a way to emulate this behavior?
You can use jQuery.getScript:
http://api.jquery.com/jQuery.getScript
Or any of the many javascript loaders like YUI, JSLoader, etc. See comparison here:
https://spreadsheets.google.com/lv?key=tDdcrv9wNQRCNCRCflWxhYQ
You can use something like this:
jsimport = function(url) {
var _head = document.getElementsByTagName("head")[0];
var _script = document.createElement('script');
_script.type = 'text/javascript';
_script.src = url;
_head.appendChild(_script);
}
then use it in your code like:
jsimport("example.class.js");
Be careful to use this when the head is already in the DOM, else it won't work.
Yes: You can create script tags from JavaScript and load required classes on demand.
See here for a couple of solutions: http://ntt.cc/2008/02/10/4-ways-to-dynamically-load-external-javascriptwith-source.html
With careful use of id attributes or a global variable that contains "already loaded" scripts, it should be possible to develop a dependency resolution framework for JavaScript like Maven or OSGi for Java.
When we are talking about JavaScript, I feel it is better to include one file that includes everything you need instead of requesting a new file every time you need something that you don't currently have access to.
Each time you send out for another file, the browser will do many things. It checks if the requested file can in fact be found by sending an HTTPRequest, and if the browser has already seen this, is it cached and unchanged?
What you are wanting to do is not in the spirit of JavaScript. Doing what you are explaining will produce addition load times, and you wouldn't be able to do anything until the file has completely loaded, which creates wait times.
It would be better to use one file for this, include at the inner end of the </body tag (which won't cause the browser to wait until the script is done to load the page), then create one simple function that will execute when the page is completely loaded.
For example:
<html>
<head></head>
<body>
<!-- HTML code here... -->
<script src="javascript.js"></script>
<script>
(function r(f) {
/in/.test(document.readyState) ? setTimeout('r(' + f + ')', 9) : f()
})(function() {
// When the page has completey loaded
alert("DOM has loaded and is ready!");
});
</script>
</body>
</html>
you can include one js file into another js file by doing something like this in the begginig of your js file:
document.write("<script type='text/javascript' src='another.js'></script>");
The best approach in your situation is using of compiler of some kind. The greatest one is Google Closure Compiler. This is part of Google Closure Libraty which has structure similar to what you described.