O'Reilly

SnackJS: A Tiny-But-Tasty JavaScript Framework

By on  
Snack JS

moo4q creator Ryan Florence and I generally agree on most JavaScript-related topics, one of which is that most JavaScript frameworks, jQuery, MooTools, and Dojo included, are much more feature-rich (and thus larger) than most websites need.  You wouldn't build a corporate or enterprise-level website without an expansive JavaScript framework, but many smaller scale websites simply don't need the heft.  Enter Florence's new JavaScript framework, SnackJS -- a JavaScript framework that provides only the functionality that most smaller websites need -- and in only 3KB! (minified and gzipped)

What does "only the functionality that most smaller websites need" mean?  By that I mean the ability to:

  • more easily work with arrays
  • efficiently retrieve and modify element CSS classes and attributes, etc.
  • easily add, remove, and fire event handlers
  • execute and handle the result of basic AJAX / JSON / JSONP request

SnackJS provides all of the above, with a few extras:

  • a small pub/sub system for easier app communication
  • an extend method for shallow merging of object properties
  • everyone's favorite: a "ready" event
  • a selector engine wrapper for easy implementation of any selector engine (Slick, Sizzle, etc.)
  • a punch method which acts very much like dojo.connect, in that a function can be assigned to execute any time another function is executed
  • an element store solution

Let's take a look SnackJS code snippets so you can get a feel for it usage!

snack.extend

This method simply merges properties from any number of objects into the first argument:

// Mix objects
var endObject = {
	color: "red"
};
snack.extend(
	endObject, // The starting object
	{ color: "green", text: "Name" }, // A second object
	{ color: "blue" } // And another
);

// endObject becomes: { color: "blue", "text: "Name" }

snack.punch

The ability to "connect" to functions is extremely useful within the Dojo Toolkit, so I couldn't have been more happy to see this in SnackJS:

// Create an object with a function
var myObjectWithFns = {
	color: "red",
	onColorChange: function(color) {
		// Reset the color
		this.color = color;
	}
};

// Punch time:  whenever myObjectWithFns is called, call another function which simple logs the value
var reactor = function(color) {
	console.log("The color was just changed to: ",color);
};
snack.punch(myObjectWithFns,"onColorChange",reactor,true);
myObjectWithFns.onColorChange("red");

Whenever the myObjectWithFn.onColorChange is executed, the reactor function immediately runs.

snack.wrap

snack.wrap acts very similar to the dojo.query method or jQuery("selector") usage in that it wraps nodes so extra functionality can be added to them. Nodes themselves are not modified as they are within MooTools.

// Get all DIV elements.
var divs = snack.wrap("div");
// Add a CSS class to the divs
divs.addClass("found");
// Add a click event that...
divs.attach("click",function() {
	// Removes the class we added
	snack.wrap(this).removeClass("found");
});

snack.listener

The snack.listener method is your standard cross-browser node event syntax.

// Add an event listener to a given node
var listener = snack.listener({
	node: document.getElementById("content"),
	event: "click"
},function() {
	console.warn("You clicked on the node!");
});

// Detach the listener at any time
listener.detach();

// ...and add it back again
listener.attach();

Especially nice are the detach and attach methods, allowing you to effectively disable and enable event listeners.

snack.request

Runs a standard AJAX request with the standard options:

// Create an AJAX request
var req = snack.request({
	url: "get-user-bio.php",
	data: {
		userId: 1234
	},
	method: "get",
	now: false // Don't send immediately
},function(error,response){ // The success event
	// If it was successful...
	if(!error) {
		document.getElementById("content").innerHTML = response;
	}
});

// Now send it!
req.send();

snack.publisher: PubSub Implementation

SnackJS implements the ever-useful pub/sub system by creating a publisher, and then publishing and subscribing to it:

// Set up a pub/sub event
var pubsub = snack.publisher();

// Create a subscription to an event
pubsub.subscribe("inputchange",function(val) {
	console.warn("The value was changed to: ",val);
});

// Attach an onKeyUp event to the input node
// When keyup'd, the node's value has changed, and we should notify all subscribers
snack.wrap("#email").attach("keyup",function() {
	pubsub.publish("inputchange",[this.value]);
});

