I am writing a widget template, which will be included in a page where it is installed.
One may install several of the same kind of widget in one page, so my template may get included several times.
Now I have written some JavaScript to initialize the widget, you know, the clickings and hoverings.
My problem is that these <script>s get executed multiple times, for example, when I click something, the bounded function get executed several times.
What is the best way to solve this problem?
EDIT:
By the way, I am using the Mako template engine, and I've tried using the c variable to store a boolean flag, but it seems that the c get overridden every time.
What about a similar solution to the one that's been used in C to prevent header-files to be included multiple times?
For example in the file "example.html" you could wrap your code in an if-statement like this:
<script type=text/javascript>
if (!window._EXAMPLE_HTML_) {
window._EXAMPLE_HTML_ = true;
// your code goes here
}
</script>
Related
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?
In my project I have a load of functions that are used on every page, so I have put these in a single javascript file common.js and have included it in my footer template. My questions is, what is the best way to handle page-specific javscript?
For example, on one of my pages I have a google map. If my map js code is run on a page where I don't have an element with id map_canvas, I get an error.
Method 1: I could write some PHP which echos an additional script tag requesting map.js if and only if I'm on a map page.
Method 2: I could give the <body> of my map page an id of "map_page", then I could write a conditional clause in common.js along the lines of:
if (#map_page exists){
put contents of map.js here
}
The problem with method 1 is that it increases the number of requests to the server.
The problem with method 2 is that it bloats my common javascript file.
Please can somebody explain, which, if any would be the preferred method to do this, or if neither are suitable, what I should do instead?
I have approximately 10 page-specific javascript files to deal with.
Thanks
I would say that simpler is better. On every page, just add a script tag calling map.js. Or, in your common.js, you don't need to paste all of map.js's code. You can just create a new script tag with the js and call map.js like that. I would not recommend the php method. The easiest and simplest, therefore the least likely to be buggy method, is just to add another script tag to the pages that need it. Or if that is not an option, common.js could include this:
if(need map.js){
var mapjs=document.createElement("script");
mapjs.type="text/javascript";
mapjs.src="map.js";
document.body.appendChild(mapjs);
}
I've spent a great deal of time creating and testing an application with quite a few functions. Now that I have configured everything and it works how I want, I would like to begin cleaning up the code so its not 400 lines of mush.
I have already created an external CSS file and would like to do something similar for the JS and possibly even the HTML (approx 100 lines of code of just HTML, ick).
Admittedly I am a novice programmer but I've picked up quite a bit of knowledge in the short time I've been doing this. What is the best way to separate out the functions into external files and then call them so that the whole application works as it does now?
For example (this is a web mapping application): I have functions for search, basemap gallery, legend, layers, init, infowindows, etc. Since the code is already written and I'll be creating multiple applications in the future, the goal would be to just have these js functions in files ready to be referenced by whatever application needs them.
Thanks.
To link an external javascript file, place a script tag with a src attribute pointing to your file.
<script src="legend.js"></script>
<script src="layers.js"></script>
<script src="init.js"></script>
Calling a function requires nothing special.
onclick="myFunction();"
Could you not just put all of those functions in one .js file and then call the file from within your web page?
<script src="../scripts/javascript.js"></script>
And then call on your functions as and when you need them?
The first thing you might consider doing do is to create a non-global "namespace" for your functions in a fashion such as the following:
window.MyApp = window.MyApp || {};
The above line can be at the top of every file; the first time it is invoked it creates a new namespace/object, subsequently it returns the one you previously created.
Then you can move your functions under MyApp in a manner such as the following:
MyApp.func1 = function() {...}
Google for creating Javascript namespaces, and possibly also the Javascript module pattern
I have created a string builder JavaScript object and I'm using it with many different .js files in my project.
Can I create this class in a separate .js file and call it from all the other scripts that instansiate it, just like a C# class file?
Is this possible, or do I continue copying and pasting it into the bottom of every .js file that uses it?
Yes, this should not be a problem. Just include the .js files in the correct order in your html pages.
If you include the file in your main HTML page with your other js, you can then use the "class" as you wish:
<script src="js1.js" type="text/javascript"></script>
<script src="js2.js" type="text/javascript"></script>
In the above example, you can now instantiate a new instance of an object from js1.js with the code in js2.js. To do this with pure javascript, you would have to add the script tag to the DOM, or use AJAX to fetch the script file and eval() it.
// Create a <script> element
var scriptEl = document.createElement("script");
scriptEl.src = "js2.js";
scriptEl.type = "text/javascript";
// Append it to the <head>
document.getElementsByTagName("head")[0].appendChild(scriptEl);
To be perfectly correct, it's not the order of inclusion that matter, but rather the order of executing code. In most cases, Andy's and Segfault's instructions are just fine, but sometimes including the class file before its consumers isn't sufficient. For example, if you use ExtJS and you happen to define your class inside an onReady handler like this:
Ext.onReady(function() {
myClass = ...
}.bind(this));
then it won't get executed by the time your second src file is included into the page and executed.
I know, the example is a bit far-fetched :) but just make sure that your code is executed in the right order, not just included in the right order.
I came across this question and I wanted to add something (which probably wasn't there a few years ago).
Even thought you can add every single script to your "index.html" it's not a very beautiful practice (imho). Especially if you consider that you may want to write a extension (~ framework). You don't want to annoy the user with a bunch of script tags he has to add to his code. What you want is a single line like this:
<script src="yourFramework" (...) />
However, with the use of RequireJS you are able to achieve this. You've the freedom to separate your code and "your user" still don't have to add a novel to his "script section".
I have a script element in my webpage, something like this:
<script id="myscript"></script>
Now, from a javascript file, I'm doing something like the following:
$('#myscript').src('http://foo.bar?callback=somefunc')
Now this remote script 'returns javascript' of the following form:
somefunc(somearg);
When I run all of this, things work neatly, the script gets loaded dynamically, and the 'somefunc' callback is executed.
The problem happens when I do the same thing again. Let's say I again call the same thing:
$('#myscript').src('http://foo.bar?callback=somefunc')
This, for some reason, DOESNT return the javascript call in Firefox only. (Works fine in IE - somefunc gets executed again as expected).
I can think of ugly workarounds (such as doing a $('head').append('<script...')) every time - but I'd like to know what's going on here.
Thanks in advance!
I would recommend you to use $.getScript instead of using a single script tag load scripts multiple times:
$.getScript("http://foo.bar?callback=somefunc");
That function will abstract the script element creation and its introduction to the DOM.
But it seems you are accessing a JSONP service, in that case you need only $.getJSON:
$.getJSON("http://foo.bar?callback=?", function(json){
// callback
});
I can think of ugly workarounds (such as doing a $('head').append('
Ugliness is subjective; personally, I find the technique you're trying to use (making a single script tag load multiple scripts) far uglier.
But that's not really important. Adding a new script tag works - so if you're having trouble with what you're doing, just use the normal method and live with it.
FWIW: Firefox probably doesn't respond because you're not actually changing anything... If you want to make this even uglier, append some do-nothing querystring parameter that changes each time through.