开发者

Is there a better way to organise javascript in a single file with specific code for multiple pages?

I have a couple of websites where I use a relatively small amount of jQuery to do various things on the pages. Generally we're talking about a couple of dozen lines of code per page.

I keep all of my JS in one file so far as it's not huge and fairly clearly defined. That said, what I have trended towards is organizing it like so:

$(document).ready(function(){
  var onPage1 = $("#id_thing_on_1").length === 1;
  if( onPage1 ){
    var usefulPage1Function = function(){}; //blah
    $("a").click(function(){}); //etc
  }
});

$(document).ready(function(){
  var onPage2 = $("#id_of_page_2").length === 1;
  if( onPage2 ){
    $(".someClass").fadeIn().click(function(){}); //etc
  }
});

Anything that is used on multiple pages gets taken out into a library, but for page specific stuff, this is the pattern I've been following. Is there a better approach, or is this an acceptable practice for keeping your JS i开发者_如何学Pythonn one file and loading it on multiple pages?


I would be interested in knowing other's view on this, but what I did so organize and execute the correct set of JS code for each page, is to have a kind of routing engine as the basis of my js app where I add a 'controller' list that each section adds it self to and the routing engine calls the controller.init() method based on the url.

myApp = {};

(function(app, $) {
    var defaultController = "Default";

    var routes = [];
    routes["Default"] = defaultController;

    var currentControllerFromUrl = function() {
        // match urls in the form ../mvc/controllerName.mvc/...
        var re = new RegExp(/\/(\w*)/i);
        var m = re.exec(document.location);
        if (m == null) {
            return null;
        }
        else {
            return m[1];
        }
    };

    var currentActionFromUrl = function() {
        // match urls in the form ../mvc/controllerName.mvc/action/
        var re = new RegExp(/\/mvc\/\w*.mvc\/(\w*)(\/|\b)/i);
        var m = re.exec(document.location);
        if (m == null) {
            return null;
        }
        else {
            return m[1].toLowerCase();
        }
    };

    var currentWebPageFromUrl = function() {
        var re = new RegExp(/\/(\w*).html/i);
        var m = re.exec(document.location);
        if (m == null) {
            return null;
        }
        else {
            return m[1];
        }
    };

    var populateControllerRoutes = function(app) {
        for (var ctl in app.controllers) {
            routes[ctl] = ctl;
        }
    };


    var theApp = {
        controllers: {},
        run: function() {
            this.initController();
        },
        initController: function() {
            var urlController = currentWebPageFromUrl();
            // populate routes
            populateControllerRoutes(this);
            if (urlController && routes[urlController]) {

                // load the correct controller into the activeController
                this.controller = new this.controllers[routes[urlController]]();
                this.controller.init();

                var action = currentActionFromUrl() || "index";
                if (action && this.controller[action + "Action"] !== undefined)
                    this.controller[action + "Action"]();

            }
        }

    };

    window.myApp = $.extend(app, theApp);
})(myApp || {}, jQuery);


// and somewhere else
(function($) {
    myApp.controllers.default = function() {
        this.init = function() {
        };

        this.indexAction = function() {
            // index action init
            $("#res").text("hi there!");
        }
    }
})(jQuery);

$(function() {
    myApp.run();
});

With this approach, the controller functions don't need to be in one file, so during development you can keep your controller functions in separate files nicely organized and as part of the build/deploy, combine them and minimize them all into one JS file.


Here's one way to reduce the redundancy in your code:

$(document).ready(function(){
  function page1() {
    var usefulPage1Function = function(){}; //blah
    $("a").click(function(){}); //etc
  }

  function page2() {
    $(".someClass").fadeIn().click(function(){}); //etc
  }

  var pages = [
    [ '#id_thing_on_1', page1 ],
    [ '#id_of_page_2',  page2 ]
  ];

  for (var i = 0; i < pages.length; i++)
    if ($(pages[i][0]).length === 1)
      pages[i][1]();
});


There is a cost for loading js you don't need. But really it depends on the usage pattern of your site. If the majority of the page loads occur on the homepage for instance, then merging and minifying all your js into one file for that page might make sense. If the unique code is kept small, then your approach is sound. This illustrates the natural tendency of code to loose structure when it is optimized.


Can you tell us why you want to put different page specific codes into the one single file, given the fact that you are 100% sure those codes won't be executed, in fact you are spending time to write up code/controller to avoid those unrelated code to be executed.

Also how many pages are you talking about, if it's only 2 pages, then you should be fine. But what if 50 pages? What if 20 pages use the same code, what your controller is going to look like? Or are you going to copy the same piece of code 20 times?

HOWEVER, having all codes in a minified single file does seem to load faster than browser initiating multiple downloads. You should have a balance between network VS coding practice.

I tend to have different js files with page specific code for different pages, so unrelated codes are not loaded.

Any code that is common use, I put it into specific lib js files, so most of the unrelated lib code are not loaded.

Eg.

Search page will have:
  search_page.js
  util.js  
  form_validation.js

Result page will have
  result_page.js
  util.js
  lib_map.js

Just my $0.02

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