(Optional) Building jQuery

Build your tools from the beginning so you don't take anything for granted in jQuery.

Scroll down...

Content

Resources

Comments

You can't really understand your tools until you've had a chance to look at them up close and personal. In this assignment, you'll build many of jQuery's core functions on your own to get a solid understanding of how it works under the hood.

Getting Started

  1. Fork and clone the project's Github Repo.
  2. Create a script file and include it into an HTML file.

Warmup: Constructors

You've worked with constructors before but let's do a quick warm up to clarify that they really aren't all that magical.

  1. Create a normal constructor called Foo which returns a simple Foo instance containing a sample property and method when you call it with the new keyword.
  2. Create your own "constructor" called Bar which returns a simple anonymous object which is otherwise the same as the one you created using Foo above but doesn't need to be called using new.

Verify:

var foo = new Foo();
foo instanceof Object
//=> true
foo instanceof Foo
//=> true


var bar = Bar();
bar instanceof Object
//=> true
bar instanceof Bar
//=> false

Now comes the fun part... you can actually set up your constructor to return an instance regardless of whether it is invoked with the new keyword or not. Create a constructor function Baz that returns an instance of Baz when invoked with and without the new keyword.

Verify that:

var baz = new Baz();
baz instanceof Baz
//=> true

baz = Baz();
baz instanceof Baz
//=> true

Note: this SO post should be helpful.

Warmup: Anonymous Functions

Let's do a quick warmup to verify that you understand how to define functions which take other functions. In this case, build a SimpleObject constructor which makes an object that contains a collection inside of it and also a method called each which allows you to iterate over that collection using a passed-in function:

myObj = new SimpleObject();
myObj.collection = [1,"foo",3];
myObj.each( function( el, index ) {
  console.log( "Item " + index + " is " + el);
})
// Item 0 is 1
// Item 1 is foo
// Item 2 is 3

Now let's add a method to the SimpleObject function itself. Let's create a method each that takes two parameters. The first is a collection, and the second is a callback function that passes the element and index as arguments. This should result in the following being possible:

var collection = ['foo', 'bar', 'fiz', 'baz'];

SimpleObject.each(collection, function(el, index) {
  console.log( "Item " + index + " is " + el);
});

Remember JavaScript functions are objects too, so creating properties on them is as simple as:

var Foo = function() {};

Foo.myProperty = 'Property on a function!';

Foo.myMethod = function() {
  console.log(Foo.myProperty);
  console.log('Method on a function!');
};

Build jQuery

Build each of the following jQuery functions on your own using the native JavaScript DOM methods and properties. It will be a scavenger hunt through these methods and properties to find the correct ones to use for each case.

The Core Basics

  1. Build the jQuery() function (Docs), which takes a string representing a CSS selector and returns a collection of elements (or the single element) that match it. Add the following functionality: Note: assume only single selectors and not chained or nested ones like ".some-class someElement"
    1. Classes, e.g. jQuery(".some-class")
    2. IDs, e.g. jQuery("#some-id")
    3. Elements, e.g. jQuery("div")
  2. Make this function available when your page loads so you can play with it in the console.
  3. Make your jQuery() function return a jQuery object which contains your collection and any methods you want to run on it (see the warm up again for a hint on how). Read this description of jQuery's object). You will add properties and methods to this object shortly.

    1. It's okay for the object's collection to be empty.
    2. You'll need to implement a few simple array-like methods and properties on this object which treat it almost like an array but which really operate on the collection contained inside it, for instance length:

      var myQuery = jQuery(".some-class")
      myQuery.length
      //=> 5
      
    3. Allow indexing into this collection inside your object by using a new method called idx() which approximates the functionality of standard array indexing using brackets ([]) but returns the raw DOM object:

      var myQuery = jQuery(".some-class")
      myQuery.idx(0)
      //=> <div class="some-class">Text here</div>
      
  4. Allow your jQuery() function to take a DOM node as an input instead of a string. Passing a single DOM node to your jQuery object should result in its collection being an array with a single element. That element should be the passed DOM node.

    // Assume there's a `<div id="some-id"></div>`
    //   somewhere in the DOM for this example
    var someDiv = document.getElementById("some-id")
    var myQuery = jQuery(someDiv)
    myQuery.length
    //=> 1
    myQuery.idx(0)
    //=> <div id="some-id"></div>
    
  5. Alias your jQuery() function as $().

Full Featured Functionality

Now it's time to allow users to get and set the properties of a particular element or collection of elements by writing the methods below on your jQuery object. You will first need to build in jQuery's "implicit iteration" functionality so the methods get run on the whole collection.

Many of these are both a getter (no arguments) and a setter (with arguments). The "getter" typically works on the first (or only) element in the collection while the "setter" usually works on the whole collection of elements. Note that many of these methods should return a jQuery object so they can be chained together.

Don't use querySelector for any of this

  1. hasClass() (Docs)
  2. addClass() (Docs)
  3. removeClass() (Docs)
  4. toggleClass() (Docs)
  5. val() (Docs) Getter & Setter
  6. css() (Docs) Getter & Setter
  7. height() (Docs) Getter & Setter
  8. width() (Docs) Getter & Setter
  9. attr() (Docs) Getter & Setter
  10. html() (Docs) Getter & Setter

(Optional) Extensions

  1. Allow chaining of selectors in your original jQuery function, e.g. jQuery("div .some-class .some-other-class"). You may use the new querySelector method for this.

Finishing Up

  1. Commit, push, and submit a pull request back to the main repo
Pull request 300 Octocat 300


Sign up to track your progress for free

There are ( ) additional resources for this lesson. Check them out!

There are no additional resources for this lesson just yet!

Sorry, comments aren't active just yet!

Next Lesson: The JavaScript Event Loop