Este plugin transforma un inocente span o div con dos contenedores de tipo inline dentro en un vistoso botón cuyos contenidos (primer contendor) aparece y desaparece al pasar el ratón sobre él. Soporta eventos y funciona!
Ahí va el jsFiddle de rigor y como siempre, si encuentras algún bug o lo mejoras, decídmelo, y si lo usas, cuéntamelo también, que al menos no tenga sensación de haber perdido el tiempo.
Ejemplo
Código javascript
/**
* jquery.slideButton-0.1.js - Slide Button plugin for jQuery
* ==========================================================
* (C) 2011 José Ramón Díaz - jrdiazweb@gmail.com
*
* http://3nibbles.blogspot.com/2011/07/plugin-jquery-sliding-buttons.html
*
* INSTANTIATION
* Any container with the .slideButton class will be initialized
* on domReady event using the options defined in object
* "slideButtonDefaults". This feature can be disabled by setting
* the variable "slideButtonAutoload" to the false value.
*
* Manual instantiation
* $('.slideButton').slideButton( [ options_object ] );
*
* OPTIONS
* - direction : 'left', Slide direction "left" = LtR, "right" = RtL
* - border : '3px', Border width == difference in height of control(>) and contents(<)
* - radius : '20px', Border radius of the slideButton
* - height : '36px', Maximum height of the slideButton. Includes all borders
* - width : '70px', Minimum width. Applied to control
* - deployedWidth: '225px', Maximum width. Applied to container and deployed contents
* - inAnimation : 'swing', Function used to deploy (slide in) the elements. For more functions needs the easing packs
* - outAnimation : 'swing', Function used to hide (slide out) the elements. For more functions needs the easing packs
* - inSpeed : 500, deploy effect duration
* - outSpeed : 300, hide effect duration
* - onClick : null, button click trigger callback function
* - onBlur : null, blur (slide out) trigger callback function
* - onDeploy : null, deploy (slide in) trigger callback function
* - onHide : null, hide (end of slide out) trigger callback function
*
* API
* - show() Deploys the sliding contents
* - hide() Hides the sliding contents
* - lock() Locks the sliding contents open
* - locked Indicates that the control is locked
* - deployed Indicates that the control is deployed
*
* CLASSES
* - Container: .slideButton, .deployed, .clicked
* - Button: .button
* - Content: .content
*
* HTML format
* *
* Valid HTML content and control containers are any inline element (a, span, etc...).
* Container must be div or span.
*
* Legal stuff
* You are free to use this code, but you must give credit and/or keep header intact.
* Please, tell me if you find it useful. An email will be enough.
* If you enhance this code or correct a bug, please, tell me.
*/
var slideButtonDefaults = {}; // The default options used for all auto loading sliding buttons
var slideButtonAutoload = true; // Enables the autoinstantiation feature for .slidingButton
(function( $ ) {
// Private members
function SlideButton( el, options ) {
this.container = $(el);
this.cA = null;
this.cB = null;
//this.el.attr('locked', 'off');
// States control
this.locked = false;
this.deployed = false;
// Default options
this.options = {
direction : 'right', // Slide direction "left" = LtR, "right" = RtL
border : '3px', // Border width == difference in height of control(>) and contents(<)
radius : '20px', // Border radius of the slideButton
height : '36px', // Maximum height of the slideButton. Includes all borders
width : '70px', // Minimum width. Applied to control
deployedWidth: '225px', // Maximum width. Applied to container and deployed contents
inAnimation : 'swing', // Function used to deploy (slide in) the elements. For more functions needs the easing packs
outAnimation : 'swing', // Function used to hide (slide out) the elements. For more functions needs the easing packs
inSpeed : 300, // deploy effect duration
outSpeed : 200, // hide effect duration
onClick : null, // button click trigger callback function
onBlur : null, // blur (slide out) trigger callback function
onDeploy : null, // deploy (slide in) trigger callback function
onHide : null, // hide (end of slide out) trigger callback function
};
slideButtonDefaults = this.options; // Sets the initial value of global default options
this.setOptions( options );
this.initialize();
}
// Instantiation
$.fn.slideButton = function( options ) {
return new SlideButton(this.get(0) || $('<span />') || $('<div />'), options);
};
// Public Members
SlideButton.prototype = {
// Plugin functions
killerFn: null,
initialize: function() {
var me, o, c, children, cA, cB, h1, h2, w1, w2, w3, r1, r2, b;
me = this;
o = me.options;
c = me.container;
// Sets objects and variables initial values
children = c.children();
cA = me.cA = $( children[0] );
cB = me.cB = $( children[1] );
// Widths and heights
b = parseInt(o.border); // Border
h1 = parseInt( o.height ) + 'px'; // Container/Contents height
h2 = ( parseInt( h1 ) - (b * 2) ) + 'px'; // Control height
w1 = parseInt( o.deployedWidth ) + 'px'; // Container and deployed width
w2 = parseInt( o.width ) + 'px'; // Contents width
w3 = ( parseInt( w2 ) - (b * 2) ) + 'px'; // Control width
r1 = parseInt( o.radius ) + 'px'; // External border radius
r2 = ( parseInt( o.radius ) - b ) + 'px'; // Internal border radius
// Container modifications
if( !c.hasClass('slideButton') ) me.container.addClass( 'slideButton' );
c.width( w1 );
c.height( h1 );
//me.container.height(o.height);
c.css({ 'position': 'relative', 'overflow': 'hidden' });
// Chidren modifications
cA.addClass( 'content' ); //o.direction + 'A content' );
cB.addClass( 'button' ); //o.direction + 'B button' );
// Wraps sliding contents into a span
var text = cA.get(0).innerHTML;
cA.get(0).innerHTML = '' + text + '';
cA.find('span:first-child').hide();
// Sets styles
c.data( 'initialWidth', w1 ); // Stores the initial width in container data
cA.width( w2 );
cB.width( w3 );
cA.height( h1 );
cB.height( h2 );
cA.css({ 'position': 'absolute', 'top': '0px' , 'lineHeight': h1, 'zIndex': 0, 'borderRadius': r1 });
cB.css({ 'position': 'absolute', 'top': b+'px', 'lineHeight': h2, 'zIndex': 1, 'borderRadius': r2 });
if(o.direction == 'left')
{
cA.css({ 'right': '0px' , 'textAlign': 'left' });
cB.css({ 'right': b+'px' });
}
else
{
cA.css({ 'left': '0px' , 'textAlign': 'right' });
cB.css({ 'left': b+'px' });
}
// Killer function set
this.killerFn = function( e ) {
// Test if didn't clicked on the slideButton
var tar = $(e.target);
if (tar.parents( '.slideButton' ).size() === 0) {
me.locked = false;
me.cB.removeClass( 'clicked' );
me.hide();
me.disableKillerFn();
}
};
// Stores slideButton instance in container
c.data( 'slideButton', me );
// Event listeners
cB.hover( me.show, me.hide );
cB.click( me.click );
},
setOptions: function(options) {
var o = this.options;
var c = this.container;
// Uses container height if no options.height is given
if(typeof(o.height) === 'undefined' || o.height == null || o.height <= 0)
if(c.height()) o.height = c.height();
$.extend(o, options);
},
// Slide visualization functions
show: function() {
var me;
if( typeof this.container !== 'undefined' )
me = this.cB;
else
me = $(this);
// Gets the instance
var sb = me.parent().data( 'slideButton' );
if(sb.deployed) return; // It is already deployed
var o = sb.options;
var slidelem = me.prev();
// Animates the contents of control
slidelem.stop().animate( { 'width': parseInt(o['deployedWidth']) + 'px' }, o['inSpeed'] ); //, o['inAnimation'] );
// Animates the contents of content
slidelem.find( 'span' ).stop( true, true ).fadeIn();
// Updates the state
sb.container.addClass('deployed');
sb.deployed = true;
// Triggers events
if( typeof o.onDeploy === 'function' ) o.onDeploy(sb);
},
hide: function(force) {
var me;
if(typeof this.container !== 'undefined')
me = this.cB;
else
me = $(this);
if( typeof force !== 'object' && force == true ) me.removeClass('clicked');
if( me.hasClass('clicked') ) return; // Ignore hide when in clicked (locked) state
// Gets the instance
var sb = me.parent().data( 'slideButton' );
if(!sb.deployed) return; // Already hidden
var o = sb.options;
var slidelem = me.prev();
// Animates the contents of control
slidelem.stop().animate( { 'width': parseInt(o.width)+'px' }, o['outSpeed'], o['outAnimation'] );
// Animates the contents of content
slidelem.find( 'span' ).stop( true, true ).fadeOut();
// Updates the state
sb.container.removeClass( 'deployed' );
sb.deployed = false;
sb.locked = false;
// Triggers events
if( typeof o.onHide === 'function' ) o.onHide(sb);
},
click: function (ev) {
var me = $(this);
// Gets the instance
var sb = me.parent().data( 'slideButton' );
var o = sb.options;
if( me.hasClass( 'clicked' ) )
{
me.removeClass( 'clicked' );
sb.hide();
sb.disableKillerFn();
}
else
{
sb.show();
sb.enableKillerFn();
me.addClass( 'clicked' );
}
// Triggers events
if( typeof o.onClick === 'function' ) o.onClick(sb);
},
lock: function() {
var sb = $(this).data( 'slideButton' );
if(!sb.deployed) sb.show();
sb.enableKillerFn(); // Hooks the click event on the document to close
sb.locked = true;
},
// Lock killer functions
enableKillerFn: function() {
var me = this;
$(document).bind( 'click', me.killerFn );
},
disableKillerFn: function() {
var me = this;
$(document).unbind( 'click', me.killerFn );
},
};
}(jQuery));
// Autoinitializarion
$(document).ready(function() {
if(slideButtonAutoload)
$( '.slideButton' ).each( function ( index, elem ) {
$(elem).slideButton( slideButtonDefaults );
});
});
///////////////////////////////////////////////////////////////////////
/*
* Border-radius jQuery cssHook
* ==========================================================
* (C) 2011 José Ramón Díaz - jrdiazweb@gmail.com
*
* Instead of using borderRadius cssHook from Brandon Aaron for example
* (https://github.com/brandonaaron/jquery-cssHooks), I define a custom
* cssHook for the borderRadius CSS property for the sake of simplicity
* and to reduce other modules dependencies.
*
* If you prefer to use another cssHook from another source (Brandon's
* one for example), just delete this and include the other cssHook.
*
* NOTE: cssHooks needs jQuery v1.4.3 or greater.
*/
(function( $ ){
var div = document.createElement('div'),
divStyle = div.style;
if ( !$.cssHooks ) {
// if not, output an error message
throw("jQuery 1.4.3 or above is required for this plugin to work");
return;
}
div = null; // Avoids IE memory leaks
$.support.borderRadius =
divStyle.MozBorderRadius === ''? 'MozBorderRadius' :
(divStyle.msBorderRadius === ''? 'msBorderRadius' :
(divStyle.WebkitBorderRadius === ''? 'WebkitBorderRadius' :
(divStyle.OBorderRadius === ''? 'OBorderRadius' :
(divStyle.borderRadius === ''? 'borderRadius' :
false))));
// Border radius will be set only in border-radius compatible "borderRadius" browsers
if ( $.support.borderRadius && $.support.slideBorderRadius !== "borderRadius" )
{
$.cssHooks["borderRadius"] = {
get: function( elem, computed, extra ) {
return $.css( elem, $.support.borderRadius );
},
set: function( elem, value) {
elem.style[$.support.borderRadius] = value;
}
};
}
})(jQuery);CSS /**
* Slide Button Styles.
* ================================================
* (C) 2011 José Ramón Díaz - jrdiazweb@gmail.com
*
* http://3nibbles.blogspot.com/2011/07/plugin-jquery-sliding-buttons.html
*
* Slide Button CSS styles. Note that rounded borders is a CSS3 feature,
* so, it will be represented correctly in CSS3 ready browsers.
*
* Legal stuff
* You are free to use this CSS, but you must give credit or keep header intact.
* Please, tell me if you find it useful. An email will be enough.
* If you enhance this code or correct a bug, please, tell me.
*/
.slideButton { font-weight: bold; font-size: 11px; font-family: Arial } /* Container */
.slideButton a { text-decoration: none; } /* a components containers */
.slideButton .button { background-color: #FFFFFF; color: #000000; text-align: center;
cursor: pointer; text-transform: uppercase; } /* Control */
.slideButton.deployed .button { background-color: #9AFF66; color: #FFFFFF; } /* Control - Deployed state */
.slideButton .content { background-color: #36A300; color: #FFFFFF; } /* Content */
.slideButton.deployed .content { } /* Content - Deployed state */
/* Depends on contents of the content component */
.slideButton .button span { color: #9AFF66; } /* Control spans */
.slideButton.deployed .button span { color: #36A300; } /* Control spans - Deployed */
.slideButton .content span span { color: #9AFF66; } /* Content spans */
.slideButton.deployed .content span { } /* Content spans - Deployed */
No hay comentarios:
Publicar un comentario