jKonami plugin

Proudly present: jKonami plugin for jQuery!!

This plugin allows you to conveniently bind your own function in the case user is inputting konami code (up,up,down,down,left,right,left,right,b,a). You may put cool effects, or beautify (what my project manager frequently say), or even cornify, etc. It’s really up to your imagination.

Background: I was quite bored in the office, and suddenly reminded of this well-known cheat code. So I decided to make a jQuery plugin for it. The code is based on an article by Paul Irish. The time taken to work on this plugin is, in my opinion, one of the most productive hours in my life :D

Installation

Below is an example on installation using jQuery 1.4.2

<head>
    <script type="text/javascript" src="jquery-1.4.2.js" > </script>
    <script type="text/javascript" src="jquery.jkonami-1.0.1.js" > </script>
</head> 

HOW TO USE

$.jkonami([timeoutMillis,] callback);
  • timeoutMillis (optional) is how long does the delay whenever a key is pressed before timeout. When it’s not set, or value is zero, the timer will not run.
  • callback is your callback function

Here’s an example on how to use this plugin.

$(document).ready(function(){
   //show an alert whenever user succesfully enter konami code
   //timeout is set to 1000ms for each keystroke
   $.jkonami(1000, function(){
      alert('jkonami version: '+$.jkonami.version);
   });
});
Posted in javascript, jQuery | Tagged | Leave a comment

Event delegation with jQuery

Disclaimer: I will assume that readers know some basic JavaScript  http://www.w3schools.com/js/default.asp) and a bit of jQuery knowledge as well (Getting Started with jQuery – can be found at http://docs.jquery.com/Tutorials)

What is event delegation? to understand this, one needs to know a JavaScript feature called event bubbling in DOM. Quick explanation, when user trigger an event on an element in a page, a click for example. The action will trigger the same type of event (click event) for that element’s ancestor nodes.

A brief example. If we have a chunk of HTML code as shown below.

<table>
  <tbody>
    <tr>
      <td>
        <input type="button"/>
      </td>
    </tr>
  </tbody>
</table>

When user clicks on <input type=”button”/>,  browser would run event handler for event type click which is bound to <input type=”button”/>. Then it will run event handler for the same event type which is bound to its ancestors in this order: <td><tr><tbody><table> – etc. To know more of event bubbling, quirk’s blog has a comprehensive explanation on the topic. http://www.quirksmode.org/js/events_order.html

Because of this feature, it’s possible for us to bind an event handler to a parent node of a target element instead of bind directly to that target element. This is what we call event delegation.

Why would we want to do event delegation? Consider this scenario where we need to add new elements dynamically, and each of these elements need to behave in a same fashion.

Though it seems natural, one might be tempted to use jQuery selector to encapsule all the dynamically-added elements and then bind it to a function. The bad news is: all elements added after executing the bind will not have the function event handler to be bound to them. One can simply solve the problem simply by binding function whenever a new element is added. Note that in this solution, event binding is executed  for every element.

Another possible solution is (as you might guess) to use event delegation. Since an event will bubble up to its ancestors, we can bind an event handler function to the nearest common ancestor of these dynamically-added elements. What function needs to do now is only to recognize what is the event’s target element and then execute an appropriate handler. Note that in this solution, event binding is done only once (to the common ancestor).

Example: When ‘add’ button is clicked, a new row is added. Clicking on a ‘remove’ text in a row will remove that particular row.

<input id="btn"type="button" value="add"/>
<table id="test">
 <tbody>
 </tbody>
</table>

First solution (without event delegation) :

$("#btn").click(function(){
  var newRow = $(
         "<tr><td><span class='removeRow'>remove</span></td></tr>"); 
//create new element
//for further explanation see jQuery(html, [owner document])
//documentation at http://api.jquery.com/jQuery/

  $("#test > tbody").append(newRow);
  newRow.find(".removeRow").click(function() {
    //using .closest(selector) would be more efficient if a long
    //ancestor traversal is needed.
    $(this).parent().parent().remove();
  });
});

Second solution (with event delegation):

$("#btn").click(function(){
  $("#test > tbody").append(
         "<tr><td><span class='removeRow'>remove</span></td></tr>");
});

$("#test").click(function(event) {
  var elem = $(event.target).closest(".removeRow"); 
//.closest() is used because user might click on a descendant
//element.
  elem.parent().parent().remove();
});

Since jQuery 1.3, event delegation can be easily done with .live() function. Hence we can omit the $(event.target).closest(…) part.

$("#btn").click(function(){
  $("#test > tbody").append(
         "<tr><td><span class='removeRow'>remove</span></td></tr>");
});

$(".removeRow").live("click", function() {
  $(this).parent().parent().remove();
});

As of jQuery 1.4.2, another useful method called .delegate() is added to jQuery library. It is more efficient than .live() because it allows user to select which DOM element should the event handler be bound to, as opposed to .live() which binds strictly to root DOM element.

$("#btn").click(function(){
  $("#test > tbody").append(
         "<tr><td><span class='removeRow'>remove</span></td></tr>");
});

$("#test").delegate(".removeRow", "click", function() {
  $(this).parent().parent().remove();
});

For further information on .live() and .delegate(), please read their respective documentations from jQuery’s official page (http://docs.jquery.com/Main_Page)

Warning

As mentioned before, event delegation relies on event bubbling in order to work. It doesn’t work for events that don’t bubble like focus, or blur. You may refer to http://en.wikipedia.org/wiki/DOM_events to see the whole list of events and their related information.

Notes: If you’re too lazy to setup your own HTML file + importing jQuery library, you may use online JavaScript debuggers e.g. http://jsfiddle.net/ or http://jsbin.com/

Posted in javascript, jQuery | Leave a comment

First post!

First post, yeah!!

Posted in Uncategorized | 1 Comment