以下是 jQuery点击加载动画按钮特效 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!doctype html>
<html lang="en">
<head>
<meta charset="gb2312">
<title>jQuery������ض�����ť��Ч</title>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="dist/ladda-themeless.min.css">
<link rel="stylesheet" href="css/prism.css">
</head>
<body>
<br><br><br>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<p>
<button class="btn btn-primary ladda-button" data-style="expand-left"><span class="ladda-label">expand-left</span></button>
<button class="btn btn-primary ladda-button" data-style="expand-right"><span class="ladda-label">expand-right</span></button>
<button class="btn btn-primary ladda-button" data-style="expand-up"><span class="ladda-label">expand-up</span></button>
<button class="btn btn-primary ladda-button" data-style="expand-down"><span class="ladda-label">expand-down</span></button>
</p>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<p>
<button class="btn btn-info ladda-button" data-style="zoom-in"><span class="ladda-label">zoom-in</span></button>
<button class="btn btn-info ladda-button" data-style="zoom-out"><span class="ladda-label">zoom-out</span></button>
</p>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<p>
<button class="btn btn-warning ladda-button" data-style="slide-left"><span class="ladda-label">slide-left</span></button>
<button class="btn btn-warning ladda-button" data-style="slide-right"><span class="ladda-label">slide-right</span></button>
<button class="btn btn-warning ladda-button" data-style="slide-up"><span class="ladda-label">slide-up</span></button>
<button class="btn btn-warning ladda-button" data-style="slide-down"><span class="ladda-label">slide-down</span></button>
</p>
<p><button class="btn btn-warning ladda-button" data-style="contract"><span class="ladda-label">contract</span></button></p>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center progress-demo">
<p>Built-in progress bar</p>
<p>
<button class="btn btn-danger ladda-button" data-style="expand-right"><span class="ladda-label">expand-right</span></button>
<button class="btn btn-danger ladda-button" data-style="expand-left"><span class="ladda-label">expand-left</span></button>
<button class="btn btn-danger ladda-button" data-style="contract"><span class="ladda-label">contract</span></button>
</p>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<p>Sizes</p>
<p>
<button class="btn btn-primary btn-xs ladda-button" data-style="expand-right" data-size="xs"><span class="ladda-label">extra small</span></button>
<button class="btn btn-primary btn-sm ladda-button" data-style="expand-right" data-size="s"><span class="ladda-label">small</span></button>
<button class="btn btn-primary btn-lg ladda-button" data-style="expand-right" data-size="l"><span class="ladda-label">large</span></button>
</p>
</div>
</div>
</div>
<script src="dist/spin.min.js"></script>
<script src="dist/ladda.min.js"></script>
<script>
// Bind normal buttons
Ladda.bind( 'div:not(.progress-demo) button', { timeout: 2000 } );
// Bind progress buttons and simulate loading progress
Ladda.bind( '.progress-demo button', {
callback: function( instance ) {
var progress = 0;
var interval = setInterval( function() {
progress = Math.min( progress + Math.random() * 0.1, 1 );
instance.setProgress( progress );
if( progress === 1 ) {
instance.stop();
clearInterval( interval );
}
}, 200 );
}
} );
// You can control loading explicitly using the JavaScript API
// as outlined below:
// var l = Ladda.create( document.querySelector( 'button' ) );
// l.start();
// l.stop();
// l.toggle();
// l.isLoading();
// l.setProgress( 0-1 );
</script>
<script type="text/javascript" src="js/prism.js"></script>
</body>
</html>
JS代码(spin.js):
/** * Copyright (c) 2011-2014 Felix Gnass * Licensed under the MIT license */
(function(root,factory){
/* CommonJS */
if (typeof exports == 'object') module.exports = factory() /* AMD module */
else if (typeof define == 'function' && define.amd) define(factory) /* Browser global */
else root.Spinner = factory()}
(this,function(){
"use strict";
var prefixes = ['webkit','Moz','ms','O'] /* Vendor prefixes */
,animations ={
}
/* Animation rules keyed by their name */
,useCssAnimations /* Whether to use CSS animations or setTimeout */
/** * Utility function to create elements. If no tag name is given,* a DIV is created. Optionally properties can be passed. */
function createEl(tag,prop){
var el = document.createElement(tag || 'div'),n for(n in prop) el[n] = prop[n] return el}
/** * Appends children and returns the parent. */
function ins(parent /* child1,child2,...*/
){
for (var i=1,n=arguments.length;
i<n;
i++) parent.appendChild(arguments[i]) return parent}
/** * Insert a new stylesheet to hold the @keyframe or VML rules. */
var sheet = (function(){
var el = createEl('style',{
type:'text/css'}
) ins(document.getElementsByTagName('head')[0],el) return el.sheet || el.styleSheet}
()) /** * Creates an opacity keyframe animation rule and returns its name. * Since most mobile Webkits have timing issues with animation-delay,* we create separate rules for each line/segment. */
function addAnimation(alpha,trail,i,lines){
var name = ['opacity',trail,~~(alpha*100),i,lines].join('-'),start = 0.01 + i/lines * 100,z = Math.max(1 - (1-alpha) / trail * (100-start),alpha),prefix = useCssAnimations.substring(0,useCssAnimations.indexOf('Animation')).toLowerCase(),pre = prefix && '-' + prefix + '-' || '' if (!animations[name]){
sheet.insertRule( '@' + pre + 'keyframes ' + name + '{
' + '0%{
opacity:' + z + '}
' + start + '%{
opacity:' + alpha + '}
' + (start+0.01) + '%{
opacity:1}
' + (start+trail) % 100 + '%{
opacity:' + alpha + '}
' + '100%{
opacity:' + z + '}
' + '}
',sheet.cssRules.length) animations[name] = 1}
return name}
/** * Tries various vendor prefixes and returns the first supported property. */
function vendor(el,prop){
var s = el.style,pp,i prop = prop.charAt(0).toUpperCase() + prop.slice(1) for(i=0;
i<prefixes.length;
i++){
pp = prefixes[i]+prop if(s[pp] !== undefined) return pp}
if(s[prop] !== undefined) return prop}
/** * Sets multiple style properties at once. */
function css(el,prop){
for (var n in prop) el.style[vendor(el,n)||n] = prop[n] return el}
/** * Fills in default values. */
function merge(obj){
for (var i=1;
i < arguments.length;
i++){
var def = arguments[i] for (var n in def) if (obj[n] === undefined) obj[n] = def[n]}
return obj}
/** * Returns the absolute page-offset of the given element. */
function pos(el){
var o ={
x:el.offsetLeft,y:el.offsetTop}
while((el = el.offsetParent)) o.x+=el.offsetLeft,o.y+=el.offsetTop return o}
/** * Returns the line color from the given string or array. */
function getColor(color,idx){
return typeof color == 'string' ? color:color[idx % color.length]}
// Built-in defaults var defaults ={
lines:12,// The number of lines to draw length:7,// The length of each line width:5,// The line thickness radius:10,// The radius of the inner circle rotate:0,// Rotation offset corners:1,// Roundness (0..1) color:'#000',// #rgb or #rrggbb direction:1,// 1:clockwise,-1:counterclockwise speed:1,// Rounds per second trail:100,// Afterglow percentage opacity:1/4,// Opacity of the lines fps:20,// Frames per second when using setTimeout() zIndex:2e9,// Use a high z-index by default className:'spinner',// CSS class to assign to the element top:'50%',// center vertically left:'50%',// center horizontally position:'absolute' // element position}
/** The constructor */
function Spinner(o){
this.opts = merge(o ||{
}
,Spinner.defaults,defaults)}
// Global defaults that override the built-ins:Spinner.defaults ={
}
merge(Spinner.prototype,{
/** * Adds the spinner to the given target element. If this instance is already * spinning,it is automatically removed from its previous target b calling * stop() internally. */
spin:function(target){
this.stop() var self = this,o = self.opts,el = self.el = css(createEl(0,{
className:o.className}
),{
position:o.position,width:0,zIndex:o.zIndex}
),mid = o.radius+o.length+o.width css(el,{
left:o.left,top:o.top}
) if (target){
target.insertBefore(el,target.firstChild||null)}
el.setAttribute('role','progressbar') self.lines(el,self.opts) if (!useCssAnimations){
// No CSS animation support,use setTimeout() instead var i = 0,start = (o.lines - 1) * (1 - o.direction) / 2,alpha,fps = o.fps,f = fps/o.speed,ostep = (1-o.opacity) / (f*o.trail / 100),astep = f/o.lines;
(function anim(){
i++;
for (var j = 0;
j < o.lines;
j++){
alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep,o.opacity) self.opacity(el,j * o.direction + start,alpha,o)}
self.timeout = self.el && setTimeout(anim,~~(1000/fps))}
)()}
return self}
,/** * Stops and removes the Spinner. */
stop:function(){
var el = this.el if (el){
clearTimeout(this.timeout) if (el.parentNode) el.parentNode.removeChild(el) this.el = undefined}
return this}
,/** * Internal method that draws the individual lines. Will be overwritten * in VML fallback mode below. */
lines:function(el,o){
var i = 0,start = (o.lines - 1) * (1 - o.direction) / 2,seg function fill(color,shadow){
return css(createEl(),{
position:'absolute',width:(o.length+o.width) + 'px',height:o.width + 'px',background:color,boxShadow:shadow,transformOrigin:'left',transform:'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',borderRadius:(o.corners * o.width>>1) + 'px'}
)}
for (;
i < o.lines;
i++){
seg = css(createEl(),{
position:'absolute',top:1+~(o.width/2) + 'px',transform:o.hwaccel ? 'translate3d(0,0,0)':'',opacity:o.opacity,animation:useCssAnimations && addAnimation(o.opacity,o.trail,start + i * o.direction,o.lines) + ' ' + 1/o.speed + 's linear infinite'}
) if (o.shadow) ins(seg,css(fill('#000','0 0 4px ' + '#000'),{
top:2+'px'}
)) ins(el,ins(seg,fill(getColor(o.color,i),'0 0 1px rgba(0,0,0,.1)')))}
return el}
,/** * Internal method that adjusts the opacity of a single line. * Will be overwritten in VML fallback mode below. */
opacity:function(el,i,val){
if (i < el.childNodes.length) el.childNodes[i].style.opacity = val}
}
) function initVML(){
/* Utility function to create a VML tag */
function vml(tag,attr){
return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',attr)}
// No CSS transforms but VML support,add a CSS rule for VML elements:sheet.addRule('.spin-vml','behavior:url(#default#VML)') Spinner.prototype.lines = function(el,o){
var r = o.length+o.width,s = 2*r function grp(){
return css( vml('group',{
coordsize:s + ' ' + s,coordorigin:-r + ' ' + -r}
),{
width:s,height:s}
)}
var margin = -(o.width+o.length)*2 + 'px',g = css(grp(),{
position:'absolute',top:margin,left:margin}
),i function seg(i,dx,filter){
ins(g,ins(css(grp(),{
rotation:360 / o.lines * i + 'deg',left:~~dx}
),ins(css(vml('roundrect',{
arcsize:o.corners}
),{
width:r,height:o.width,left:o.radius,top:-o.width>>1,filter:filter}
),vml('fill',{
color:getColor(o.color,i),opacity:o.opacity}
),vml('stroke',{
opacity:0}
) // transparent stroke to fix color bleeding upon opacity change ) ) )}
if (o.shadow) for (i = 1;
i <= o.lines;
i++) seg(i,-2,'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)') for (i = 1;
i <= o.lines;
i++) seg(i) return ins(el,g)}
Spinner.prototype.opacity = function(el,i,val,o){
var c = el.firstChild o = o.shadow && o.lines || 0 if (c && i+o < c.childNodes.length){
c = c.childNodes[i+o];
c = c && c.firstChild;
c = c && c.firstChild if (c) c.opacity = val}
}
}
var probe = css(createEl('group'),{
behavior:'url(#default#VML)'}
) if (!vendor(probe,'transform') && probe.adj) initVML() else useCssAnimations = vendor(probe,'animation') return Spinner}
));
CSS代码(prism.css):
/** * prism.js default theme for JavaScript,CSS and HTML * Based on dabblet (http://dabblet.com) * @author Lea Verou */
code[class*="language-"],pre[class*="language-"]{color:black;text-shadow:0 1px white;font-family:Consolas,Monaco,'Andale Mono',monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}
pre[class*="language-"]::-moz-selection,pre[class*="language-"]::-moz-selection,code[class*="language-"]::-moz-selection,code[class*="language-"]::-moz-selection{text-shadow:none;background:#b3d4fc;}
pre[class*="language-"]::selection,pre[class*="language-"]::selection,code[class*="language-"]::selection,code[class*="language-"]::selection{text-shadow:none;background:#b3d4fc;}
@media print{code[class*="language-"],pre[class*="language-"]{text-shadow:none;}
}
/* Code blocks */
pre[class*="language-"]{padding:1em;margin:.5em 0;overflow:auto;}
:not(pre) > code[class*="language-"],pre[class*="language-"]{background:#f5f2f0;}
/* Inline code */
:not(pre) > code[class*="language-"]{padding:.1em;border-radius:.3em;}
.token.comment,.token.prolog,.token.doctype,.token.cdata{color:slategray;}
.token.punctuation{color:#999;}
.namespace{opacity:.7;}
.token.property,.token.tag,.token.boolean,.token.number{color:#905;}
.token.selector,.token.attr-name,.token.string{color:#690;}
.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#a67f59;background:hsla(0,0%,100%,.5);}
.token.atrule,.token.attr-value,.token.keyword{color:#07a;}
.token.regex,.token.important{color:#e90;}
.token.important{font-weight:bold;}
.token.entity{cursor:help;}