Conflicting global variable names in external javascript - javascript

There are a lot of questions and answers about conflicting variables names on Stackoverflow, but they all seem to be about scoping in your own code.
<script src="https://external_one/some_script.js"></script>
<script src="https://external_two/another_script.js"></script>
I'm loading two external, 3rd party JS scripts and need to run them on the same webpage. Separately they work fine, but when I try to import both at the same time, I run into a problem: both scripts have been written in such a way that they use a global _ variable. This means only the script that was imported last will work, as it overwrites the existing _ variable from the first script.
Using a global variable like this is bad practice and using a generic variable name like _ makes it even worse, but as these scripts are rather complex I can't just write my own version and I'm stuck using the scripts from these two providers. They don't seem to provide something like the 'no conflict' option libraries like JQuery provide (to prevent breaking other script that use the $ variable).
So what I'm was trying to figure out, is if it's somehow possible to encapsulate those scripts on import and prevent them from using the same variable. The only option I could think of was to use ajax to load the script, maybe make some changes and then run it using eval but this sounds like a huge problem waiting to happen.
Any suggestions on how to solve this problem?

Related

Calling functions from other scripts within Google Earth Engine

This is my first project using javascript. I am developing a set of scripts in order to acquire multiple types of data in the same area scope in google earth engine. In doing this, I could make large script to do this but would rather call functions from other scripts. I have tried multiple solutions to do this, though they were a while ago and I, unfortunately, have lost them to time. One of the primary issues that I have run into is most of the javascript help I have seen is for use in web pages not backend development.
Any questions about this are welcome and would like to learn how to make better questions if you have constructive criticism?
This is possible using the require function. In short, write a code file with anything you wish to export named as an "exports" variable, e.g.
exports.scale = 30;
Then save it and remember where it is.
Load it in another script using require, like this:
var constants = require('users/me/that_script.js');
And refer to the exported variable using constants.scale.
More info here

How to add localization toexternal js file in Asp.net MVC?

Im pretty much stuck, because i cant figure out how to "call" resource files in .js files. I have a login view, on this view i call MVC render method to generate script tag.
#Scripts.Render("~/Scripts/Login.js")
in my Login.js i have a variable :
var yes = "Resources.Resource.Yes";
which should be tranlated to Yes, or Ja, or anything else depends on which cultureInfo is set. Its pretty straight forward to do if i keep script files inside of my view, because then i just call #Resources.Rescource.Yes and it will work, but if script file is external, then it wouldnt work. How do i solve this?
The answer to this question would be largely opinion-based.
There are three main approaches i encountered working on various projects:
Localization handlers. You define the resources keys in javascript, in $(document).ready() you use ajax to get the localized values from a controller/httphandler dedicated to this and replace keyed text.
In-line js. Basically, you dump external .js and render scripts inside <script> tags in your views/pages.
Global variables. In the view your define global variables, like so:<script language="text/javascript">var myString='<%= Resources.MyString %>';</script>, then use the variable inside included .js.
Personally i prefer approach n 3 -> you can have a single place in code to create all variables and the page loads in one go.

Organizing javascript in Rails app

