Home

jQuery & Famo.us

You already know jQuery is a cornerstone of frontend web development: It’s used on millions of websites by developers who enjoy its fast, easy-to-use methods for manipulating web pages. But you might not know that jQuery and Famo.us play together well.

This section covers techniques for using jQuery with Famo.us. If you’re looking for information on how to learn jQuery itself, visit the jQuery learning center.

When to use jQuery with Famo.us

Before you decide include the jQuery library within your Famo.us project, spend some time carefully thinking about why exactly you need it.

The area where jQuery shines brightest is its concise, powerful methods for DOM manipulation, but since Famo.us endorses avoiding touching the DOM at all, using the libraries together poses a risk of deoptimization. Ask yourself whether you can achieve your goals in Famo.us alone, without touching the DOM. If you think you will need to manipulate the DOM no matter what, jQuery could be a great addition. Here are a few rules of thumb:

Good reasons to use jQuery with Famo.us:

Bad reasons to use jQuery with Famo.us:

Including jQuery in your Famo.us project

You should be able to use jQuery within your Famo.us project right out of the box, without any additional wiring-up. Simply link to the jQuery library from your within main HTML file, e.g.:

<script src="//code.jquery.com/jquery-migrate-2.1.1.min.js"></script>

jQuery is available in a variety of different formats (Bower, CDN links); see the jQuery downlod page for more options.

Manipulating DOM elements not controlled by Famo.us

If you want to use jQuery to manipulate elements on the page that are not directly controlled by Famo.us, you can use jQuery normally, without needing to add any special handling code for Famo.us. jQuery will retrieve the elements you select without interfering with the Famo.us rendering engine.

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group A
// @famous-block-option preset famous-0.3.0-globals-jquery
// @famous-block-filename main.js
var Engine = famous.core.Engine;
// Famo.us stuff goes here.
// Etc.

// Elsewhere, we can use jQuery.
$('p').addClass('blue');
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group A
// @famous-block-filename main.html
<div>
  <p>jQuery</p>
  <p>&</p>
  <p>Famo.us</p>
  <p>Rock!</p>
</div>
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group A
// @famous-block-filename main.css
.blue {
  color: cyan;
}

Manipulating elements within Famo.us surfaces

One thing you might want to do with jQuery within a Famo.us app is to select elements contained within surfaces and change them in some way — say, by reordering them, or changing all of their class names. For example, suppose we had a surface whose content was an unordered list (<ul>) element. If we needed to toggle a class on all of those list elements, and then sort the items in the list, jQuery can be a great tool for the job.

Surfaces aren’t inserted into the DOM right when they are instantiated; the Famo.us Engine decides whether to insert each surface into the DOM as part of its main rendering loop. Because of this, we can’t be sure exactly when the surface content will be present in the DOM in order to be successfully selected by jQuery. Fortunately, every Surface instance emits a 'deploy' event when it has been inserted into the DOM. We can use a callback to trigger our jQuery code at the appropriate time.

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group B
// @famous-block-option preset famous-0.3.0-globals-jquery
// @famous-block-filename main.js
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var Modifier = famous.core.Modifier;

var context = Engine.createContext();

var surface = new Surface({
  content: '<ul class="list"><li>Peach</li><li>Apple</li><li>Orange</li><li>Banana</li><li>Plum</li><li>Pear</li></ul>',
  properties: {
    backgroundColor: '#fa5c4f'
  }
});

surface.on('deploy', function() {
  var $list = $('.list');
  var $items = $list.find('li');

  $items.addClass('blue');

  var $sorted = $items.sort(function(a, b) {
    var aText = $(a).text();
    var bText = $(b).text();
    return aText > bText;
  });

  $list.append($sorted);
});

var modifier = new Modifier({
  size: [250, 250],
  align: [0.5, 0.5],
  origin: [0.5, 0.5]
});

context.add(modifier).add(surface);
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group B
// @famous-block-filename main.css
.blue {
  color: cyan;
}

Important: Note that a surface instance may emit a 'deploy' event multiple times, because the Famo.us Engine may recycle its respective <div> element for use with other instances, and then reinsert it at a later point. For finer-grained control of jQuery within that lifecycle, you may also wish to listen to a surface’s 'recall' event, which is fired when the surface instance is removed from the DOM.

Manipulating surfaces

We can also use jQuery to select and modify Famo.us surfaces directly. All surfaces have the class famous-surface, which we can select with jQuery in order to manipulate them directly. We can also assign a class to the surface when we instantiate it and select that. Suppose, for example, that we wanted to insert content into the surface once data has been loaded from the server:

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group C
// @famous-block-option preset famous-0.3.0-globals-jquery
// @famous-block-filename main.js
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var Modifier = famous.core.Modifier;

var context = Engine.createContext();

var surface = new Surface({
  classes: ['data-surface'],
  properties: {
    backgroundColor: '#fa5c4f'
  }
});

// A simple AJAX call, for demonstration purposes
$.ajax({
  url: '#',
  type: 'GET',
  success: function() {
    surface.setContent('Data has loaded!');
  }
});

var modifier = new Modifier({
  size: [250, 250],
  align: [0.5, 0.5],
  origin: [0.5, 0.5]
});

context.add(modifier).add(surface);

The right tool for the job

Ultimately, whether you choose to use jQuery with your Famo.us project is entirely up to you: The two are perfectly compatible. The question to ask is whether jQuery (or Famo.us) is the right tool for the job you’re doing. When used properly, jQuery and Famo.us can work great together. Just keep the pitfalls in mind, and always stop to think about what the best approach to a problem is. If you have suggestions for great ways to integrate jQuery with Famo.us, we’d love to hear about them.