jQuery special events

Custom destroy event http://benalman.com/news/2010/03/jquery-special-events/

by billjohnston4

HTML

<h1>
    <a href="http://benalman.com/news/2010/03/jquery-special-events/" target="_top">jQuery special events</a>
    &raquo; Custom destroy event
</h1>

<p class="intro">(widgets must be closed in order)</p>

<div class="widget">
    <div class="widget-head">
        <h2>First widget</h2>
        <a href="#" class="close">X</a>
    </div>
    <div class="widget-body">
        <p>
            This example illustrates one way in which the jQuery special event <code>_default</code> method can be used.
        </p>
    </div>
</div>

<div class="widget">
    <div class="widget-head">
        <h2>Second widget</h2>
        <a href="#" class="close">X</a>
    </div>
    <div class="widget-body">
        <p>
            When our special 'destroy' event is triggered, if the event's default action is not prevented, the element it was triggered on will be removed from the DOM.
        </p>
    </div>
</div>

<div class="widget">
    <div class="widget-head">
        <h2>Third widget</h2>
        <a href="#" class="close">X</a>
    </div>
    <div class="widget-body">
        <p>
            While the framework code determines what happens when the event is triggered, the implementation-specific code supplies the logic for deciding when that default behavior should be prevented.
        </p>
    </div>
</div>

<div class="widget">
    <div class="widget-head">
        <h2>Fourth widget</h2>
        <a href="#" class="close">X</a>
    </div>
    <div class="widget-body">
        <p>
            This approach allows framework and plugin developers to further abstract the internals of their events from end-users, which allows special events to behave more like native events, and can result in more organized code!
        </p>
    </div>
</div>

CSS

body { font-family: Arial, Helvetica, sans-serif; font-size: 0.8em; }
h1, h2 { font-weight: 700; font-family: "Gill Sans", "Gill Sans MT", Arial, Helvetica, sans-serif; }
h1, a { color: #913D00; }
a:hover { color: #FF7F00; }
h1 { font-size: 120%; margin-bottom: 0.6em; }
.intro { font-style: italic; margin: 0.5em 0 1em; }

.widget {
    border: 2px solid #C4884F;
    background: #FDEBDC;
    margin-bottom: 0.6em;
    position: relative;
}

.widget .close {
    position: absolute;
    top: 0.2em;
    right: 0.5em;
    line-height: 0.9em;
    padding: 0.1em;
    font-weight: 700;
    color: #C4884F;
    background: #FDEBDC;
    border: 1px solid #C4884F;
    text-decoration: none;
}

.widget .close:hover {
    color: #fff;
    background: #f00;
    border-color: #fff;
}

.widget-head,
.widget-body {
    padding: 0.2em 0.5em;
}

.widget-head {
    color: #fff;
    background: #C4884F;
}

.widget h2 {
    font-size: 120%;
    font-weight: 700;
}

JavaScript

//////////////////////////////////////////////////
// THE FOLLOWING CODE IS TAKEN FROM THE EXAMPLE //
//////////////////////////////////////////////////

// The framework code
(function($){
  
  // When the 'destroy' event is triggered on an element, that element will
  // be removed from the DOM, unless prevented with event.preventDefault().
  $.event.special.destroy = {
    _default: function(event){
      $(event.target).remove();
    }
  };
  
})(jQuery);

// The implementation-specific code
$(function(){
  
  // Handle the 'destroy' event for each widget.
  $('.widget').bind( 'destroy', function(event){
    
    // Only allow the widget to be destroyed if it isn't preceded by any
    // other widgets.
    if ( $(this).prevAll('.widget').length ) {
      
      // Note that the 'heavy lifting' of removing the element is done
      // in the framework, thus abstracting away the internals from the
      // user. All they need to do is prevent it, or not.
      event.preventDefault();
      
      // An implementation-specific error message.
      alert( 'Widgets must be closed in order!' );
    }
  });
  
  // When an 'X' close link is clicked, trigger the 'destroy' event for
  // that widget.
  $('.widget .close').bind( 'click', function(event){
    $(this).closest('.widget').trigger('destroy');
  });
  
});