The power of pub/sub is that you don't need references to events or anything else -- you simply need the name of the wire. Whenever a message is published to that wire, you'll know about it!

These are just a few of the functionalities available within SnackJS.  There are many more methods available, so I encourage you to check out the SnackJS documentation. I'll bet that SnackJS has all the functionality you need for most websites!

Moving Forward

Snack JS was just recently released so there aren't many custom modules/plugins available.  There are a few items I'd like added to see added to SnackJS:

  • style setter and getter -- I know that the style property of nodes is where you set individual styles, but opacity takes more work since it's not standard, and an object-to-styles setter would be awesome
  • deferreds -- They're a godsend within Dojo, and could prove to be with SnackJS as well

The SnackJS repository lives at GitHub and the documentation and demos can be found at snackjs.com.  Congratulations to Ryan Florence for this awesome micro framework!  I look forward to contributing in the future!

In the coming days, I'll be showing you how you can create your own SnackJS plugin for creating nodes, placing them within the page, and getting and setting their attributes! Stay tuned!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

  • How to Create a Twitter Card

    One of my favorite social APIs was the Open Graph API adopted by Facebook.  Adding just a few META tags to each page allowed links to my article to be styled and presented the way I wanted them to, giving me a bit of control...

  • Send Text Messages with PHP

    Kids these days, I tell ya.  All they care about is the technology.  The video games.  The bottled water.  Oh, and the texting, always the texting.  Back in my day, all we had was...OK, I had all of these things too.  But I still don't get...

Incredible Demos

Discussion

  1. This will be super handy. There are a lot of sites I modify that just use those core functions and 3kb is a ton smaller than jQuery or MooTools.

    Thanks for the share!

  2. Wow, that little framework looks handy. I’m content with learning MooTools because I like it and it’s capability of handling anything, but if I need something really small or just want to learn something knew, I’ll look into this.

  3. Talk about good timing. I am working on a site that only requires a twitter feed through a json request! this is perfect for the job!

    • If all you are doing is a single ajax request, you should probably just use pure javascript. There is no need for a framework if you only are running a few lines.

      Here is a link if you are interested.
      http://www.w3schools.com/ajax/default.asp

    • alpha123

      You might want to check out http://w3fools.com/

    • He’ll probably need at least an event handler as well to trigger the request. Also, it’s not an AJAX request, since you can’t do cross-domain xhr, it’s JSONP.

      All that said, I whole heartedly encourage people to check out snack’s source and pull out only the tiny pieces they need, it’s also delete key friendly :)

  4. What’s the difference between Snack and a more stripped down JavaScript framework like DOM Assistant? (and DOM Assistant works with the ultra-useful Selectivizr)

  5. alpha123

    Interestingly enough, I just finished something like this, called Shrike (GitHub). It’s about 5.5KB gzipped though, so Snack is lighter. Shrike’s documentation is still missing, and the event system is definitely less cool than Snack’s, but it’s pretty neat if you need a lightweight JavaScript framework.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...

  • Create Any Type Of Website With These Multi-Purpose Themes

    We have selected what we believe are the very best multipurpose WordPress themes on the market today. Our list contains a number of best sellers, several newcomers that are proving to be highly popular, and a few themes that are ideal for creating the types of...

  • An Introduction to Static Site Generators

    Static site generators seem to have been becoming more and more popular recently, but they’re not one of those ephemeral novelty things that grow in popularity as quickly as they fall into oblivion shortly after. For over a decade, many different projects — 394 of...

  • Automated Tests for Visual Responsive Layouts

    Today it's all about testing. In 2015, many developers knows about TDD and I personally think that testing is one of the key for quality products. But what about testing in a Front-end environment? How do you guys write your tests for a responsive page or...

  • Getting Dicey With Flexbox

    What if you could build complex CSS layouts in minutes? Flexbox is a new CSS layout spec that makes it easy to construct dynamic layouts. With flexbox, vertical centering, same-height columns, reordering, and direction agnosticism are a piece of cake. There's a popular myth floating around that...