Do events bubble all the way up before default behavior? And more.

by dimadima

HTML

<p>
  <a id="go-to-google" href="http://google.com">Go to Google</a>
</p>

CSS

#log {
    padding: 18px 16px 8px 18px;
    background-color: #d5d5d5;
    border-top: 2px solid #999;
    border-bottom: 2px solid #999;
    font-family: Consolas, monospace;
    font-size: 14px;
    line-height: 20px;
    list-style-type: none;
}
.log-entry {
    margin-bottom: 10px;
}
.timestamp, .message {
    display: block;
}
.message {
    margin-left: 110px;
}
.timestamp {
    float: left;
    background-color: #999;
    color: #fff;
    padding: 2px 7px 0px 7px;
    margin-right: 8px;
    margin-top: -2px;
}

JavaScript

$(function () {
    var llog = window.llog = function () {
        var $log = $('<ol id="log"></ol>').appendTo($('body'));
        var timestamp = function () {
            var now = new Date();
            var components = [now.getHours(), now.getMinutes(), now.getSeconds()];
            components.zero_pad = function(index, component) {
                this[index] = (this[index].toString().length == 1) ? ('0' + component) : component;
            }
            $.each(components, $.proxy(components.zero_pad, components));
            return '[' + components[0] + ':' + components[1] + ':' + components[2] + ']';
        };
        return {
            write: function (message) {
                $log.append($('<li class="log-entry"><span class="timestamp">' + timestamp() + '</span> <span class="message">' + message + '</span></li>'));
            }
        };
    }();
    llog.write('Ready to log.');
});

$.fn.depth = function() {
  return $(this).parents().length;
};

// =========================================================== //
// Q: Do events bubble all the way up before default behavior? //
// =========================================================== //

$(function() {
  // A decorator designed for event handlers. Allows specifying 
  // preventDefault() and bubbling propogation behavior without  
  // modifying the handler.
  var decorator_maker = function(prevent_default, stop_bubbling) { 

    var decorator = function(func) {
   
      var wrapped = function(e) {
        // The event handler.
        func(e);
        // preventDefault() and bubbling behavior
        prevent_default && e.preventDefault();
   
        return !stop_bubbling;
      };
   
      return wrapped;
    };
   
    return decorator;
  };

  // The event handler. 
  var depth_logger = function(e) {
    llog.write('Current depth: ' + $(this).depth());
  };

  // Event bindings. Pass two `true` or `false` params to 
  // `decorator_maker` to determine behavior.
 ...