I have a multiple page website using RequireJS, which loads a boot strap file (boot.js), which then requires app.js.
app.js handles all the logic, and all other module initialization happens through app.initModule() (which is just a require() call wrapper)
I also have a app.loadPageJS() to load page specific JS files (based on window.location.pathname, for example, www.domain.com/path/to/file.html would auto-load /_assets/js/pages/path/to/file.js)
This feature can be turned on/off, and overridden by adding a class of "no-auto-load" or "auto-load" to the body, respectively.
Now, my approach isn't robust enough. For one, url rewriting would break the mechanism, and for two, if loadPageJS is turned off, unless I have access to the body tag, I can't include a page specific JS file (in the case of sites using templating systems, adding a class to the body tag isn't always an option).
What are other ways to include page specific code? I'd rather avoid the following:
adding page specific code to a global.js file and doing if checks and only running certain code sets
using a pageName variable (which would essentially be similar to the above)
Thanks in advance.
If you have different modules on the page sectioned by unique ID's (a newsletter module wrapped within a div with an ID of 'newsletter', etc), you could test for existence of the module element in the DOM and conditionally load in the JS file necessary to run that module. So rather than being page-specific, it is module specific.
Related
I have Post model for a blog app in Django. It has a field named body. In posts, I may use Latex so I need to use MathJax.js. In some posts, I add code snippet, so I use highlight.js. In some I use both, in some I use none of them.
I want to load the relevant javascript depending on the body field of the Post model (similar to THIS). How can I make the relevant .js file(s) to load automatically?
I know that I can add an indicator field like hasLatex (True, False) or hasCode (True, False). But I'm lazy, I want Post.body to be automatically scanned and only relevant js files loaded.
Set something in your context or use a template context processor. For example I load code that handles forms if there is a form key is my context. For something I want on almost every page I put a no_something in my context to disable it. This is done by putting a conditional around the tag in your base template. If the variable is not there or is false it won't show.
What I also do is put my static files in lists inside of my context. JavaScript is in context['js'] and css in context['css']. Those are looped through in my header. I can implement get_context_data in a base class, and all the views that extend from that will have the javascript and css files.
We have a product that is a widget people load onto their site, which consists of a single JS file that also needs angular to run, so angular is bundled into the JS file.
However, if a site already is using and loading angular themselves, when they load our widget they get an error which kills everything with the following:
WARNING: Tried to load angular more than once
Which makes complete sense since angular was indeed loaded more than once.
What we'd like to do is either of the following:
In our script, rename / namespace angular so it does't conflict with
the host sites already loaded angular, or
Detect if angular is
already loaded, and if so don't load angular ourselves.
To show examples of our code would be difficult since it's spread over about 20 files etc, however it's based off the following angular seed project which uses requirejs to load everything, then we're compiling to a single file: https://github.com/tnajdek/angular-requirejs-seed
Would really appreciate any feedback / tips / solutions
NB This is not a duplicate of any "check if angular loaded correctly" type questions, angular is packaged inside our widget js, the issue comes when angular is also already loaded by the parent page. We need a way to rename angular inside our package.
I'd advise taking a look at this answer, it has to do with a chrome extension running in the same circumstance. The idea here is to separate your loading of angular from the website's, and it assumes that your widget will be loaded after the main content of the page has been loaded.
If you are loading in html content with an ng-app directive or ng-controller, wrap your html content in a container with ng-non-bindable as an attribute.
Angular looks immediately for an element with the ng-app attribute when you load in angular.js. If two ng-apps are present i.e., on your site, and the widget, it will cause errors. Defer the parsing with: window.name = "NG_DEFER_BOOTSTRAP!" + window.name; Then load in your script.
Once your script has loaded, set window.name to '' or whatever it was before.
Individually bootstrap (the term for angular finding an ng-app attribute) your html content using:
var appRoot = document.querySelector('#id');
angular.bootstrap(appRoot, ['angularModuleName']);
And that should do it... Caveat, I have no idea how this would work if your widget Angular is on a different version than the client website, and I've only made it work with extensions, which are a little bit different because they live in their own isolated 'worlds'.
That being said, I feel like this should get people going in the right direction when dealing with this problem.
Just a quick question here. I am trying to register a js file for script validation using
if (!Page.ClientScript.IsClientScriptBlockRegistered("strIncludeJSFile")) Page.ClientScript.RegisterClientScriptBlock(strIncludeJSFile.GetType(), "strIncludeJSFile", strIncludeJSFile);
code in C# and it works well for the js files. But, some js files are used in multiple pages, so I am unsure if the above code will be a good idea. As such, I want to do the same thing in the js file itself, instead of using the code behind. Is there any possibility to do that? Or is this thing specific to C#?
of course you can register a js file (or script block) from html by using a script tag. However, the main reason RegisterClientScriptBlock exists is because developers might need to generate (or modify) a script block dynamically from code behind or conditionally register a script file dynamically.
If you need any of the above...generate a script block dynamically, then you "might" be better off registering it from code behind, I mean, it depends on the whole solution itself, it's hard to recommend an approach without having some context. Either way, some options are:
register the script blocks from code behind if you need to generate based on some conditions that can only be evaluated from server side code
use a master page for better and register the script block from the master page. This will make it easier to maintain if you keep the logic in one place
similar to the option above, you can use a base page class if using a master page is not possible
use an html script element if what you need is to reference a static js file
use place holders such as js variables and fetch dynamic data from the server using ajax
use unobtrusive javascript, custom data attributes and ajax
Whatever the suitable option(s) is depends on too many factor that you have to assess
Quick question, I have some scripts that only need to be run on some pages and some only on a certain page, would it be best to include the script at the bottom of the actual page with script tags or do something like in my js inlcude;
var pageURL = window.location.href;
if (pageURL == 'http://example.com') {
// run code
}
Which would be better and faster?
The best is to include the script only on pages that need it. Also in terms of maintenance your script is more independant from the pages that are using it. Putting those ifs in your script makes it tightly coupled to the structure of your site and if you decide to rename some page it will no longer work.
I can recommend you to use an asynchrounous resource loader, LAB.js for example. Then you could build a dependencies list, for instance:
var MYAPP = MYAPP || {};
/*
* Bunches of scripts
* to load together
*/
MYAPP.bunches = {
defaults: ["libs/jquery-1.6.2.min.js"],
cart: ["plugins/jquery.tmpl.min.js",
"libs/knockout-1.2.1.min.js",
"scripts/shopping-cart.js"],
signup: ["libs/knockout-1.2.1.min.js",
"scripts/validator.js"]
/*
... etc
*/
};
/*
* Loading default libraries
*/
$LAB.script(MYAPP.defaults);
if (typeof MYAPP.require !== 'undefined') {
$LAB.script(MYAPP.dependencies[MYAPP.require]);
}
and in the end of your page you could write:
<script type="text/javascript">
var MYAPP = MYAPP || {};
MYAPP.require = "cart";
</script>
<script type="text/javascript" src='js/libs/LAB.min.js'></script>
<script type="text/javascript" src='js/dependencies.js'></script>
By the way, a question to everyone, is it a good idea to do so?
In so far as possible only include the scripts on the pages that requirement. That said, if you're delivering content via AJAX that can be hard to do, since the script might already be loaded and reloading could cause problems. Of course you can deliver code in a script block (as opposed to referencing an external js file), in code delivered via AJAX.
In cases where you need to load scripts (say via a master page) for all pages, but that only apply to certain pages, take advantage of the fact that jQuery understands and deals well with selectors that don't match any elements. You can also use live handlers along with very specific selectors to allow scripts loaded at page load time to work with elements added dynamically later.
Note: if you use scripts loaded via content distribution network, you'll find that they are often cached locally in the browser anyway and don't really hurt your page load time. The same is true with scripts on your own site, if they've already been loaded once.
You have two competing things to optimize for, page load time over the network and page initialization time.
You can minimize your page load time over the network by taking maximum advantage of browser caching so that JS files don't have to be loaded over the network. To do this, you want as much javascript code for your site in on or two larger and fully minimized JS files. To do this, you should put JS for multiple different pages in one common JS file. It will vary from site to site whether the JS for all pages should be ine one or two larger JS files or whether you group it into a small number of common JS files that are each targeted at part of your site. But, the general idea is that you want to combine the JS code from different pages into a common JS file that can be most effectively cached.
You can minimize your page initialization time by only calling initialization code that actually needs to execute on the particular page that is being displayed. There are several different ways to approach this. I agree with the other callers that you do not want to be looking at URLs to decide which code to execute because this ties your code to the URL structure which is better to avoid. If your code has a manageable number of different types of pages, then I'd recommend identifying each of those page types with a unique class name on the body tag. You can then have your initialization code look for the appropriate class on the body tag and branch to the appropriate initialization code based on that. I've even seen it done where you find a class name with a particular common prefix, parse out the non-common part of the name and call an initialization function by that name. This allows you to give a page a specific set of behaviors by only adding a classname to the body tag. The code remains very separate from the actual page.
the less general purpose way of doing this is to keep all the code in the one or two common JS files, but to add the appropriate initialization call to each specific page's HTML. So, the JS code that does the initialization code lives in the common JS files and thus is maximally cached, but the calling of the appropriate initialization code for that page is embedded inline in each specific page. This minimizes the execution time of the initialization, but still lets you use maximal caching. It's slightly less generic than the class name technique mentioned earlier, but some may like the more direct calling technique.
Include scripts at bottom of pages that need it only.
The YSlow add-on is the best solution to know why your website is slow.
There are many issues which could be the reason for slowness.
Combining many jQuery to one could help you increasing your performance.
Also you can put the script at the bottom of your page and CSS at top.
Its basically up to you and depends on what the code is.
Generally with small things I will slip it into the bottom of the page. (I'm talking minor ui things that relate only to that page).
If you're doing the location ref testing for more than a couple pages it probably means you're doing something wrong.
You might want to take a look at one of these:
http://en.wikipedia.org/wiki/Unobtrusive_JavaScript
http://2tbsp.com/node/91
And as for which is faster it's wildly negligible, pick what is easier for you to maintain.
This is the scenario:
I'm working on a new ASP.NET application that uses master pages for virtually all of the web pages in it, a few of them nested to 4 levels. Due to the size of the project, I was forced to organize the web pages into folders, at various depth levels. The global, Master (in uppercase) page, located at the root directory, contains some useful Javascript functions that are used all along the web app, and I wanted to place these functions together in a single .js file, in order to keep things, well, in order :D . (They're currently embedded into the Master page).
I discovered recently, however, that <script> tags placed on the <head> block can't have their paths specified as, for example, "~/Scripts/Utils.js", since ASP.NET does not seem to recognize these paths on <script> tags (yet, strangely enough, it does recognize them on <link> tags). I'm trying to avoid inserting a <script> tag on every single web page on the site specifying a relative path to the .js file (that's sort of why I wanted to use master pages in the first place).
So, in essence, given this scenario, I want to ask you, what's the recommended way of inserting, via code, <script> tags into the <head> block of a web page so that I can use, when specifying the link to the .js file, something like Something.Something(Something, Page.ResolveURL("~/Scripts/Utils.js")); in the global Master page, so it will resolve to the right path on all the web pages of the application, no matter what directory are they inside?
Or is this not the right approach, and I should be using something else entirely?
You can use the ClientScriptManager:
Page.ClientScript.RegisterClientScriptInclude("MyScript", ResolveUrl("~/Scripts/MyScript.js"));
The first argument is a unique key representing the script file, this is to stop subsequent scripts being registered with the same key. E.g. you may have some shared code that does the same thing and could be executed multiple times, so by specifying a key, you ensure the script is only registered the once.