category

article

Sandboxing jQuery selection

Posted on: November 26th, 2012 1 Comment

Recently, I had to come up with an architecture that would allow multiple teams within Sky to write modules for a single page application. They were supposed to host their own JS scripts and CSS, and we'd load them into the app dynamically, when users would visit certain sections of the app.

You can imagine how without proper sandboxing, this would cause chaos, as a naive approach would allow a team's scripts and CSS to clash with other teams'. The proposed solution I came up with included enforcing modules, dependency management and dynamic loading via Require JS, using an MVC framework, hooks in the software versioning system that would trigger integration tests to run, and last, but very important: currying jQuery, so that when a selector was used, it would only select elements under a certain view's root element.

A selector that is too broad can have unforeseen effects, and is more dangerous when it affects parts of the DOM that you don't own. The solution is pretty simple: within a module you declare a local variable "$", or "jQuery", which will actually be a curried version of jQuery.

The jQuery function has multiple signatures: http://api.jquery.com/jQuery/. When the first argument is a string, and no context is provided, we want to make sure that it can only grab elements that are owned by us. So, based on the parameters passed into our wrapper around jQuery, we decide whether to add our root element as context:

    getSandboxedJQuery: function($root){
        var selector = null;
    
        return function(){
            var args = Array.prototype.slice.call(arguments);
    
            if (args.length == 1 && (typeof (selector = args[0]) == 'string')){
                return $.apply(this, args.concat($root));
            }
            
            return $.apply(this, arguments);
        };
    }

Here is some more code in a demo (http://jsfiddle.net/LwFsy/22/: you have a simple module that is run when the DOM has finished loading, and that receives an Api as a parameter. This is similar to a real life RequireJS module. Then, with the curried version of jQuery, we use a broad selector to find a div. If we'd select it the original jQuery, we'd also get another div outside our restricted tree.

One Response

  1. RitaX

    June 29, 2017

    I must say you have hi quality articles here. Your posts can go viral.
    You need initial traffic only. How to get massive traffic?
    Search for: Murgrabia’s tools go viral

    Reply

Leave a Reply