I have several javascript (coffee script) files in my Rails javascripts directory. The code is logically divided into different files. However, each file starts with $(document).ready -> and some files share common helper functions.
What is the best way to factor out the helper functions? Should I just put them all in some other file that gets included earlier in application.js?
Also, is it normal to have the code divided up the way mine is, where every page does $(document).ready ->? Doesn't this mean that all of my code is called on every page, regardless of whether or not it is relevant? Are there alternatives to this organization?
I'm not sure if this question is specific to Rails or relevant to javascript and jQuery in general.
I do think this is a Rails question, and a good one.
The normal paradigm in Rails, where "global" stuff goes in application.* is a little messed up with the asset pipeline, since the application.js really acts as a manifest, rather than a common file. Of course you could add stuff there, or even create an application.js.coffee for your common code. I decided to create a file called common.js.coffee (and in another case shared.js.coffee), which in my case was automatically handled by the require_tree . directive.
(Update based on comment from #jonathan-tran) In some cases, you may just want methods called on document ready for all pages -- for example, I used this to make a datepicker available to any field in any view. If, instead you want methods (actually global functions) available to be callable, you'll need to export the coffeescript functions to variables, for example by attaching to the window object. You can do both in a shared file.
It is true that if you use generators you'll end up with files for every controller which, if there's no specialized code result in a series of redundant $(document).ready -> statements when assets are compiled. So just get rid of the ones you don't use. But following the pattern of separating functionality specific to a page makes good sense to me and works well -- I know where to look to find stuff and that's worth a lot as a project grows.
And another rule I have learned with Rails: go with the flow. If that's how Rails does it, it's probably a good way. They do indeed think about these things. Don't fix what works :-)

Does the ORDER of javascript files matter, when they are all combined into one file?

In todays modern age, where lots of (popular) javascripts files are loaded externally and locally, does the order in which the javascripts files are called matter especially when all local files are all combined (minified) into one file?
Furthermore, many claim that Javascript should go in the bottom of the page while others say javascript is best left in the head. Which should one do when? Thanks!
google cdn latest jquery js | external
another cdn loaded javascript js | external
TabScript ...js \
GalleryLightbox ...js \
JavascriptMenu ...js \
HTMlFormsBeautifier ...js > all minified and combined into one .js file!
TextFieldResize ...js /
SWFObjects ...js /
Tooltips ...js /
CallFunctions ...js /
Order matters in possibly one or more of the following situations:
When one of your scripts contains dependencies on another script.
If the script is in the BODY and not the HEAD.. UPDATE: HEAD vs BODY doesn't seem to make a difference. Order matters. Period.
When you are running code in the global namespace that requires a dependency on another script.
The best way to avoid these problems is to make sure that code in the global namespace is inside of a $(document).ready() wrapper. Code in the global namespace must be loaded in the order such that executed code must first be defined.
Checking the JavaScript error console in Firebug or Chrome Debugger can possibly tell you what is breaking in the script and let you know what needs to be modified for your new setup.
Order generally doesn't matter if functions are invoked based on events, such as pageload, clicks, nodes inserted or removed, etc. But if function calls are made outside of the events in the global namespace, that is when problems will arise. Consider this code:
JS file: mySourceContainingEvilFunctionDef.js
function evilGlobalFunctionCall() {
alert("I will cause problems because the HTML page is trying to call " +
"me before it knows I exist... It doesn't know I exist, sniff :( ");
}
HTML:
<script>
evilGlobalFunctionCall(); // JS Error - syntax error
</script>
<!-- Takes time to load -->
<script type="text/javascript" src="mySourceContainingEvilFunctionDef.js"></script>
...
In any case, the above tips will help prevent these types of issues.
As a side note, you may want to consider that there are certain speed advantages to utilizing the asynchronous nature of the browser to pull down resources. Web browsers can have up to 4 asynchronous connections open at a time, meaning that it's quite possible that your one massive script might take longer to load than that same script split up into chunks! There is also Yahoo Research that shows combining scripts produces the faster result, so results vary from one situation to another.
Since it's a balance between the time taken to open and close several HTTP connections vs the time lost in limiting yourself to a single connection instead of multiple asynchronous connections, you may need to do some testing on your end to verify what works best in your situation. It may be that the time taken to open all of the connections is offset by the fact that the browser can download all the scripts asynchronously and exceed the delays in opening/closing connections.
With that said, in most cases, combining the script will likely result in the fastest speed gains and is considered a best practice.
Yes, depending very much on what you do.
For example, if a.js had...
var a = function() {
alert('a');
}
...and b.js had...
a()
...then you wouldn't want to include b.js before a.js, or a() won't be available.
This only applies to function expressions; declarations are hoisted to the top of their scope.
As for whether you should combine jQuery, I reckon it would be better to use the Google hosted copy - adding it to your combined file will make it larger when there is a great chance the file is already cached for the client.
Read this post from the webkit team for some valuable information about how browsers load and execute script files.
Normally when the parser encounters an
external script, parsing is paused, a
request is issued to download the
script, and parsing is resumed only
after the script has fully downloaded
and executed.
So normally (without those async or defer attributes), scripts get excuted in the order in which they are specified in the source code. But if the script tags are in the <head>, the browser will first wait for all scripts to load before it starts executing anything.
This means that it makes no difference if the script is splitted into multiple files or not.
If I'm understanding your question I think you're asking if it matters where in a file a function/method is defined, and the answer is no, you can define them anywhere in a single source file. The JavaScript parser will read in all symbols before trying to run the code.
If you have two files that define variables or functions with the same name, the order that they're included will change which one actually is defined

Javascript scope problems

I have a bunch of javascript "classes" (Prototype) that make up the inheritance hierarchy of a web application I'm building. I've been trying to organize these classes into "namespaces":
var UI = {
Control: Class.create(KVO.Object,
{
...
})
}
The classes are organized into separate files, so when I wanted to add a class to UI, I did this in a separate file:
UI.TextFieldControl = Class.create(UI.Control,
{
...
})
But, when I try to use UI.TextFieldControl in my program after including the files, it is undefined. I guess this is a scope problem of some sort, because within the TextFieldControl file it is defined, but as far as I can understand UI.TextFieldControl should be defined after it is included; what am I doing wrong?
Ok, I found the problem; I was including the file that defines UI twice, once before the file that defines UI.TextFieldControl and once after. Thanks for your responses; I was beginning to worry I didn't understand javascript scope at all!
Have you tries using FireBug? Because by the code you provided nothing seems to be wrong. If your file includes are fine. Your controls should be defined.
Use FireBug and check your files and their order of loading. Maybe your UI.Control is being loaded after you define TextFieldControl? You'll also be able to see your UI namespace if it hass all the necessery classes and also try defining them by hand and see what happens.
If you're using IE you probably forgot to remove some trailing comma, that simply discarded the whole file with your TextFieldControl...

Categories