Understanding throttling and debouncing of functions in JavaScript

Throttling and debouncing are arguably two concepts too often overlooked in front end development, even though they’re quite simple to grasp and bring major benefits when developing complex and/or intensive web applications.

Theory

Throttling and debouncing function calls basically prevent functions to be executed too many times in a specified time interval. More specifically:

  • Throttle will queue and execute functions calls at most once per given milliseconds
  • Debounce will execute the function once and filter all following calls until a given time has passed, then fire it again.

If you’re more a visual person, check out this interactive example to get how they work.

Ok, but when should I use them?

Throttling and debouncing are particularly useful when you need to listen (and react) to events that fire a lot of times, rapidly – think of a window resize, or a page scroll. If you try to attach a console.log() handler to one of those two events and fire them, you might have something like that:

image

That’s a lot of logs, right? Imagine if our handler function had to calculate different elements’ positions and had to move stuff around at the same time. Now, put this in the context of a heavy-interactive web application and your lag is served!

Enter throttle and debounce

That’s a perfect use case for some good ol’ throttling. 

The most famous implementation of the two is probably the Underscore.js one, which we’re going to use in our small example.

Its syntax is quite simple (from the Underscore.js docs): 

_.throttle(function, wait, [options])

Let’s put it in practice!

A _.throttle example

Our console.log() handler could be like this:

var i = 0;
var handler = function() {
  console.log('Scroll event fired ' + i + ' times!');
  i++;
}

We’ll pass it as an argument to the _.throttle function, so that it will return our new, throttled handler: 

var throttledHandler = _.throttle(handler, 500);

Now, some jQuery sugar to listen for the scroll event and fire it:

$(window).on('scroll', throttledHandler);

Et voilà, less lag and a better approach to intensive Javascript application development:

image

You can see how our throttled handler function now fires at most once every 500ms.

If you’re interested in how throttling and debouncing work internally, take a look at the annotated source code provided by the Underscore.js pals!

Media keys not working on Mac OSX? This might be the solution

If you’re on a Macintosh and your media keys (play/forward/rewind) are not working, don’t panic! There could be a simple solution.

First, if none of your upper keyboard controls are working (screen brightness, key brightness, volume, etc.), then this tip might not help you – your Mac might be experiencing some hardware issues.

If this isn’t the case, well, go ahed and give it a try!

It’s not iTunes

Your problem might be the Google Play Music Chrome Extension.

The extension that you might have installed after having visited the Google Play Music website overwrites the key bindings on your system, preventing any other application to use them (iTunes, VLC, or any other media player that uses them). What now?

It’s in the preferences

First, open the Settings from the top right menu:

Then, click on the “Extensions” section on the left side:

After that, you should scroll all the way down, where you’ll see a link in the bottom right section. Click on it:

A modal will pop up with a comprehensive list with all the applications that use keyboard shortcuts. You’ll see that the Google Play Music extension has our precious media keys binded to it. Click on the small cross at the right of the four labels and then click Ok.

Et voilà! We can take control on our iTunes library once again.

Barebon, a minimal prototyping framework based on Bourbon and Neat

Say hello to the first, unpolished version of Barebon!

Barebon is a simple skeleton boilerplate for fast static page prototyping. It provides a friendly environment for front-end developers who love Sass and CoffeeScript. It also comes with a super-easy Grunt configuration that helps you to start hacking on your project right away.

Why?

Legit question! I absolutely love and use HTML5 boilerplate and Yeoman, but when it comes to super-simple static pages prototyping they’re just… overkill. I just wanted a neat, easy “framework" for these kinds of websites.

Since I’ve been enjoying Bourbon and Neat for a while I’ve decided to give it a try and make something focused on that. I liked it, so I thought I could share it with teh internetz.

How easy is it?

VERY easy. If you already have npm and grunt-cli installed, you just need to fork the repo, get in the folder and run $ npm install. When done, you just need to spawn the grunt watcher (that includes a Livereload feature), and you can start hacking on your code! 

Gimme dat repository link already!

Ok, ok! You can find Barebon on Github. Feel free to give it a try – any feedback is obviously appreciated!

Facebook share buttons and history.pushState()

If you’ve ever tried to use Facebook social plugins‘ latest version in your website, you might have noticed how smooth and streamlined is now the embedding process.

Select a button type, include the SDK, copy-paste a snippet of code and… you’re done! You can also leave the data-href attribute blank, so the plugin will like/share the current page. Awesome!

