Patrick Desjardins Blog
Patrick Desjardins picture from a conference

How to shake (or vide) a html element

Posted on: 2013-04-05

When your user does an error, it might be interesting to select the control and to make it shakes few seconds just to get the user attention. It's not something you should do for every validation but some time, you may cross a situation where the user might be more confuse about which controls or elements he needs to take care of. Therefore, a way to do it is to shake the element on the screen and highlight this one.

The code in this post is not into the form of JQuery plugin but it should be. It's more indented to be educational. The first part of the code show you that you need to call the method "Vibrate" that takes the element to shake as parameter.

var vibrateIndex = 0;
var selector; //Animate the selector with the animation function
function Vibrate(item) {
  selector = $(item);
  var interval = 10;
  var duration = 500;
  vibrateIndex = setInterval(Vibe, interval);
  setTimeout(StopVibration, duration);
}

The second part is doing the animation of shaking the control. In fact, we are randomly moving the left and top position of the control and setting this one relative. This is important. Otherwise, the control won't move. It also set the border to red.

//Animation
function Vibe() {
  var shake = 3;
  $(selector)
    .stop(true, false)
    .css({
      position: "relative",
      left: Math.round(Math.random() * shake) + "px",
      top: Math.round(Math.random() * shake) + "px",
      borderColor: "red",
    });
}

The last part is executed when the animation is over. This is called by the setTimout method previously set with a duration.

//Remove all CSS applied to the selector
function StopVibration() {
  clearInterval(vibrateIndex);
  $(selector).stop(true, false).css({
    position: "static",
    left: "0px",
    top: "0px",
    borderColor: "",
  });
}

This could be improved by having everything inside a JQuery plugin which would be cleaner. The problem with the code above is that we use global variable to remember to control that is implicated into the animation and the interval reference is also global.

You can see a working example here.

Plugin

Here is the JQuery Plugin version: http://jsfiddle.net/kEVd3/3/

(function ($) {
  $.fn.vibrate = function (options) {
    options = $.extend({}, $.fn.vibrate.defaultOptions, options);
    var control = $(this);
    var vibrateIndex = 0;
    var selector;
    vibrateIndex = setInterval(vibe, options.interval);
    setTimeout(stopVibration, options.duration);
    function vibe() {
      var shake = 3;
      $(control)
        .stop(true, false)
        .css({
          position: "relative",
          left: Math.round(Math.random() * shake) + "px",
          top: Math.round(Math.random() * shake) + "px",
          borderColor: "red",
        });
    }

    function stopVibration() {
      clearInterval(vibrateIndex);
      $(control)
        .stop(true, false)
        .css({ position: "static", left: "0px", top: "0px", borderColor: "" });
    }

    return this;
  };

  $.fn.vibrate.defaultOptions = { interval: 10, duration: 500 };
})(jQuery);

Here is an example of how to use it :

$("#btnShake").click(function () {
  $("input[type=text]").vibrate();
});

You can also specify option like the duration:

$("input[type=text]").vibrate({ duration: 3000 });

I'll do a post concerning how to create a JQuery plugin soon to explain in detail how and why the plugin has been created this way. For the moment, you can refer to this Microsoft's tutorial which is very fine.