Laravel compressing javascript using mix.scripts(); renames function in compressed file - javascript

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.

Related

Using Ruby Variables in JavaScript

I'm new to Ruby so I had a question in regards to using some variables throughout my codebase. I have a variable declared in my Ruby file as follows:
#pages = 350
Now, I know that in HAML, I can simply do:
-if #pages = 350, and in HAML with inline javascript, I can do something like:
:javascript
console.log("#{#pages}");
However, I am linking an external JavaScript file in my HAML document, and I was wondering if it would be possible to use my Ruby variables in my external JS document? I need some variables in order to build what I am trying to build. Thanks!
Update as per one of the answers:
In my HAML file, I have the following:
:javascript
printPages(3);
In my external JS file, I have:
$(function() {
window.printPages = function(pages) {
console.log(pages);
}
});
I you are loading static javascript files I really would not recommend trying to insert variables into that code.
Instead, think about how you would provide that to your javascript code.
You could send it to that code as an argument.
<script type="text/javascript" src="./my-external-script.js"></script>
:javascript
runMyExternalFunction(#{#pages})
Or you could add the variable as a data attribute on your page, and your javascript could look for that when it loads.
Haml:
%body data-pages=#pages
JS:
console.log(document.body.dataset.pages) // value of #pages
Update about your javascript:
Using jquery's on page ready event $() for declaring the function is a bad idea. That means that it waits for everything on the page to be compeletely loaded, and then declares the function your page needs.
What you should be doing is setting up all the function that will be needed right away, and then calling those functions when the page is loaded.
They way you have it, the page loads, printPages() is executed (which doesn't exist yet), and then after all that printPages is created and put into the global scope.
So remove the $() from your external script and add it to your HAML instead.
In fact, if your aren't doing anything super fancy with transpiling or bundling, then you can simply declare the function in your external JS file, and it will be available globally. This doesn't work with your code because they way you've declared the function, it would only be available to code within that $() callback.
// js file
function printPages(pages) {
console.log(pages);
}
HAML:
$(() => {
printPages({#pages})
})

Javascript Moodle

Hi I am fairly new to moodle. I have been trying to test if my Javascript runs but to no avail. Here is what I have:
In /videojs/amd/src I made a test.js file with a simple command
define(['jquery'], function() {
return {
init: function() {
// Put whatever you like here. $ is available
// to you as normal.
alert("It changed!!");
}
};
});
Then I grunt the file and everything succeed, and made minified. But when I go to the page it doesn't run. Now I read Moodle's Javascript Doc and I see it says
The idea here is that we will run the 'init' function from our (PHP) code to set things up. This is called from PHP like this...
Where do I call this PHP?
Somewhere in the page you are outputting, you need to add a call like this:
$PAGE->requires->js_call_amd('PLUGINTYPE_videojs/test', 'init);
It's not entirely clear from your example what sort of plugin you are creating, so whichever type you are creating (https://docs.moodle.org/dev/Plugin_types), you need to put it in the appropriate subdirectory for your site (e.g. /mod/videojs, /local/videojs, etc.), then add some sort of PHP script as the entry point for your plugin and call the js_call_amd function from there.

How does jQuery solve <script defer> issue?

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.

Give preference to JS file function over HTML file

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.

How can I combine my JavaScript files and still have my callbacks wait for a ready state?

I have lots of functions and event handlers that are split across multiple javascript files which are included on different pages throughout my site.
For performance reasons I want to combine all of those files into 1 file that is global across the site.
The problem is I will have event handlers called on elements that won't necessarily exist and same function names.
This is an example of a typical javascript file...
$(document).ready(function(){
$('#blah').keypress(function(e){
if (e.which == 13) {
checkMap();
return false;
}
});
});
function checkMap() {
// code
}
function loadMap() {
// code
}
I would need to seperate this code into an object that is called on that specific page.
My thoughts are I could re-write it like this:
(function($) {
$.homepage = {
checkMap: function(){
// code
},
loadMap: function(){
//code
}
};
})(jQuery);
And then on the page that requires it I could call $.homepage.checkMap() etc.
But then how would I declare event handlers like document.ready without containing it in it's own function?
First of all: Depending on how much code you have, you should consider, if serving all your code in one file is really a good idea. It's okay to save http-requests, but if you load a huge chunk of code, from which you use 5% on a single page, you might be better of by keeping those js files separated (especially in mobile environments!).
Remember, you can let the browser cache those files. Depending on how frequent your code changes, and how much of the source changes, you might want to separate your code into stable core-functionality and additional .js packages for special purposes. This way you might be better off traffic- and maintainance-wise.
Encapsulating your functions into different objects is a good idea to prevent unnecessary function-hoisting and global namespace pollution.
Finally you can prevent calling needless event handlers by either:
Introducing some kind of pagetype which helps you decide calling only the necessary functions.
or
checking for the existence of certain elements like this if( $("specialelement").length > 0 ){ callhandlers}
to speed up your JS, you could use the Google Closure Compiler. It minifies and optimizes your code.
I think that all you need is a namespace for you application. A namespace is a simple JSON object that could look like this:
var myApp = {
homepage : {
showHeader : function(){},
hideHeader : function(){},
animationDelay : 3400,
start : function(){} // the function that start the entire homepage logic
},
about : {
....
}
}
You can split it in more files:
MyApp will contain the myApp = { } object, maybe with some useful utilities like object.create or what have you.
Homepage.js will contain myApp.homepage = { ... } with all the methods of your homepage page.
The list goes on and on with the rest of the pages.
Think of it as packages. You don't need to use $ as the main object.
<script src="myapp.js"></script>
<script src="homepage.js"></script>
<-....->
<script>
myApp.homepage.start();
</script>
Would be the way I would use the homepage object.
When compressing with YUI, you should have:
<script src="scripts.min.js"></script>
<script>
myApp.homepage.start();
</script>
Just to make sure I've understood you correctly, you have one js file with all your code, but you want to still be in control of what is executed on a certain page?
If that is the case, then the Terrific JS framework could interest you. It allows you to apply javascript functionality to a module. A module is a component on your webpage, like the navigation, header, a currency converter. Terrific JS scans the dom and executes the js for the modules it finds so you don't have to worry about execution. Terrific JS requires OOCSS naming conventions to identify modules. It's no quick solution to your problem but it will help if you're willing to take the time. Here are some more links you may find useful:
Hello World Example:
http://jsfiddle.net/brunschgi/uzjSM/
Blogpost on using:
http://thomas.junghans.co.za/blog/2011/10/14/using-terrificjs-in-your-website/
I would use something like YUI compressor to merge all files into one min.js file that is minified. If you are looking for performance both merging and minifiying is the way to go. http://developer.yahoo.com/yui/compressor/
Example:
Javascript input files: jquery.js, ads.js support.js
run yui with jquery.js, ads.js, support.js output it into min.js
Javascript output files: min.js
then use min.js in your html code.

Categories

Resources