First of all: 'Locally' neither means "localhost", nor "local folder". It means a code area or a code space or a code region.
I have two JS (*.js) files for my site. One is to show a news ticker and other is to load something on hover. They are conflicting, and I can't remove any one of 'em because I need 'em.
So a thing comes up to my mind is: as I can make many things locally, why not I load a js file locally? Suppose:
<?php
if('condition') {
DO IT ONCE;
}
?>
<?php
if('other_condition') {
DO STH ELSE ONCE;
}
?>
In such case, the first condition doesn't bother the second condition. Even though the first one is doing, the second one is also doing well. No conflict, nothing.
If I can load a JS locally for a specific purpose and then break the JS loading further, then if I load other JS, she won't find any JS before, because that's for a specific purpose for the specific region only.
I think I'm clear with my idea. I'm here with a WordPress site, loading code specifically for home page using is_home() function. I want such a way to load a JS file for a region, and then break it to let the other JS function properly.
If you've designed your Javascript well, you can have two scripts that don't interfere. Without seeing the actual scripts, it's hard to recommend improvement. You could introduce new scopes for each of the scripts:
script1.js
(function() {
var script_variable = document.getElementById("my_form");
script_variable.onchange = function() { /* ... */ };
})();
script2.js
(function() {
// Same name!
var script_variable = document.getElementById("other_element");
script_variable.onclick = function() { /* ... */ };
});
Load each in a separate iframe.
Related
I am developing web application in smartAdmin Template, which is fully ajax based template you can check demo here. i am facing some difficulties in this template. when i write one javascript function on some page it works on all pages.
for example
$(document).on('click', '#elementA', function(){
alert('Hello World');
});
works on other pages's element which also have same id, it is difficult to give different ids to all element as it is very large project and i am working on it since 6 months, so i thought about it and find out solution to give unique id to each pages and write script like this.
$(document).on('click', '#pageA #elementA', function(){
alert('Hello World');
});
i thought i solved the issue but, isn't function stopped working on other page's element. but when i visit #PageA 2nd time the function runs twice. actually template stores all the user defined function in local memory storage (i think, i am not sure about this) and keeps storing, until we do not refresh whole template.
ok, after long R&D i solved this my self..
i used loadscript() function to prevent loading scripts twice unnecessarily..
i wrote all the script into one file (now i will have two view pages for one page.)
earlier it was like..
A.php -> JScript + PHP & HTML
now it is like A.php -> PHP & HTML, script/A.php -> OnlyJS
as i am using codeginiter framework, and dont want others too see js by accessing it through url, i used this process.
code on my view file
loadScript("<?php echo site_url('processor/load_script/path_to_folder/script/add'); ?>");
function on Processor controller
public function load_script($path)
{
$last_segment = count($this->uri->segment_array());
$path = '';
for($i=3;$i<=$last_segment;$i++)
{
$path .= '/'.$this->uri->segment($i);
}
$this->load->view('core/ajax'.$path);
}
So, as a sort of exercise for myself, I'm writing a little async script loader utility (think require.js, head.js, yepnope.js), and have run across a little bit of a conundrum. First, the basic syntax is like this:
using("Models/SomeModel", function() {
//callback when all dependencies loaded
});
Now, I want to know, when this call is made, what file I'm in. I could do it with an ajax call, so that I can mark a flag after the content loads, but before I eval it to mark that all using calls are going to be for a specific file, then unset the flag immediately after the eval (I know eval is evil, but in this case it's javascript in the first place, not json, so it's not AS evil). I'm pretty sure this would get what I need, however I would prefer to do this with a script tag for a few reasons:
It's semantically more correct
Easier to find scripts for debugging (unique file names are much easier to look through than anonymous script blocks and debugger statements)
Cross-domain requests. I know I could try to use XDomainRequest, but most servers aren't going to be set up for that, and I want the ability to reference external scripts on CDN's.
I tried something that almost got me what I needed. I keep a list of every time using is called. When one of the scripts loads, I take any of those using references and incorporate them into the correct object for the file that just loaded, and clear the global list. This actually seems to work alright in Firefox and Chrome, but fails in IE because the load events seem to go off at weird times (a jQuery reference swallowed a reference to another type and ended up showing it as a dependency). I thought I could latch on to the "interactive" readystate, but it doesn't appear to ever happen.
So now I come asking if anybody here has any thoughts on this. If y'all want, I can post the code, but it's still very messy and probably hard to read.
Edit: Additional usages
//aliasing and multiple dependencies
using.alias("ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js", "jQuery");
using(["jQuery", "Models/SomeModel"], function() {
//should run after both jQuery and SomeModel have been loaded and run
});
//css and conditionals (using some non-existant variables here)
using.css({ src: "IEFix", conditionally: browser === "MSIE" && version < 9 });
//should include the IEFix.css file if the browser is IE8 or below
and to expound more on my response below, consider this to be file A (and consider the jquery alias from before to be there still):
using(["jQuery", "B"], function() {
console.log("This should be last (after both jQuery and B have loaded)");
console.log(typeof($));
});
Then this would be B:
using("C", function() {
console.log("This should be second");
});
And finally, C:
console.log("This should be first");
The output should be:
This should be first
This should be second
This should be last (after both jQuery and B have loaded)
[Object Object]
Commendable that you are taking on such an educational project.
However, you won't be able to pull it off quite the way you want to do it.
The good news is:
No need to know what file you are in
No need to mess with eval.
You actually have everything you need right there: A function reference. A callback, if you will.
A rough P-code for your using function would be:
function using(modules, callback) {
var loadedModules = []
// This will be an ajax call to load things, several different ways to do it..
loadedModules[0] = loadModule(modules[0]);
loadedModules[1] = loadModule(modules[1]);
// Great, now we have all the modules
// null = value for `this`
callback.apply(null, loadedModules);
}
Ok so I have a .js file with about 10k lines of code. This code can be split up in
sub-object definitions
container object definitions
initialization code (after the objects have been defined)
program functionality
I would like to split this one file into 4 separate files, because it provides a better oversight. How do I go about doing this, given that they absolutely have to be declared in that order? What should I wrap up in a $(document).ready() and what not?
If I just separate the files and link them to the html in the correct order, I get undefined object errors. I was also thinking of something like this; but I don't know if that's any good...
Second JS File
function initializeContainers() {
var containerObj1 = {
bla: 'bla',
bla2: 'bla2'
},
var containerObj2 = {
bla: 'bla',
bla2: 'bla2'
};
};
First JS File
$(document).ready(function() {
function initializeSubObjects(callback) {
var subObj1 = {
somekey: 'somevalue',
someke2: 'someothervalue'
};
callback();
};
initializeSubObjects(initializeContainers);
});
I have no clue whether this is the correct way to do it?
PS: I also know you can add the script tags dynamically; but is that good practice?
In your example, you should swap the contents of your first and second file. You should only call the initializeContainers method when you know for sure the file has been loaded.
The easiest way to think about this is to load all files with definitions first (helpers, functions, classes, ...). Once all these are loaded, put the rest in the last file and start executing the code only in the last file
On a side note: If you deploy this into a production environment, you should consider bundling these files. Downloading 4 files will impact your load time, so it's better to just bundle them together and send them over as a single file. While you're at it, you probably also want to minify it.
I'm having real problems with my application due to the order I render the .js scripts. For example in http://jsfiddle.net/qCAW3/1, the items will not become draggable until I change the order in which the js scripts are loaded.
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
Can anyone shed some light as to what causes this. If I change the order to get the draggable items to work, then other javascript parts of my application stop functioning.
Dependencies, that's when some code depends on other code. And on a webpage, JavaScript files are executed in the order they are declared. Which is important for dependencies!
Lets say you have two .js files that look like this:
// person.js
var Person = function(name) {
this.name = name;
};
Person.prototype.greet = function() {
alert("Hi, " + name);
}
And another file:
// roster.js
var roster = [
new Person("Alex"),
new Person("Eddy")
];
for (var i = 0; i < roster.length; i++) {
roster[i].greet();
}
If we load roster.js first, it will explode. The Person constructor would not yet be available, and calling it anyway would raise an expection.
If you load person.js, and then afterward load roster.js, then you have Person available when the roster code runs.
In your case, you need to load jQuery before any code that uses jQuery, for exactly the same reason.
Typically when one file depends on another, it has to be loaded after. That's in a very general sense. Since your problem is centered around load order and timing, I'd suggest looking here. Basically, make sure not to execute anything before all files being depended upon finish loading.
I'm working on a web application that includes different JavaScript files, depending on where I am in the app. For instance, I have a display.js for each page, each of which has an "init()" function that is called as soon as the page is loaded.
This works well for the webapp, but in my QUnit tests, where all script files are included from a single index.html, functions of the same names override each other.
How are such problems best handled? One test index.html file per page creates lots of boilerplate code and makes it non-trivial to execute all test cases. That's why I decided to name each and every function distinctively, e.g. "initFrontPage()" instead of "init()". This, however, makes the application code a bit weird: Not only do I have to include the right file, I also have to call the right functions in it. Is there a better way?
The solution is to use namespaces:
In foo/display.js:
window.foo = {};
foo.init = function () { ... };
In bar/display.js:
window.bar = {};
bar.init = function () { ... };
Then, in the page that uses bar/display.js's init method:
(function (display) {
display.init();
}(bar));
It would be a good idea to wrap your display.js code in an IIFE as well.