At this point you might ask yourself, “Well, will this nice little button work with my super cool AJAX-powered app?”. The answer is not really.

The problem

Facebook social plugins won’t work properly when your application routing is based on Javascript’s history.pushState() API – this includes a large number of Rails applications that rely on Turbolinks for their navigation.

This is because the page metadata is parsed by Facebook SDK only when a full page load is triggered. So, if I navigate from example.com/page-one to example.com/page-two and try to click on my Facebook share button, it will prompt a share for /page-one.

The solution

How to solve this? It’s actually quite easy. A small snippet (here in CoffeeScript, but easily convertible in plain JavaScript) that will update our button and retrigger a parse will be enough:

updateFbButtonHref = (el) ->
  $fbButton = $(el).find('.fb-share-button')
  $fbButton.attr('data-href', window.location.href)

  FB.XFBML.parse()

Now, we can bind this function to the “page:load” event (in the case of a Turbolinks application), or generally after every pushState():


$(document).on 'page:load', ->
  updateFbButtonHref('.my-fb-button-container')

And we’re cool! Our button will now share the correct page.

Replicating the deprecated jQuery property .selector in CoffeeScript

Recently I found myself needing a way to get any (id or class) selector from any DOM element as a string in an easy way. 

After a quick search I discovered that jQuery had an handy .selector property that would have been a perfect fit for my needs.

Unluckily, it was deprecated in version 1.7.

image

I felt like the solution suggested by the guys at jQuery wasn’t flexible enough and not very user-friendly – passing the element selector as a parameter of the plugin method call is definitely not an elegant way to deal with the problem.

So I tried to write a simple function to solve it… in CoffeeScript!

The snippet

getSelector = (el) ->
  firstClass = $(el).attr('class')?.split(' ')[0]
  elId       = $(el).attr('id')

  if (elId isnt undefined) then "##{elId}" else ".#{firstClass}"

As you can see, it’s really easy to understand: it just checks if there’s an id attribute and returns it as a string. If it’s undefined, it returns the first class instead.

Here you can see it in action in a CodePen example.

I could write it in a single line without the two variables declaration, but I wanted to get the most out of the beautiful human-friendly CoffeeScript syntax, and I think it actually makes the snippet a lot more readable.

More jQuery pls

If you wanted to, you could also extend jQuery itself adding this little function as a method in a very easy way:

jQuery.fn.extend(
  getSelector: ->
    firstClass = $(this).attr('class')?.split(' ')[0]
    elId       = $(this).attr('id')

    if (elId isnt undefined) then "##{elId}" else ".#{firstClass}"
)

And then use it like that:


$ ->
  mySelector = $('div').getSelector()

Hope that helped you!

Using SVG gradient masks with D3.js

If you’re reading this you’ll probably know what D3.js is. For anyone that doesn’t, D3.js is a great piece of JavaScript software that allows you to do some pretty awesome stuff – generally involving tons of data. It makes great use of HTML, SVG and CSS – nothing more. Neat, right?

The majority of D3.js use cases will obviously involve data representation. But what is data representation without some eyecandy goodness? You need that!

Well, in our last project we extensively used D3.js to show a lot of data, but we also needed some related graphic elements that users could zoom in and out without losing render quality or look weird. So, we decided to implement these directly in our SVG, using our beloved D3.js.

The design

Our design looked something like that (a picture is worth a thousand words):

image

It was clear we needed some sweet gradient masking using SVGs. So, how could we do that? It turned out it’s very simple.

The solution

Starting from a placeholder div for our SVG (let’s say with the id ‘svg-container’), we appended the two necessary elements for our mask in a <defs> tag inside the SVG: the vertical gradient (alpha-opaque-alpha) and the actual mask.

// Handy vars for our banner dimensions
var bannerWidth  = 1500,
    bannerHeight = 500;

// Let's append the SVG element.
d3.select('#svg-container')
    .append('svg:svg').attr('class', 'my-supah-svg')
    .append('svg:defs')
    .call(function (defs) {
      // Appending the gradient
      defs.append('svg:linearGradient')
        .attr('x1', '0')
        .attr('x2', '0')
        .attr('y1', '0')
        .attr('y2', '1')
        .attr('id', 'supah-gradient')
        .call(function (gradient) {
          gradient.append('svg:stop')
            .attr('offset', '0%')
            .attr('stop-color', 'white')
            .attr('stop-opacity', '0');
          gradient.append('svg:stop')
            .attr('offset', '50%')
            .attr('stop-color', 'white')
            .attr('stop-opacity', '1');
          gradient.append('svg:stop')
            .attr('offset', '100%')
            .attr('stop-color', 'white')
            .attr('stop-opacity', '0');
        });
      // Appending the mask
      defs.append('svg:mask')
        .attr('id', 'gradient-mask')
        .attr('width', bannerWidth)
        .attr('height', bannerHeight)
        .attr('x', 0)
        .attr('y', 0)
        // This is the rect that will actually
        // do the gradient masking job: as you can see it's
        // filled with the linear gradient.
        .call(function(mask) {
          mask.append('svg:rect')
            .attr('width', bannerWidth)
            .attr('height', bannerHeight)
            .attr('fill', 'url(#supah-gradient)')
        });
    })

These two elements formed our mask element. We just needed to apply it on our desired element – below there’s an example <rect> element with our mask on:

// Masking on a rect filled with a solid color
d3.select('.my-supah-svg').append('svg:rect')
  .attr('class', 'final-rect')
  .attr('width', bannerWidth)
  .attr('height', bannerHeight)
  .attr('x', 0)
  .attr('y', 0)
  .attr('fill', 'salmon')
  .attr('mask', 'url(#gradient-mask)');

We also needed to apply the masking on image elements – here’s another example for it:

// Masking on an actual image
d3.select('.my-supah-svg').append('svg:image')
  .attr('class', 'final-bg')
  .attr('xlink:href', 'http://lorempixel.com/output/technics-q-g-1500-500-4.jpg')
  .attr('width', bannerWidth)
  .attr('height', bannerHeight)
  .attr('x', 0)
  .attr('y', 0)
  .attr('mask', 'url(#gradient-mask)');

Easy peasy!

Just a little heads up: the mask element must have the same dimensions and position of the element being applied on. In our examples we set it to a fixed width/height and a 0 X/Y.

Conclusion

D3.js is a great, fun tool that can also be used for presentational purposes other than for serious and austere data graphs. Have fun!

Oh, and here you have the interactive demo on codepen!

How to build a super-simple, clean CSS sticky footer

Sticky footers, although being a simple concept, have always been a pain to implement in plain CSS.

Lately I had to build one for a project here in Mikamai, and I found myself using a technique I realized not everyone knows.

It boils down to these few lines of CSS code:

html
    min-height: 100%
    position: relative
    
body
    margin-bottom: 50px
    
footer
    width: 100%
    height: 50px
    position: absolute
    left: 0
    bottom: 0

And a basic page markup:

body
    Meaningful content.
    
    footer
        Yay, I'm sticky!

Neat, right?

You’re basically giving the body some extra “space” (via a bottom margin) in which you’ll later position your footer absolutely. So, as you can see, the bottom margin on the body equals to your footer’s height. 

If you’re using any CSS preprocessors, you could further improve this piece of code, storing your footer height in a variable. This way, when you’ll need to edit your footer you just need to change a single value (ideally in a separated var.scss file).

Have fun!

Tendina, a super-simple jQuery plugin for dropdown side menus

I have just released the first beta version of my jQuery plugin Tendina.

image

Tendina is a easy-to-use jQuery plugin to rapidly build dropdown side menus.

Its usage is very simple and straightforward: you just need a basic unordered list menu markup and a link to jQuery and the plugin. For example:

    
<body>
<ul class="dropdown">
<li>
<a href="#">Menu 1</a>
<ul>
<li><a href="#">Submenu 1</a></li>
</ul>
</li>
<li>
<a href="#">Menu 2</a>
<ul>
<li><a href="#">Submenu 2</a></li>
<li><a href="#">Submenu 2</a></li>
<li><a href="#">Submenu 2</a></li>
</ul>
</li>
<li>
<a href="#">Menu 3</a>
<ul>
<li><a href="#">Submenu 3</a></li>
<li><a href="#">Submenu 3</a></li>
</ul>
</li>
</ul>

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="../tendina.js"></script>
<script>
$('.dropdown').tendina()
</script>
</body>

As you can see, you just need to call the function on your elements and… That’s it! The plugin will handle all the interactions and leave all the styling to you, so you don’t have to override useless CSS classes.

Tendina will also work on dinamically appended elements, and additionally add a “selected” class to expanded elements.

Check it out on Github or on this demo CodePen!