├── .gitignore ├── src ├── less │ ├── base │ │ ├── fadingIn │ │ │ ├── fadeIn.less │ │ │ ├── fadeInUp.less │ │ │ ├── fadeInDown.less │ │ │ ├── fadeInLeft.less │ │ │ ├── fadeInRight.less │ │ │ ├── fadeInUpBig.less │ │ │ ├── fadeInDownBig.less │ │ │ ├── fadeInLeftBig.less │ │ │ └── fadeInRightBig.less │ │ ├── fadingOut │ │ │ ├── fadeOut.less │ │ │ ├── fadeOutUp.less │ │ │ ├── fadeOutDown.less │ │ │ ├── fadeOutLeft.less │ │ │ ├── fadeOutRight.less │ │ │ ├── fadeOutDownBig.less │ │ │ ├── fadeOutLeftBig.less │ │ │ ├── fadeOutUpBig.less │ │ │ └── fadeOutRightBig.less │ │ ├── zoomingIn │ │ │ ├── zoomIn.less │ │ │ ├── zoomInUp.less │ │ │ ├── zoomInDown.less │ │ │ ├── zoomInLeft.less │ │ │ └── zoomInRight.less │ │ ├── slidingIn │ │ │ ├── slideInUp.less │ │ │ ├── slideInDown.less │ │ │ ├── slideInLeft.less │ │ │ └── slideInRight.less │ │ ├── slidingOut │ │ │ ├── slideOutDown.less │ │ │ ├── slideOutLeft.less │ │ │ ├── slideOutUp.less │ │ │ └── slideOutRight.less │ │ ├── zoomingOut │ │ │ ├── zoomOut.less │ │ │ ├── zoomOutLeft.less │ │ │ ├── zoomOutRight.less │ │ │ ├── zoomOutUp.less │ │ │ └── zoomOutDown.less │ │ ├── bouncingOut │ │ │ ├── bounceOutLeft.less │ │ │ ├── bounceOutRight.less │ │ │ ├── bounceOut.less │ │ │ ├── bounceOutDown.less │ │ │ └── bounceOutUp.less │ │ ├── rotatingOut │ │ │ ├── rotateOut.less │ │ │ ├── rotateOutUpLeft.less │ │ │ ├── rotateOutDownLeft.less │ │ │ ├── rotateOutUpRight.less │ │ │ └── rotateOutDownRight.less │ │ ├── rotatingIn │ │ │ ├── rotateIn.less │ │ │ ├── rotateInUpLeft.less │ │ │ ├── rotateInDownLeft.less │ │ │ ├── rotateInUpRight.less │ │ │ └── rotateInDownRight.less │ │ ├── flippers │ │ │ ├── flipOutX.less │ │ │ ├── flipOutY.less │ │ │ ├── flipInX.less │ │ │ ├── flipInY.less │ │ │ └── flip.less │ │ └── bouncingIn │ │ │ ├── bounceInDown.less │ │ │ ├── bounceInLeft.less │ │ │ ├── bounceInRight.less │ │ │ ├── bounceInUp.less │ │ │ └── bounceIn.less │ ├── src │ │ ├── delay.less │ │ ├── fading │ │ │ ├── fade.less │ │ │ ├── fadeUp.less │ │ │ ├── fadeDown.less │ │ │ ├── fadeLeft.less │ │ │ ├── fadeRight.less │ │ │ ├── fadeUpBig.less │ │ │ ├── fadeDownBig.less │ │ │ ├── fadeLeftBig.less │ │ │ └── fadeRightBig.less │ │ ├── zoom │ │ │ ├── zoom.less │ │ │ ├── zoomUp.less │ │ │ ├── zoomDown.less │ │ │ ├── zoomLeft.less │ │ │ └── zoomRight.less │ │ ├── rotate │ │ │ ├── rotate.less │ │ │ ├── rotateUpLeft.less │ │ │ ├── rotateDownLeft.less │ │ │ ├── rotateUpRight.less │ │ │ └── rotateDownRight.less │ │ ├── bouncing │ │ │ ├── bounce.less │ │ │ ├── bounceUp.less │ │ │ ├── bounceDown.less │ │ │ ├── bounceLeft.less │ │ │ └── bounceRight.less │ │ ├── slide │ │ │ ├── slideUp.less │ │ │ ├── slideDown.less │ │ │ ├── slideLeft.less │ │ │ └── slideRight.less │ │ └── flip │ │ │ ├── flipX.less │ │ │ └── flipY.less │ ├── animate.less │ └── reset.less └── js │ ├── scroll.js │ └── zepto.js ├── package.json ├── config.json ├── demo ├── css │ └── style.css └── index.html ├── README.md └── Gruntfile.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeIn.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeIn { 2 | 0% {opacity: 0;} 3 | 100% {opacity: 1;} 4 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOut.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOut { 2 | 0% {opacity: 1;} 3 | 100% {opacity: 0;} 4 | } -------------------------------------------------------------------------------- /src/less/base/zoomingIn/zoomIn.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomIn { 2 | 0% { 3 | opacity: 0; 4 | transform: scale3d(.3, .3, .3); 5 | } 6 | 7 | 50% { 8 | opacity: 1; 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOutUp.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOutUp { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 100% { 7 | opacity: 0; 8 | transform: translate3d(0, -100%, 0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOutDown.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOutDown { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 100% { 7 | opacity: 0; 8 | transform: translate3d(0, 100%, 0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOutLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOutLeft { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 100% { 7 | opacity: 0; 8 | transform: translate3d(-100%, 0, 0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOutRight.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOutRight { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 100% { 7 | opacity: 0; 8 | transform: translate3d(100%, 0, 0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/src/delay.less: -------------------------------------------------------------------------------- 1 | .delay1{ 2 | animation-delay:0.2s; 3 | } 4 | .delay2{ 5 | animation-delay:1s; 6 | } 7 | .delay3{ 8 | animation-delay:1.2s; 9 | } 10 | .delay4{ 11 | animation-delay:2s; 12 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOutDownBig.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOutDownBig { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 100% { 7 | opacity: 0; 8 | transform: translate3d(0, 2000px, 0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOutLeftBig.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOutLeftBig { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 100% { 7 | opacity: 0; 8 | transform: translate3d(-2000px, 0, 0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOutUpBig.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOutUpBig { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 100% { 7 | opacity: 0; 8 | transform: translate3d(0, -2000px, 0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingOut/fadeOutRightBig.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeOutRightBig { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 100% { 7 | opacity: 0; 8 | transform: translate3d(2000px, 0, 0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/slidingIn/slideInUp.less: -------------------------------------------------------------------------------- 1 | @keyframes slideInUp { 2 | 0% { 3 | transform: translateY(100%); 4 | visibility: visible; 5 | } 6 | 7 | 100% { 8 | transform: translateY(0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/src/fading/fade.less: -------------------------------------------------------------------------------- 1 | /*fade*/ 2 | @import '../../base/fadingIn/fadeIn'; 3 | @import '../../base/fadingOut/fadeOut'; 4 | .fade{ 5 | animation-name: fadeIn; 6 | &.out{ 7 | animation-name: fadeOut; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/zoom/zoom.less: -------------------------------------------------------------------------------- 1 | /*zoom*/ 2 | @import '../../base/zoomingIn/zoomIn'; 3 | @import '../../base/zoomingOut/zoomOut'; 4 | .zoom{ 5 | animation-name: zoomIn; 6 | &.out{ 7 | animation-name: zoomOut; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeInUp.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeInUp { 2 | 0% { 3 | opacity: 0; 4 | transform: translate3d(0, 100%, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | transform: none; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/base/slidingIn/slideInDown.less: -------------------------------------------------------------------------------- 1 | @keyframes slideInDown { 2 | 0% { 3 | transform: translateY(-100%); 4 | visibility: visible; 5 | } 6 | 7 | 100% { 8 | transform: translateY(0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/slidingIn/slideInLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes slideInLeft { 2 | 0% { 3 | transform: translateX(-100%); 4 | visibility: visible; 5 | } 6 | 7 | 100% { 8 | transform: translateX(0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/slidingIn/slideInRight.less: -------------------------------------------------------------------------------- 1 | @keyframes slideInRight { 2 | 0% { 3 | transform: translateX(100%); 4 | visibility: visible; 5 | } 6 | 7 | 100% { 8 | transform: translateX(0); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/slidingOut/slideOutDown.less: -------------------------------------------------------------------------------- 1 | @keyframes slideOutDown { 2 | 0% { 3 | transform: translateY(0); 4 | } 5 | 6 | 100% { 7 | visibility: hidden; 8 | transform: translateY(100%); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/slidingOut/slideOutLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes slideOutLeft { 2 | 0% { 3 | transform: translateX(0); 4 | } 5 | 6 | 100% { 7 | visibility: hidden; 8 | transform: translateX(-100%); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/slidingOut/slideOutUp.less: -------------------------------------------------------------------------------- 1 | @keyframes slideOutUp { 2 | 0% { 3 | transform: translateY(0); 4 | } 5 | 6 | 100% { 7 | visibility: hidden; 8 | transform: translateY(-100%); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeInDown.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeInDown { 2 | 0% { 3 | opacity: 0; 4 | transform: translate3d(0, -100%, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | transform: none; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeInLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeInLeft { 2 | 0% { 3 | opacity: 0; 4 | transform: translate3d(-100%, 0, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | transform: none; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/base/slidingOut/slideOutRight.less: -------------------------------------------------------------------------------- 1 | @keyframes slideOutRight { 2 | 0% { 3 | transform: translateX(0); 4 | } 5 | 6 | 100% { 7 | visibility: hidden; 8 | transform: translateX(100%); 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeInRight.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeInRight { 2 | 0% { 3 | opacity: 0; 4 | transform: translate3d(100%, 0, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | transform: none; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeInUpBig.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeInUpBig { 2 | 0% { 3 | opacity: 0; 4 | transform: translate3d(0, 2000px, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | transform: none; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/src/fading/fadeUp.less: -------------------------------------------------------------------------------- 1 | /*fadeUp*/ 2 | @import '../../base/fadingIn/fadeInUp'; 3 | @import '../../base/fadingOut/fadeOutDown'; 4 | .fadeUp{ 5 | animation-name: fadeInUp; 6 | &.out{ 7 | animation-name: fadeOutDown; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/rotate/rotate.less: -------------------------------------------------------------------------------- 1 | /*rotate*/ 2 | @import '../../base/rotatingIn/rotateIn'; 3 | @import '../../base/rotatingOut/rotateOut'; 4 | .rotate{ 5 | animation-name: rotateIn; 6 | &.out{ 7 | animation-name: rotateOut; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/zoom/zoomUp.less: -------------------------------------------------------------------------------- 1 | /*zoomUp*/ 2 | @import '../../base/zoomingIn/zoomInUp'; 3 | @import '../../base/zoomingOut/zoomOutDown'; 4 | .zoomUp{ 5 | animation-name: zoomInUp; 6 | &.out{ 7 | animation-name: zoomOutDown; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeInDownBig.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeInDownBig { 2 | 0% { 3 | opacity: 0; 4 | transform: translate3d(0, -2000px, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | transform: none; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeInLeftBig.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeInLeftBig { 2 | 0% { 3 | opacity: 0; 4 | transform: translate3d(-2000px, 0, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | transform: none; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/base/fadingIn/fadeInRightBig.less: -------------------------------------------------------------------------------- 1 | @keyframes fadeInRightBig { 2 | 0% { 3 | opacity: 0; 4 | transform: translate3d(2000px, 0, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | transform: none; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/src/bouncing/bounce.less: -------------------------------------------------------------------------------- 1 | /*bounce*/ 2 | @import '../../base/bouncingIn/bounceIn'; 3 | @import '../../base/bouncingOut/bounceOut'; 4 | .bounce{ 5 | animation-name: bounceIn; 6 | &.out{ 7 | animation-name: bounceOut; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/fading/fadeDown.less: -------------------------------------------------------------------------------- 1 | /*fadeDown*/ 2 | @import '../../base/fadingIn/fadeInDown'; 3 | @import '../../base/fadingOut/fadeOutUp'; 4 | .fadeDown{ 5 | animation-name: fadeInDown; 6 | &.out{ 7 | animation-name: fadeOutUp; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/zoom/zoomDown.less: -------------------------------------------------------------------------------- 1 | /*zoomDown*/ 2 | @import '../../base/zoomingIn/zoomInDown'; 3 | @import '../../base/zoomingOut/zoomOutUp'; 4 | .zoomDown{ 5 | animation-name: zoomInDown; 6 | &.out{ 7 | animation-name: zoomOutUp; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/base/zoomingOut/zoomOut.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomOut { 2 | 0% { 3 | opacity: 1; 4 | } 5 | 6 | 50% { 7 | opacity: 0; 8 | transform: scale3d(.3, .3, .3); 9 | } 10 | 11 | 100% { 12 | opacity: 0; 13 | } 14 | } -------------------------------------------------------------------------------- /src/less/src/fading/fadeLeft.less: -------------------------------------------------------------------------------- 1 | /*fadeLeft*/ 2 | @import '../../base/fadingIn/fadeInLeft'; 3 | @import '../../base/fadingOut/fadeOutLeft'; 4 | .fadeLeft{ 5 | animation-name: fadeInLeft; 6 | &.out{ 7 | animation-name: fadeOutLeft; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/slide/slideUp.less: -------------------------------------------------------------------------------- 1 | /*slideUp*/ 2 | @import '../../base/slidingIn/slideInUp'; 3 | @import '../../base/slidingOut/slideOutDown'; 4 | .slideUp{ 5 | animation-name: slideInUp; 6 | &.out{ 7 | animation-name: slideOutDown; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/zoom/zoomLeft.less: -------------------------------------------------------------------------------- 1 | /*zoomLeft*/ 2 | @import '../../base/zoomingIn/zoomInLeft'; 3 | @import '../../base/zoomingOut/zoomOutLeft'; 4 | .zoomLeft{ 5 | animation-name: zoomInLeft; 6 | &.out{ 7 | animation-name: zoomOutLeft; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/slide/slideDown.less: -------------------------------------------------------------------------------- 1 | /*slideDown*/ 2 | @import '../../base/slidingIn/slideInDown'; 3 | @import '../../base/slidingOut/slideOutUp'; 4 | .slideDown{ 5 | animation-name: slideInDown; 6 | &.out{ 7 | animation-name: slideOutUp; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/bouncing/bounceUp.less: -------------------------------------------------------------------------------- 1 | /*bounceUp*/ 2 | @import '../../base/bouncingIn/bounceInUp'; 3 | @import '../../base/bouncingOut/bounceOutDown'; 4 | .bounceUp{ 5 | animation-name: bounceInUp; 6 | &.out{ 7 | animation-name: bounceOutDown; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/fading/fadeRight.less: -------------------------------------------------------------------------------- 1 | /*fadeRight*/ 2 | @import '../../base/fadingIn/fadeInRight'; 3 | @import '../../base/fadingOut/fadeOutRight'; 4 | .fadeRight{ 5 | animation-name: fadeInRight; 6 | &.out{ 7 | animation-name: fadeOutRight; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/fading/fadeUpBig.less: -------------------------------------------------------------------------------- 1 | /*fadeUpBig*/ 2 | @import '../../base/fadingIn/fadeInUpBig'; 3 | @import '../../base/fadingOut/fadeOutDownBig'; 4 | .fadeUpBig{ 5 | animation-name: fadeInUpBig; 6 | &.out{ 7 | animation-name: fadeOutDownBig; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/slide/slideLeft.less: -------------------------------------------------------------------------------- 1 | /*slideLeft*/ 2 | @import '../../base/slidingIn/slideInLeft'; 3 | @import '../../base/slidingOut/slideOutLeft'; 4 | .slideLeft{ 5 | animation-name: slideInLeft; 6 | &.out{ 7 | animation-name: slideOutLeft; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/zoom/zoomRight.less: -------------------------------------------------------------------------------- 1 | /*zoomRight*/ 2 | @import '../../base/zoomingIn/zoomInRight'; 3 | @import '../../base/zoomingOut/zoomOutRight'; 4 | .zoomRight{ 5 | animation-name: zoomInRight; 6 | &.out{ 7 | animation-name: zoomOutRight; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/bouncing/bounceDown.less: -------------------------------------------------------------------------------- 1 | /*bounceDown*/ 2 | @import '../../base/bouncingIn/bounceInDown'; 3 | @import '../../base/bouncingOut/bounceOutUp'; 4 | .bounceDown{ 5 | animation-name: bounceInDown; 6 | &.out{ 7 | animation-name: bounceOutUp; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/slide/slideRight.less: -------------------------------------------------------------------------------- 1 | /*slideRight*/ 2 | @import '../../base/slidingIn/slideInRight'; 3 | @import '../../base/slidingOut/slideOutRight'; 4 | .slideRight{ 5 | animation-name: slideInRight; 6 | &.out{ 7 | animation-name: slideOutRight; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/base/bouncingOut/bounceOutLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceOutLeft { 2 | 20% { 3 | opacity: 1; 4 | transform: translate3d(20px, 0, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 0; 9 | transform: translate3d(-2000px, 0, 0); 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/base/bouncingOut/bounceOutRight.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceOutRight { 2 | 20% { 3 | opacity: 1; 4 | transform: translate3d(-20px, 0, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 0; 9 | transform: translate3d(2000px, 0, 0); 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/src/bouncing/bounceLeft.less: -------------------------------------------------------------------------------- 1 | /*bounceLeft*/ 2 | @import '../../base/bouncingIn/bounceInLeft'; 3 | @import '../../base/bouncingOut/bounceOutLeft'; 4 | .bounceLeft{ 5 | animation-name: bounceInLeft; 6 | &.out{ 7 | animation-name: bounceOutLeft; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/fading/fadeDownBig.less: -------------------------------------------------------------------------------- 1 | /*fadeDownBig*/ 2 | @import '../../base/fadingIn/fadeInDownBig'; 3 | @import '../../base/fadingOut/fadeOutUpBig'; 4 | .fadeDownBig{ 5 | animation-name: fadeInDownBig; 6 | &.out{ 7 | animation-name: fadeOutUpBig; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/fading/fadeLeftBig.less: -------------------------------------------------------------------------------- 1 | /*fadeLeftBig*/ 2 | @import '../../base/fadingIn/fadeInLeftBig'; 3 | @import '../../base/fadingOut/fadeOutLeftBig'; 4 | .fadeLeftBig{ 5 | animation-name: fadeInLeftBig; 6 | &.out{ 7 | animation-name: fadeOutLeftBig; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/bouncing/bounceRight.less: -------------------------------------------------------------------------------- 1 | /*bounceRight*/ 2 | @import '../../base/bouncingIn/bounceInRight'; 3 | @import '../../base/bouncingOut/bounceOutRight'; 4 | .bounceRight{ 5 | animation-name: bounceInRight; 6 | &.out{ 7 | animation-name: bounceOutRight; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/fading/fadeRightBig.less: -------------------------------------------------------------------------------- 1 | /*fadeRightBig*/ 2 | @import '../../base/fadingIn/fadeInRightBig'; 3 | @import '../../base/fadingOut/fadeOutRightBig'; 4 | .fadeRightBig{ 5 | animation-name: fadeInRightBig; 6 | &.out{ 7 | animation-name: fadeOutRightBig; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/base/rotatingOut/rotateOut.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateOut { 2 | 0% { 3 | transform-origin: center; 4 | opacity: 1; 5 | } 6 | 7 | 100% { 8 | transform-origin: center; 9 | transform: rotate3d(0, 0, 1, 200deg); 10 | opacity: 0; 11 | } 12 | } -------------------------------------------------------------------------------- /src/less/src/flip/flipX.less: -------------------------------------------------------------------------------- 1 | /*flipX*/ 2 | @import '../../base/flippers/flipInX'; 3 | @import '../../base/flippers/flipOutX'; 4 | .flipX{ 5 | backface-visibility: visible !important; 6 | animation-name: flipInX; 7 | &.out{ 8 | animation-name: flipOutX; 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/src/flip/flipY.less: -------------------------------------------------------------------------------- 1 | /*flipY*/ 2 | @import '../../base/flippers/flipInY'; 3 | @import '../../base/flippers/flipOutY'; 4 | .flipY{ 5 | backface-visibility: visible !important; 6 | animation-name: flipInY; 7 | &.out{ 8 | animation-name: flipOutY; 9 | } 10 | } -------------------------------------------------------------------------------- /src/less/src/rotate/rotateUpLeft.less: -------------------------------------------------------------------------------- 1 | /*rotateUpLeft*/ 2 | @import '../../base/rotatingIn/rotateInUpLeft'; 3 | @import '../../base/rotatingOut/rotateOutDownLeft'; 4 | .rotateUpLeft{ 5 | animation-name: rotateInUpLeft; 6 | &.out{ 7 | animation-name: rotateOutDownLeft; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/rotate/rotateDownLeft.less: -------------------------------------------------------------------------------- 1 | /*rotateDownLeft*/ 2 | @import '../../base/rotatingIn/rotateInDownLeft'; 3 | @import '../../base/rotatingOut/rotateOutUpLeft'; 4 | .rotateDownLeft{ 5 | animation-name: rotateInDownLeft; 6 | &.out{ 7 | animation-name: rotateOutUpLeft; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/rotate/rotateUpRight.less: -------------------------------------------------------------------------------- 1 | /*rotateUpRight*/ 2 | @import '../../base/rotatingIn/rotateInUpRight'; 3 | @import '../../base/rotatingOut/rotateOutDownRight'; 4 | .rotateUpRight{ 5 | animation-name: rotateInUpRight; 6 | &.out{ 7 | animation-name: rotateOutDownRight; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/src/rotate/rotateDownRight.less: -------------------------------------------------------------------------------- 1 | /*rotateDownRight*/ 2 | @import '../../base/rotatingIn/rotateInDownRight'; 3 | @import '../../base/rotatingOut/rotateOutUpRight'; 4 | .rotateDownRight{ 5 | animation-name: rotateInDownRight; 6 | &.out{ 7 | animation-name: rotateOutUpRight; 8 | } 9 | } -------------------------------------------------------------------------------- /src/less/base/rotatingIn/rotateIn.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateIn { 2 | 0% { 3 | transform-origin: center; 4 | transform: rotate3d(0, 0, 1, -200deg); 5 | opacity: 0; 6 | } 7 | 8 | 100% { 9 | transform-origin: center; 10 | transform: none; 11 | opacity: 1; 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/rotatingOut/rotateOutUpLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateOutUpLeft { 2 | 0% { 3 | transform-origin: left bottom; 4 | opacity: 1; 5 | } 6 | 7 | 100% { 8 | transform-origin: left bottom; 9 | transform: rotate3d(0, 0, 1, -45deg); 10 | opacity: 0; 11 | } 12 | } -------------------------------------------------------------------------------- /src/less/base/rotatingOut/rotateOutDownLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateOutDownLeft { 2 | 0% { 3 | transform-origin: left bottom; 4 | opacity: 1; 5 | } 6 | 7 | 100% { 8 | transform-origin: left bottom; 9 | transform: rotate3d(0, 0, 1, 45deg); 10 | opacity: 0; 11 | } 12 | } -------------------------------------------------------------------------------- /src/less/base/rotatingOut/rotateOutUpRight.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateOutUpRight { 2 | 0% { 3 | transform-origin: right bottom; 4 | opacity: 1; 5 | } 6 | 7 | 100% { 8 | transform-origin: right bottom; 9 | transform: rotate3d(0, 0, 1, 90deg); 10 | opacity: 0; 11 | } 12 | } -------------------------------------------------------------------------------- /src/less/base/rotatingOut/rotateOutDownRight.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateOutDownRight { 2 | 0% { 3 | transform-origin: right bottom; 4 | opacity: 1; 5 | } 6 | 7 | 100% { 8 | transform-origin: right bottom; 9 | transform: rotate3d(0, 0, 1, -45deg); 10 | opacity: 0; 11 | } 12 | } -------------------------------------------------------------------------------- /src/less/base/bouncingOut/bounceOut.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceOut { 2 | 20% { 3 | transform: scale3d(.9, .9, .9); 4 | } 5 | 6 | 50%, 55% { 7 | opacity: 1; 8 | transform: scale3d(1.1, 1.1, 1.1); 9 | } 10 | 11 | 100% { 12 | opacity: 0; 13 | transform: scale3d(.3, .3, .3); 14 | } 15 | } -------------------------------------------------------------------------------- /src/less/base/rotatingIn/rotateInUpLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateInUpLeft { 2 | 0% { 3 | transform-origin: left bottom; 4 | transform: rotate3d(0, 0, 1, 45deg); 5 | opacity: 0; 6 | } 7 | 8 | 100% { 9 | transform-origin: left bottom; 10 | transform: none; 11 | opacity: 1; 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/rotatingIn/rotateInDownLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateInDownLeft { 2 | 0% { 3 | transform-origin: left bottom; 4 | transform: rotate3d(0, 0, 1, -45deg); 5 | opacity: 0; 6 | } 7 | 8 | 100% { 9 | transform-origin: left bottom; 10 | transform: none; 11 | opacity: 1; 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/rotatingIn/rotateInUpRight.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateInUpRight { 2 | 0% { 3 | transform-origin: right bottom; 4 | transform: rotate3d(0, 0, 1, -90deg); 5 | opacity: 0; 6 | } 7 | 8 | 100% { 9 | transform-origin: right bottom; 10 | transform: none; 11 | opacity: 1; 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/rotatingIn/rotateInDownRight.less: -------------------------------------------------------------------------------- 1 | @keyframes rotateInDownRight { 2 | 0% { 3 | transform-origin: right bottom; 4 | transform: rotate3d(0, 0, 1, 45deg); 5 | opacity: 0; 6 | } 7 | 8 | 100% { 9 | transform-origin: right bottom; 10 | transform: none; 11 | opacity: 1; 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/zoomingOut/zoomOutLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomOutLeft { 2 | 40% { 3 | opacity: 1; 4 | transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 0; 9 | transform: scale(.1) translate3d(-2000px, 0, 0); 10 | transform-origin: left center; 11 | } 12 | } -------------------------------------------------------------------------------- /src/less/base/zoomingOut/zoomOutRight.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomOutRight { 2 | 40% { 3 | opacity: 1; 4 | transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); 5 | } 6 | 7 | 100% { 8 | opacity: 0; 9 | transform: scale(.1) translate3d(2000px, 0, 0); 10 | transform-origin: right center; 11 | } 12 | } -------------------------------------------------------------------------------- /src/less/base/bouncingOut/bounceOutDown.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceOutDown { 2 | 20% { 3 | transform: translate3d(0, 10px, 0); 4 | } 5 | 6 | 40%, 45% { 7 | opacity: 1; 8 | transform: translate3d(0, -20px, 0); 9 | } 10 | 11 | 100% { 12 | opacity: 0; 13 | transform: translate3d(0, 2000px, 0); 14 | } 15 | } -------------------------------------------------------------------------------- /src/less/base/bouncingOut/bounceOutUp.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceOutUp { 2 | 20% { 3 | transform: translate3d(0, -10px, 0); 4 | } 5 | 6 | 40%, 45% { 7 | opacity: 1; 8 | transform: translate3d(0, 20px, 0); 9 | } 10 | 11 | 100% { 12 | opacity: 0; 13 | transform: translate3d(0, -2000px, 0); 14 | } 15 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "animateLess", 3 | "version": "0.1.0", 4 | "devDependencies": { 5 | "grunt": "~0.4.5", 6 | "grunt-contrib-less": "~1.0.0", 7 | "grunt-contrib-cssmin" : "0.10.0", 8 | "grunt-contrib-copy": "~0.7.0" , 9 | "grunt-contrib-uglify": "~0.7.0", 10 | "grunt-autoprefixer": "~0.4.0" 11 | } 12 | } -------------------------------------------------------------------------------- /src/less/base/flippers/flipOutX.less: -------------------------------------------------------------------------------- 1 | @keyframes flipOutX { 2 | 0% { 3 | transform: perspective(400px); 4 | } 5 | 6 | 30% { 7 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 8 | opacity: 1; 9 | } 10 | 11 | 100% { 12 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 13 | opacity: 0; 14 | } 15 | } -------------------------------------------------------------------------------- /src/less/base/flippers/flipOutY.less: -------------------------------------------------------------------------------- 1 | @keyframes flipOutY { 2 | 0% { 3 | transform: perspective(400px); 4 | } 5 | 6 | 30% { 7 | transform: perspective(400px) rotate3d(0, 1, 0, -15deg); 8 | opacity: 1; 9 | } 10 | 11 | 100% { 12 | transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 13 | opacity: 0; 14 | } 15 | } -------------------------------------------------------------------------------- /src/less/base/zoomingIn/zoomInUp.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomInUp { 2 | 0% { 3 | opacity: 0; 4 | transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); 5 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 6 | } 7 | 8 | 60% { 9 | opacity: 1; 10 | transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 11 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/zoomingIn/zoomInDown.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomInDown { 2 | 0% { 3 | opacity: 0; 4 | transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); 5 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 6 | } 7 | 8 | 60% { 9 | opacity: 1; 10 | transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 11 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/zoomingIn/zoomInLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomInLeft { 2 | 0% { 3 | opacity: 0; 4 | transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); 5 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 6 | } 7 | 8 | 60% { 9 | opacity: 1; 10 | transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); 11 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/zoomingIn/zoomInRight.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomInRight { 2 | 0% { 3 | opacity: 0; 4 | transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); 5 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 6 | } 7 | 8 | 60% { 9 | opacity: 1; 10 | transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); 11 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 12 | } 13 | } -------------------------------------------------------------------------------- /src/less/base/zoomingOut/zoomOutUp.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomOutUp { 2 | 40% { 3 | opacity: 1; 4 | transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 5 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 6 | } 7 | 8 | 100% { 9 | opacity: 0; 10 | transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); 11 | transform-origin: center bottom; 12 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 13 | } 14 | } -------------------------------------------------------------------------------- /src/less/base/zoomingOut/zoomOutDown.less: -------------------------------------------------------------------------------- 1 | @keyframes zoomOutDown { 2 | 40% { 3 | opacity: 1; 4 | transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 5 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 6 | } 7 | 8 | 100% { 9 | opacity: 0; 10 | transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); 11 | transform-origin: center bottom; 12 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 13 | } 14 | } -------------------------------------------------------------------------------- /src/less/base/bouncingIn/bounceInDown.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceInDown { 2 | 0%, 60%, 75%, 90%, 100% { 3 | transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 4 | } 5 | 6 | 0% { 7 | opacity: 0; 8 | transform: translate3d(0, -3000px, 0); 9 | } 10 | 11 | 60% { 12 | opacity: 1; 13 | transform: translate3d(0, 25px, 0); 14 | } 15 | 16 | 75% { 17 | transform: translate3d(0, -10px, 0); 18 | } 19 | 20 | 90% { 21 | transform: translate3d(0, 5px, 0); 22 | } 23 | 24 | 100% { 25 | transform: none; 26 | } 27 | } -------------------------------------------------------------------------------- /src/less/base/bouncingIn/bounceInLeft.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceInLeft { 2 | 0%, 60%, 75%, 90%, 100% { 3 | transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 4 | } 5 | 6 | 0% { 7 | opacity: 0; 8 | transform: translate3d(-3000px, 0, 0); 9 | } 10 | 11 | 60% { 12 | opacity: 1; 13 | transform: translate3d(25px, 0, 0); 14 | } 15 | 16 | 75% { 17 | transform: translate3d(-10px, 0, 0); 18 | } 19 | 20 | 90% { 21 | transform: translate3d(5px, 0, 0); 22 | } 23 | 24 | 100% { 25 | transform: none; 26 | } 27 | } -------------------------------------------------------------------------------- /src/less/base/bouncingIn/bounceInRight.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceInRight { 2 | 0%, 60%, 75%, 90%, 100% { 3 | transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 4 | } 5 | 6 | 0% { 7 | opacity: 0; 8 | transform: translate3d(3000px, 0, 0); 9 | } 10 | 11 | 60% { 12 | opacity: 1; 13 | transform: translate3d(-25px, 0, 0); 14 | } 15 | 16 | 75% { 17 | transform: translate3d(10px, 0, 0); 18 | } 19 | 20 | 90% { 21 | transform: translate3d(-5px, 0, 0); 22 | } 23 | 24 | 100% { 25 | transform: none; 26 | } 27 | } -------------------------------------------------------------------------------- /src/less/base/bouncingIn/bounceInUp.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceInUp { 2 | 0%, 60%, 75%, 90%, 100% { 3 | transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 4 | } 5 | 6 | 0% { 7 | opacity: 0; 8 | transform: translate3d(0, 3000px, 0); 9 | } 10 | 11 | 60% { 12 | opacity: 1; 13 | transform: translate3d(0, -20px, 0); 14 | } 15 | 16 | 75% { 17 | transform: translate3d(0, 10px, 0); 18 | } 19 | 20 | 90% { 21 | transform: translate3d(0, -5px, 0); 22 | } 23 | 24 | 100% { 25 | transform: translate3d(0, 0, 0); 26 | } 27 | } -------------------------------------------------------------------------------- /src/less/base/flippers/flipInX.less: -------------------------------------------------------------------------------- 1 | @keyframes flipInX { 2 | 0% { 3 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 4 | transition-timing-function: ease-in; 5 | opacity: 0; 6 | } 7 | 8 | 40% { 9 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 10 | transition-timing-function: ease-in; 11 | } 12 | 13 | 60% { 14 | transform: perspective(400px) rotate3d(1, 0, 0, 10deg); 15 | opacity: 1; 16 | } 17 | 18 | 80% { 19 | transform: perspective(400px) rotate3d(1, 0, 0, -5deg); 20 | } 21 | 22 | 100% { 23 | transform: perspective(400px); 24 | } 25 | } -------------------------------------------------------------------------------- /src/less/base/flippers/flipInY.less: -------------------------------------------------------------------------------- 1 | @keyframes flipInY { 2 | 0% { 3 | transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 4 | transition-timing-function: ease-in; 5 | opacity: 0; 6 | } 7 | 8 | 40% { 9 | transform: perspective(400px) rotate3d(0, 1, 0, -20deg); 10 | transition-timing-function: ease-in; 11 | } 12 | 13 | 60% { 14 | transform: perspective(400px) rotate3d(0, 1, 0, 10deg); 15 | opacity: 1; 16 | } 17 | 18 | 80% { 19 | transform: perspective(400px) rotate3d(0, 1, 0, -5deg); 20 | } 21 | 22 | 100% { 23 | transform: perspective(400px); 24 | } 25 | } -------------------------------------------------------------------------------- /src/less/base/bouncingIn/bounceIn.less: -------------------------------------------------------------------------------- 1 | @keyframes bounceIn { 2 | 0%, 20%, 40%, 60%, 80%, 100% { 3 | transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 4 | } 5 | 6 | 0% { 7 | opacity: 0; 8 | transform: scale3d(.3, .3, .3); 9 | } 10 | 11 | 20% { 12 | transform: scale3d(1.1, 1.1, 1.1); 13 | } 14 | 15 | 40% { 16 | transform: scale3d(.9, .9, .9); 17 | } 18 | 19 | 60% { 20 | opacity: 1; 21 | transform: scale3d(1.03, 1.03, 1.03); 22 | } 23 | 24 | 80% { 25 | transform: scale3d(.97, .97, .97); 26 | } 27 | 28 | 100% { 29 | opacity: 1; 30 | transform: scale3d(1, 1, 1); 31 | } 32 | } -------------------------------------------------------------------------------- /src/less/base/flippers/flip.less: -------------------------------------------------------------------------------- 1 | @keyframes flip { 2 | 0% { 3 | transform: perspective(400px) rotate3d(0, 1, 0, -360deg); 4 | animation-timing-function: ease-out; 5 | } 6 | 7 | 40% { 8 | transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); 9 | animation-timing-function: ease-out; 10 | } 11 | 12 | 50% { 13 | transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); 14 | animation-timing-function: ease-in; 15 | } 16 | 17 | 80% { 18 | transform: perspective(400px) scale3d(.95, .95, .95); 19 | animation-timing-function: ease-in; 20 | } 21 | 22 | 100% { 23 | transform: perspective(400px); 24 | animation-timing-function: ease-in; 25 | } 26 | } 27 | 28 | .animated.flip { 29 | backface-visibility: visible; 30 | animation-name: flip; 31 | } 32 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "bouncing": { 4 | "bounce": true, 5 | "bounceDown": true, 6 | "bounceLeft": true, 7 | "bounceRight": true, 8 | "bounceUp": true 9 | }, 10 | 11 | "fading": { 12 | "fade": true, 13 | "fadeDown": true, 14 | "fadeDownBig": true, 15 | "fadeLeft": true, 16 | "fadeLeftBig": true, 17 | "fadeRight": true, 18 | "fadeRightBig": true, 19 | "fadeUp": true, 20 | "fadeUpBig": true 21 | }, 22 | 23 | "flip": { 24 | "flipX": true, 25 | "flipY": true 26 | }, 27 | 28 | "rotate": { 29 | "rotate": true, 30 | "rotateDownLeft": true, 31 | "rotateDownRight": true, 32 | "rotateUpLeft": true, 33 | "rotateUpRight": true 34 | }, 35 | 36 | "slide": { 37 | "slideDown": true, 38 | "slideLeft": true, 39 | "slideRight": true, 40 | "slideUp": true 41 | }, 42 | 43 | "zoom": { 44 | "zoom": true, 45 | "zoomDown": true, 46 | "zoomLeft": true, 47 | "zoomRight": true, 48 | "zoomUp": true 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/less/animate.less: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | @import 'reset'; 3 | .pt-pageList{ 4 | width: 100%; 5 | height: 100%; 6 | position: absolute; 7 | top: 0; 8 | left: 0; 9 | right: 0; 10 | bottom: 0; 11 | .animated { 12 | animation-duration: 1s; 13 | animation-fill-mode: both; 14 | &.infinite { 15 | animation-iteration-count: infinite; 16 | } 17 | &.hinge { 18 | animation-duration: 2s; 19 | } 20 | &.bounceIn,&.bounceOut{ 21 | animation-duration: .75s; 22 | } 23 | &.flipOutX,&.flipOutY{ 24 | animation-duration: .75s; 25 | } 26 | } 27 | 28 | /*import animate*/ 29 | @import 'src/delay'; 30 | } 31 | .pt-page{ 32 | width: 100%; 33 | height: 100%; 34 | position: absolute; 35 | top: 0; 36 | left: 0; 37 | right: 0; 38 | bottom: 0; 39 | visibility: hidden; 40 | overflow: hidden; 41 | backface-visibility: hidden; 42 | transform: translate3d(0, 0, 0); 43 | transform-style: preserve-3d; 44 | .removeable{ 45 | display: none; 46 | } 47 | background-size: cover; 48 | background-position: 50% 100%; 49 | } 50 | 51 | .pt-page-current{ 52 | visibility: visible; 53 | } -------------------------------------------------------------------------------- /demo/css/style.css: -------------------------------------------------------------------------------- 1 | .pt-page-1 { 2 | background: #0ac2d2; 3 | color:#fff; 4 | } 5 | 6 | .pt-page-2 { 7 | background: #7bb7fa; 8 | } 9 | 10 | .pt-page-3 { 11 | background: #60d7a9; 12 | } 13 | 14 | .pt-page-4 { 15 | background: #fdc162; 16 | } 17 | 18 | .pt-page-5 { 19 | background: #fd6a62; 20 | } 21 | 22 | .pt-page-6 { 23 | background: #f68dbb; 24 | } 25 | .pt-page-7 { 26 | background: #0ac2d2; 27 | } 28 | 29 | .pt-page-8 { 30 | background: #7bb7fa; 31 | } 32 | 33 | .pt-page-9 { 34 | background: #60d7a9; 35 | } 36 | 37 | .pt-page-10 { 38 | background: #fdc162; 39 | } 40 | 41 | .pt-page-11 { 42 | background: #fd6a62; 43 | } 44 | 45 | .pt-page-12 { 46 | background: #f68dbb; 47 | } 48 | .pt-page-13 { 49 | background: #0ac2d2; 50 | } 51 | 52 | .pt-page-14 { 53 | background: #7bb7fa; 54 | } 55 | 56 | .pt-page-15 { 57 | background: #60d7a9; 58 | } 59 | 60 | .pt-page-16 { 61 | background: #fdc162; 62 | } 63 | 64 | .pt-page-17 { 65 | background: #fd6a62; 66 | } 67 | 68 | .pt-page-18 { 69 | background: #f68dbb; 70 | } 71 | .pt-page-19 { 72 | background: #0ac2d2; 73 | } 74 | 75 | .pt-page-20 { 76 | background: #7bb7fa; 77 | } 78 | 79 | .pt-page-21 { 80 | background: #60d7a9; 81 | } 82 | 83 | .pt-page-22 { 84 | background: #fdc162; 85 | } 86 | 87 | .pt-page-23 { 88 | background: #fd6a62; 89 | } 90 | 91 | .pt-page-24 { 92 | background: #f68dbb; 93 | } 94 | .pt-page-25 { 95 | background: #0ac2d2; 96 | } 97 | 98 | .pt-page-26 { 99 | background: #7bb7fa; 100 | } 101 | 102 | .pt-page-27 { 103 | background: #60d7a9; 104 | } 105 | 106 | .pt-page-28 { 107 | background: #fdc162; 108 | } 109 | 110 | .pt-page-29 { 111 | background: #fd6a62; 112 | } 113 | 114 | .pt-page-30 { 115 | background: #f68dbb; 116 | } -------------------------------------------------------------------------------- /src/less/reset.less: -------------------------------------------------------------------------------- 1 | /* 2 | * ml 3 | * 4 | */ 5 | @charset "utf-8"; 6 | html { 7 | color: #000; 8 | background: #fff; 9 | overflow-y: scroll; 10 | -webkit-text-size-adjust: 100%; 11 | -ms-text-size-adjust: 100%; 12 | } 13 | html * { 14 | outline: none; 15 | -webkit-text-size-adjust: none; 16 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 17 | } 18 | html, 19 | body { 20 | font-family: sans-serif; 21 | } 22 | /* 内外边距通常让各个浏览器样式的表现位置不同 */ 23 | body, 24 | div, 25 | dl, 26 | dt, 27 | dd, 28 | ul, 29 | ol, 30 | li, 31 | h1, 32 | h2, 33 | h3, 34 | h4, 35 | h5, 36 | h6, 37 | pre, 38 | code, 39 | form, 40 | fieldset, 41 | legend, 42 | input, 43 | textarea, 44 | p, 45 | blockquote, 46 | th, 47 | td, 48 | hr, 49 | button, 50 | article, 51 | aside, 52 | details, 53 | figcaption, 54 | figure, 55 | footer, 56 | header, 57 | hgroup, 58 | menu, 59 | nav, 60 | section { 61 | margin: 0; 62 | padding: 0; 63 | } 64 | input, 65 | select, 66 | textarea { 67 | font-size: 100%; 68 | } 69 | /* 去掉各 Table cell 的边距并让其边重合 */ 70 | table { 71 | border-collapse: collapse; 72 | border-spacing: 0; 73 | } 74 | /* 去除默认边框 */ 75 | fieldset, 76 | img { 77 | border: 0; 78 | } 79 | /* 去掉 firefox 下此元素的边框 */ 80 | abbr, 81 | acronym { 82 | border: 0; 83 | font-variant: normal; 84 | } 85 | /* 一致的 del 样式 */ 86 | del { 87 | text-decoration: line-through; 88 | } 89 | address, 90 | caption, 91 | cite, 92 | code, 93 | dfn, 94 | em, 95 | th, 96 | var { 97 | font-style: normal; 98 | font-weight: 500; 99 | } 100 | /* 去掉列表前的标识, li 会继承 */ 101 | ol, 102 | ul { 103 | list-style: none; 104 | } 105 | /* 对齐是排版最重要的因素, 别让什么都居中 */ 106 | caption, 107 | th { 108 | text-align: left; 109 | } 110 | /* 来自 yahoo, 让标题都自定义, 适应多个系统应用 */ 111 | h1, 112 | h2, 113 | h3, 114 | h4, 115 | h5, 116 | h6 { 117 | font-size: 100%; 118 | font-weight: 500; 119 | } 120 | q:before, 121 | q:after { 122 | content: ''; 123 | } 124 | /* 统一上标和下标 */ 125 | sub, 126 | sup { 127 | font-size: 75%; 128 | line-height: 0; 129 | position: relative; 130 | vertical-align: baseline; 131 | } 132 | sup { 133 | top: -0.5em; 134 | } 135 | sub { 136 | bottom: -0.25em; 137 | } 138 | /* 正常链接 未访问 */ 139 | /* 鼠标悬停 */ 140 | a:hover { 141 | text-decoration: underline; 142 | } 143 | /* 默认不显示下划线,保持页面简洁 */ 144 | ins, 145 | a { 146 | text-decoration: none; 147 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##使用 2 | 3 | ###1. 起步 4 | 插件依赖于一个animate.css还有scroll.js两个文件,需要在页面中引入,其中scroll.js依赖于Zepto或者jQuery的几个方法,所以还需要引入zepto或者jQuery 5 | 6 | 7 | 8 | 9 | 10 | ###2. 基本模板 11 | 12 |
13 |
/*直接加载出来*/
14 |
15 | /*以bounceUp方式动画*/ 16 |
17 |
18 | /*对有背景图的进行惰性加载,并以bounceUp方式动画*/ 19 |
20 |
21 |

/*页面切换完就有*/

22 |

/*切换完后延迟动画*/

23 | /*每一页中的图片元素也支持惰性加载*/ 24 |
25 | ... 26 |
27 | 28 | (1) 父元素上**需要**加类.pt-pageList(可以在less中修改,重新构建) 29 | 30 | (2) 子元素即每一页**需要**加类pt-page(可以在less中修改,重新构建) 31 | 32 | (3) data-animate=""这里可以填写需要的页面切换之间的动画,一共有××种,详见文档最后的附录部分(关于这个animate属性,支持重新配置,如果有冲突可以在js中进行赋值) 33 | 34 | (4) data-bg=""对于每一页设置背景图片还需要进行惰性加载的页面,可以将背景图的地址放在这里(暂不支持bg名字的重新配置),**同时元素需要再加一个类lazyload** 35 | 36 | (5) 对于每一个页面中的元素,可以自行进行定位样式的设置,如果需要对每一页中的元素进行动画配置,则只需要对该元素加上class为"removeable bounceUp delay2",除了延迟的类以外其他都是必须的且都不可配置 37 | 38 | bounceUp /*动画的名字,种类见附录*/ 39 | delay2 /*动画延迟时间,可自行定义类加入,若没有则无延迟*/ 40 | 关于延迟,默认提供了四种方案(不够可自行进行写css) 41 | A. delay1 :延迟0.2s 42 | B. delay2 :延迟1S 43 | C. delay3 :延迟1.2S 44 | D. delay4 :延迟2S 45 | (6) 对于每一页的图片元素也支持惰性加载,只需要在img标签中加一个data-src(不可配置)和一个类lazyload(可配置),当然这里同时还可以继续添加动画 46 | 47 | 48 | ###3. 使用方法 49 | 50 | var slid = new SlidePage({ 51 | /*@required:传入父节点的类或者ID*/ 52 | container : "", 53 | /*自定义节点动画属性data-animate,修改animate名字默认为animate*/ 54 | attr : "", 55 | /*节点中的类lazyload,可以进行配置,不传试用默认*/ 56 | lazyClass : "", 57 | /*自定义惰性加载的数量,默认是3,既页面中至少会加载三个页*/ 58 | preLoadNum : , 59 | }), 60 | mainBody = $("#pt-main"); 61 | mainBody.on('swipeDown',function(){ 62 | slid.prePage();/*上一页*/ 63 | }) 64 | 65 | mainBody.on('swipeUp',function(){ 66 | slid.nextPage();/*下一页*/ 67 | }) 68 | 69 | ###4. 动画介绍 70 | 71 | 动画来源自[Animate.css](https://github.com/daneden/animate.css),这里仅仅是对动画进行整理分类,构建为less文件,原有的一些零散的动画,将他整理到一起,比如一个bounceUp动画,按照原来的路径退出,这里整理为bounceUp out的类,具体的动画支持如下 72 | (1) bounce类 73 | 74 | bounce、bounceUp、bounceRight、bounceDown、bounceLeft 75 | (2) fade类 76 | 77 | fade、fadeUp、fadeUpBig、fadeRight、fadeRightBig、fadeDown、fadeDownBig、fadeLeft、fadeLeftBig 78 | (3) flip类 79 | 80 | flipX、flipY 81 | (4) rotate类 82 | 83 | rotate、rotateDownLeft、rotateDownRight、rotateUpLeft、rotateUpRight 84 | (5) slide类 85 | 86 | slideUp、slideRight、slideDown、slideLeft 87 | (6) zoom类 88 | 89 | zoom、zoomUp、zoomRight、zoomDown、zoomLeft 90 | 91 | 92 | ###5.选择用到的css进行打包 93 | 为了将最后的动画css文件最小,力求需要动画的css打进来,不用的不加载,所以提供了一个config.json的文件,来进行配置,默认的情况下,所有的动画都是true,即开启,你可以根据自行需要将不需要的动画选项设置为false,然后grunt(css无压缩)or grunt:pro(css进行了压缩) 94 | 95 | 注:图片来源于百度&&谷歌 -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | 3 | 4 | grunt.initConfig({ 5 | pkg : grunt.file.readJSON("package.json"), 6 | less: { 7 | options: { 8 | paths: ["less"], 9 | compress: false, 10 | sourceMap: false 11 | }, 12 | main:{ 13 | files: [{ 14 | src:"src/less/tmp.less", 15 | dest:"build/css/animate.css" 16 | }] 17 | } 18 | }, 19 | autoprefixer: { // https://github.com/nDmitry/grunt-autoprefixer 20 | options: { 21 | browsers: ['last 2 versions', 'bb 10'] 22 | }, 23 | no_dest: { 24 | src: 'build/css/animate.css' // output file 25 | } 26 | }, 27 | cssmin: { 28 | main :{ 29 | files: [{ 30 | expand: true, 31 | cwd: 'build/css/', 32 | src: ['*.css'], 33 | dest:"build/css/" 34 | }] 35 | } 36 | }, 37 | copy :{ 38 | main:{ 39 | files: [{ 40 | expand: true, 41 | cwd: 'src/js/', 42 | src: ['**'], 43 | dest: 'build/js/' 44 | }] 45 | } 46 | }, 47 | uglify : { 48 | options: { 49 | report : 'gzip' 50 | }, 51 | pro :{ 52 | files: [{ 53 | expand : true, 54 | cwd : 'build/js/', 55 | src : '**/**.js', 56 | dest : 'build/js/' 57 | }] 58 | } 59 | }, 60 | }); 61 | 62 | 63 | var concatAnim = function () { 64 | 65 | var categories = grunt.file.readJSON('config.json'), 66 | category, files, file, fileArry = []; 67 | 68 | for(category in categories){ 69 | files = categories[category]; 70 | for(file in files){ 71 | if(files.hasOwnProperty(file) && files[file]){ 72 | fileArry.push("@import 'src/"+category+"/"+file+"';"); 73 | } 74 | } 75 | } 76 | 77 | 78 | var a = grunt.file.read('src/less/animate.less'); 79 | grunt.file.write('src/less/tmp.less',a.replace('/*import animate*/',fileArry.join(''))); 80 | 81 | grunt.task.run('less:main'); 82 | grunt.task.run('clean-Animate'); 83 | }; 84 | 85 | var cleanAnimateTmp = function(){ 86 | grunt.file.delete('src/less/tmp.less'); 87 | }; 88 | 89 | grunt.registerTask('cancat-Animate','concat animate less',concatAnim); 90 | grunt.registerTask('clean-Animate','clean animate less tmp',cleanAnimateTmp); 91 | 92 | 93 | /*deal with css*/ 94 | grunt.loadNpmTasks('grunt-contrib-less'); 95 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 96 | grunt.loadNpmTasks('grunt-autoprefixer'); 97 | grunt.loadNpmTasks('grunt-contrib-copy'); 98 | grunt.loadNpmTasks('grunt-contrib-uglify'); 99 | 100 | /*different task 'less:main','autoprefixer','copy:main',*/ 101 | grunt.registerTask('default', ['cancat-Animate','autoprefixer','copy:main']); 102 | grunt.registerTask('pro', ['cancat-Animate','autoprefixer','cssmin:main','copy:main','uglify:pro']); 103 | 104 | }; 105 | -------------------------------------------------------------------------------- /src/js/scroll.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | @description 类似幻灯片轮播的工具 4 | *@author tankpt 5 | *@email tinkpt@hotmail.com 6 | *@version 1.0 7 | */ 8 | ;(function(window,$){ 9 | /*浏览器支持的动画事件*/ 10 | var transitionEvent = (function(){ 11 | var t, 12 | el = document.createElement('fakeelement'), 13 | transitions = { 14 | 'WebkitAnimation' : 'webkitAnimationEnd', 15 | 'OAnimation' : 'oAnimationEnd', 16 | 'msAnimation' : 'MSAnimationEnd', 17 | 'animation' : 'animationend' 18 | }; 19 | 20 | for(t in transitions){ 21 | if( el.style[t] !== undefined ){ 22 | return transitions[t]; 23 | } 24 | } 25 | })(); 26 | 27 | /* 28 | *@para options(obj) 29 | *@para option.container 容器的选择器 30 | *@para option.attr 标签中data-**的属性名,定义动画名字默认是animate 31 | *@para option.delay 标签中默认延迟动画的名字data-*,默认是delay 32 | *@para option.preLoadNum 惰性加载的控制数量 33 | */ 34 | var SlidePage = function(options){ 35 | this.$container = $(options.container); 36 | this.attr = options.attr || 'animate'; 37 | this.lazyClass = options.delay || 'lazyload'; 38 | this.preLoadNum = options.preLoadNum || 3; 39 | this._initial(); 40 | } 41 | 42 | SlidePage.prototype._initial = function() { 43 | 44 | this.index = 0 ; 45 | /*缓存所有的页面DOM节点*/ 46 | this.pageArray = this.$container.find(".pt-page"); 47 | /*缓存子页面的数量*/ 48 | this.pageLength = this.pageArray.length; 49 | /*标识页面切换的过程中是否正在进行动画*/ 50 | this.isAnimating = false; 51 | /*存放所有页面节点的动画队列*/ 52 | this.animationArray = []; 53 | /*存放所有页面中开启了延迟加载的动画队列*/ 54 | this.childrenNodes = []; 55 | /*存放页面之中延迟加载的背景图*/ 56 | this.lazyArray =[]; 57 | 58 | var self = this, 59 | attr = this.attr; 60 | 61 | $.each(this.pageArray,function(index,item){ 62 | var $item = $(item); 63 | self.animationArray.push($item.data(attr)); 64 | self.childrenNodes.push($item.children(".removeable")); 65 | self.lazyArray.push(0); 66 | $item.css("z-index",index); 67 | }); 68 | 69 | /**首页的动画*/ 70 | this.pageArray.eq(this.index).addClass("pt-page-current"); 71 | this._showPage(this.index); 72 | }; 73 | 74 | SlidePage.prototype.nextPage = function() { 75 | if(!this.isAnimating && this.index != this.pageLength -1){ 76 | 77 | var outIndex = this.index, 78 | inIndex = ++this.index, 79 | outClass = this.animationArray[outIndex], 80 | $outNode = this.pageArray.eq(outIndex), 81 | inClass = this.animationArray[inIndex]+' animated', 82 | $inNode = this.pageArray.eq(inIndex), 83 | self = this; 84 | 85 | this.isAnimating = true; 86 | 87 | $inNode.addClass(inClass+' pt-page-current').one(transitionEvent,function(){ 88 | $outNode.removeClass('pt-page-current'); 89 | $inNode.removeClass(inClass); 90 | self._showPage(inIndex,outIndex); 91 | self.isAnimating = false; 92 | }) 93 | } 94 | }; 95 | 96 | SlidePage.prototype.prePage = function() { 97 | if(!this.isAnimating && this.index != 0){ 98 | 99 | var outIndex = this.index, 100 | inIndex = --this.index, 101 | outClass = this.animationArray[outIndex]+' out animated', 102 | $outNode = this.pageArray.eq(outIndex), 103 | inClass = this.animationArray[inIndex], 104 | $inNode = this.pageArray.eq(inIndex), 105 | self = this; 106 | 107 | this.isAnimating = true; 108 | 109 | /*往前翻,为了防止本页隐藏的时候出现白屏,先将上一页显示*/ 110 | $inNode.addClass('pt-page-current'); 111 | 112 | $outNode.addClass(outClass).one(transitionEvent,function(){ 113 | $outNode.removeClass(outClass+' pt-page-current'); 114 | self._showPage(inIndex,outIndex); 115 | self.isAnimating = false; 116 | }) 117 | } 118 | }; 119 | 120 | SlidePage.prototype._showPage = function(inIndex,outIndex){ 121 | var animateIn = this.childrenNodes[inIndex].data("animate")+' animated'; 122 | this.childrenNodes[inIndex].removeClass("removeable").addClass(animateIn); 123 | if(outIndex!= void 0){ 124 | var animateOut = this.childrenNodes[outIndex].data('animate')+' animated'; 125 | this.childrenNodes[outIndex].addClass("removeable").removeClass(animateOut); 126 | } 127 | this._lazyLoad(inIndex); 128 | }; 129 | 130 | SlidePage.prototype._lazyLoad = function(index){ 131 | for(var i = index, len = index+this.preLoadNum; i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Scroll 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |

1.bounce动画+背景惰性加载

19 |

bounceUp此处延迟1s

20 |
21 |
22 |

2.bounceUp 动画延迟0.2s

23 |

延迟1s

24 |
25 |
26 |

3.bounceRight Transitions

27 |

延迟1.2秒

28 |
29 |
30 |

4.bounceDown Transitions

31 |

2. delay2秒

32 |
33 |
34 |

5.bounceLeft Transitions

35 |

延迟1s

36 |
37 |
38 |

6.fade Transitions

39 |

延迟1s

40 |
41 |
42 |

7.fadeUp Transitions

43 |

延迟1s

44 |
45 |
46 |

8.fadeUpBig Transitions

47 |

延迟1s

48 |
49 |
50 |

9.fadeRight Transitions

51 |

延迟1s

52 |
53 |
54 |

10.fadeRightBig Transitions

55 |

延迟1s

56 |
57 |
58 |

11.fadeDown Transitions

59 |

延迟1s

60 |
61 |
62 |

12.fadeDownBig Transitions

63 |

延迟1s

64 |
65 |
66 |

13.fadeLeft Transitions

67 |

延迟1s

68 |
69 |
70 |

14.fadeLeftBig Transitions

71 |

延迟1s

72 |
73 |
74 |

15.flipX Transitions

75 |

延迟1s

76 |
77 |
78 |

16.flipY Transitions

79 |

延迟1s

80 |
81 |
82 |

17.rotate Transitions

83 |

延迟1s

84 |
85 |
86 |

18.rotateDownLeft Transitions

87 |

延迟1s

88 |
89 |
90 |

19.rotateDownRight Transitions

91 |

延迟1s

92 |
93 |
94 |

20.rotateUpLeft Transitions

95 |

延迟1s

96 |
97 |
98 |

21.rotateUpRight Transitions

99 |

延迟1s

100 |
101 |
102 |

22.slideUp Transitions

103 |

延迟1s

104 |
105 |
106 |

23.slideRight Transitions

107 |

延迟1s

108 |
109 |
110 |

24.slideDown Transitions

111 |

延迟1s

112 |
113 |
114 |

25.slideLeft Transitions

115 |

延迟1s

116 |
117 |
118 |

26.zoom Transitions

119 |

延迟1s

120 |
121 |
122 |

27.zoomUp Transitions

123 |

延迟1s

124 |
125 |
126 |

28.zoomRight Transitions

127 |

延迟1s

128 |
129 |
130 |

29.zoomDown Transitions

131 |

延迟1s

132 |
133 |
134 |

30.zoomLeft Transitions

135 |

延迟1s

136 |
137 |
138 | 139 | 140 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /src/js/zepto.js: -------------------------------------------------------------------------------- 1 | var Zepto = (function() { 2 | var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice, filter = emptyArray.filter, 3 | document = window.document, 4 | elementDisplay = {}, classCache = {}, 5 | cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, 6 | fragmentRE = /^\s*<(\w+|!)[^>]*>/, 7 | singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, 8 | tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 9 | rootNodeRE = /^(?:body|html)$/i, 10 | capitalRE = /([A-Z])/g, 11 | 12 | // special attributes that should be get/set via method calls 13 | methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'], 14 | 15 | adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], 16 | table = document.createElement('table'), 17 | tableRow = document.createElement('tr'), 18 | containers = { 19 | 'tr': document.createElement('tbody'), 20 | 'tbody': table, 'thead': table, 'tfoot': table, 21 | 'td': tableRow, 'th': tableRow, 22 | '*': document.createElement('div') 23 | }, 24 | readyRE = /complete|loaded|interactive/, 25 | simpleSelectorRE = /^[\w-]*$/, 26 | class2type = {}, 27 | toString = class2type.toString, 28 | zepto = {}, 29 | camelize, uniq, 30 | tempParent = document.createElement('div'), 31 | propMap = { 32 | 'tabindex': 'tabIndex', 33 | 'readonly': 'readOnly', 34 | 'for': 'htmlFor', 35 | 'class': 'className', 36 | 'maxlength': 'maxLength', 37 | 'cellspacing': 'cellSpacing', 38 | 'cellpadding': 'cellPadding', 39 | 'rowspan': 'rowSpan', 40 | 'colspan': 'colSpan', 41 | 'usemap': 'useMap', 42 | 'frameborder': 'frameBorder', 43 | 'contenteditable': 'contentEditable' 44 | }, 45 | isArray = Array.isArray || 46 | function(object){ return object instanceof Array } 47 | 48 | zepto.matches = function(element, selector) { 49 | if (!selector || !element || element.nodeType !== 1) return false 50 | var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || 51 | element.oMatchesSelector || element.matchesSelector 52 | if (matchesSelector) return matchesSelector.call(element, selector) 53 | // fall back to performing a selector: 54 | var match, parent = element.parentNode, temp = !parent 55 | if (temp) (parent = tempParent).appendChild(element) 56 | match = ~zepto.qsa(parent, selector).indexOf(element) 57 | temp && tempParent.removeChild(element) 58 | return match 59 | } 60 | 61 | function type(obj) { 62 | return obj == null ? String(obj) : 63 | class2type[toString.call(obj)] || "object" 64 | } 65 | 66 | function isFunction(value) { return type(value) == "function" } 67 | function isWindow(obj) { return obj != null && obj == obj.window } 68 | function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } 69 | function isObject(obj) { return type(obj) == "object" } 70 | function isPlainObject(obj) { 71 | return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype 72 | } 73 | function likeArray(obj) { return typeof obj.length == 'number' } 74 | 75 | function compact(array) { return filter.call(array, function(item){ return item != null }) } 76 | function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array } 77 | camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } 78 | function dasherize(str) { 79 | return str.replace(/::/g, '/') 80 | .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') 81 | .replace(/([a-z\d])([A-Z])/g, '$1_$2') 82 | .replace(/_/g, '-') 83 | .toLowerCase() 84 | } 85 | uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) } 86 | 87 | function classRE(name) { 88 | return name in classCache ? 89 | classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) 90 | } 91 | 92 | function maybeAddPx(name, value) { 93 | return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value 94 | } 95 | 96 | function defaultDisplay(nodeName) { 97 | var element, display 98 | if (!elementDisplay[nodeName]) { 99 | element = document.createElement(nodeName) 100 | document.body.appendChild(element) 101 | display = getComputedStyle(element, '').getPropertyValue("display") 102 | element.parentNode.removeChild(element) 103 | display == "none" && (display = "block") 104 | elementDisplay[nodeName] = display 105 | } 106 | return elementDisplay[nodeName] 107 | } 108 | 109 | function children(element) { 110 | return 'children' in element ? 111 | slice.call(element.children) : 112 | $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node }) 113 | } 114 | 115 | // `$.zepto.fragment` takes a html string and an optional tag name 116 | // to generate DOM nodes nodes from the given html string. 117 | // The generated DOM nodes are returned as an array. 118 | // This function can be overriden in plugins for example to make 119 | // it compatible with browsers that don't support the DOM fully. 120 | zepto.fragment = function(html, name, properties) { 121 | var dom, nodes, container 122 | 123 | // A special case optimization for a single tag 124 | if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)) 125 | 126 | if (!dom) { 127 | if (html.replace) html = html.replace(tagExpanderRE, "<$1>") 128 | if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 129 | if (!(name in containers)) name = '*' 130 | 131 | container = containers[name] 132 | container.innerHTML = '' + html 133 | dom = $.each(slice.call(container.childNodes), function(){ 134 | container.removeChild(this) 135 | }) 136 | } 137 | 138 | if (isPlainObject(properties)) { 139 | nodes = $(dom) 140 | $.each(properties, function(key, value) { 141 | if (methodAttributes.indexOf(key) > -1) nodes[key](value) 142 | else nodes.attr(key, value) 143 | }) 144 | } 145 | 146 | return dom 147 | } 148 | 149 | // `$.zepto.Z` swaps out the prototype of the given `dom` array 150 | // of nodes with `$.fn` and thus supplying all the Zepto functions 151 | // to the array. Note that `__proto__` is not supported on Internet 152 | // Explorer. This method can be overriden in plugins. 153 | zepto.Z = function(dom, selector) { 154 | dom = dom || [] 155 | dom.__proto__ = $.fn 156 | dom.selector = selector || '' 157 | return dom 158 | } 159 | 160 | // `$.zepto.isZ` should return `true` if the given object is a Zepto 161 | // collection. This method can be overriden in plugins. 162 | zepto.isZ = function(object) { 163 | return object instanceof zepto.Z 164 | } 165 | 166 | // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and 167 | // takes a CSS selector and an optional context (and handles various 168 | // special cases). 169 | // This method can be overriden in plugins. 170 | zepto.init = function(selector, context) { 171 | var dom 172 | // If nothing given, return an empty Zepto collection 173 | if (!selector) return zepto.Z() 174 | // Optimize for string selectors 175 | else if (typeof selector == 'string') { 176 | selector = selector.trim() 177 | // If it's a html fragment, create nodes from it 178 | // Note: In both Chrome 21 and Firefox 15, DOM error 12 179 | // is thrown if the fragment doesn't begin with < 180 | if (selector[0] == '<' && fragmentRE.test(selector)) 181 | dom = zepto.fragment(selector, RegExp.$1, context), selector = null 182 | // If there's a context, create a collection on that context first, and select 183 | // nodes from there 184 | else if (context !== undefined) return $(context).find(selector) 185 | // If it's a CSS selector, use it to select nodes. 186 | else dom = zepto.qsa(document, selector) 187 | } 188 | // If a function is given, call it when the DOM is ready 189 | else if (isFunction(selector)) return $(document).ready(selector) 190 | // If a Zepto collection is given, just return it 191 | else if (zepto.isZ(selector)) return selector 192 | else { 193 | // normalize array if an array of nodes is given 194 | if (isArray(selector)) dom = compact(selector) 195 | // Wrap DOM nodes. 196 | else if (isObject(selector)) 197 | dom = [selector], selector = null 198 | // If it's a html fragment, create nodes from it 199 | else if (fragmentRE.test(selector)) 200 | dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null 201 | // If there's a context, create a collection on that context first, and select 202 | // nodes from there 203 | else if (context !== undefined) return $(context).find(selector) 204 | // And last but no least, if it's a CSS selector, use it to select nodes. 205 | else dom = zepto.qsa(document, selector) 206 | } 207 | // create a new Zepto collection from the nodes found 208 | return zepto.Z(dom, selector) 209 | } 210 | 211 | // `$` will be the base `Zepto` object. When calling this 212 | // function just call `$.zepto.init, which makes the implementation 213 | // details of selecting nodes and creating Zepto collections 214 | // patchable in plugins. 215 | $ = function(selector, context){ 216 | return zepto.init(selector, context) 217 | } 218 | 219 | function extend(target, source, deep) { 220 | for (key in source) 221 | if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { 222 | if (isPlainObject(source[key]) && !isPlainObject(target[key])) 223 | target[key] = {} 224 | if (isArray(source[key]) && !isArray(target[key])) 225 | target[key] = [] 226 | extend(target[key], source[key], deep) 227 | } 228 | else if (source[key] !== undefined) target[key] = source[key] 229 | } 230 | 231 | // Copy all but undefined properties from one or more 232 | // objects to the `target` object. 233 | $.extend = function(target){ 234 | var deep, args = slice.call(arguments, 1) 235 | if (typeof target == 'boolean') { 236 | deep = target 237 | target = args.shift() 238 | } 239 | args.forEach(function(arg){ extend(target, arg, deep) }) 240 | return target 241 | } 242 | 243 | // `$.zepto.qsa` is Zepto's CSS selector implementation which 244 | // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. 245 | // This method can be overriden in plugins. 246 | zepto.qsa = function(element, selector){ 247 | var found, 248 | maybeID = selector[0] == '#', 249 | maybeClass = !maybeID && selector[0] == '.', 250 | nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked 251 | isSimple = simpleSelectorRE.test(nameOnly) 252 | return (isDocument(element) && isSimple && maybeID) ? 253 | ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : 254 | (element.nodeType !== 1 && element.nodeType !== 9) ? [] : 255 | slice.call( 256 | isSimple && !maybeID ? 257 | maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class 258 | element.getElementsByTagName(selector) : // Or a tag 259 | element.querySelectorAll(selector) // Or it's not simple, and we need to query all 260 | ) 261 | } 262 | 263 | function filtered(nodes, selector) { 264 | return selector == null ? $(nodes) : $(nodes).filter(selector) 265 | } 266 | 267 | $.contains = document.documentElement.contains ? 268 | function(parent, node) { 269 | return parent !== node && parent.contains(node) 270 | } : 271 | function(parent, node) { 272 | while (node && (node = node.parentNode)) 273 | if (node === parent) return true 274 | return false 275 | } 276 | 277 | function funcArg(context, arg, idx, payload) { 278 | return isFunction(arg) ? arg.call(context, idx, payload) : arg 279 | } 280 | 281 | function setAttribute(node, name, value) { 282 | value == null ? node.removeAttribute(name) : node.setAttribute(name, value) 283 | } 284 | 285 | // access className property while respecting SVGAnimatedString 286 | function className(node, value){ 287 | var klass = node.className || '', 288 | svg = klass && klass.baseVal !== undefined 289 | 290 | if (value === undefined) return svg ? klass.baseVal : klass 291 | svg ? (klass.baseVal = value) : (node.className = value) 292 | } 293 | 294 | // "true" => true 295 | // "false" => false 296 | // "null" => null 297 | // "42" => 42 298 | // "42.5" => 42.5 299 | // "08" => "08" 300 | // JSON => parse if valid 301 | // String => self 302 | function deserializeValue(value) { 303 | try { 304 | return value ? 305 | value == "true" || 306 | ( value == "false" ? false : 307 | value == "null" ? null : 308 | +value + "" == value ? +value : 309 | /^[\[\{]/.test(value) ? $.parseJSON(value) : 310 | value ) 311 | : value 312 | } catch(e) { 313 | return value 314 | } 315 | } 316 | 317 | $.type = type 318 | $.isFunction = isFunction 319 | $.isWindow = isWindow 320 | $.isArray = isArray 321 | $.isPlainObject = isPlainObject 322 | 323 | $.isEmptyObject = function(obj) { 324 | var name 325 | for (name in obj) return false 326 | return true 327 | } 328 | 329 | $.inArray = function(elem, array, i){ 330 | return emptyArray.indexOf.call(array, elem, i) 331 | } 332 | 333 | $.camelCase = camelize 334 | $.trim = function(str) { 335 | return str == null ? "" : String.prototype.trim.call(str) 336 | } 337 | 338 | // plugin compatibility 339 | $.uuid = 0 340 | $.support = { } 341 | $.expr = { } 342 | 343 | $.map = function(elements, callback){ 344 | var value, values = [], i, key 345 | if (likeArray(elements)) 346 | for (i = 0; i < elements.length; i++) { 347 | value = callback(elements[i], i) 348 | if (value != null) values.push(value) 349 | } 350 | else 351 | for (key in elements) { 352 | value = callback(elements[key], key) 353 | if (value != null) values.push(value) 354 | } 355 | return flatten(values) 356 | } 357 | 358 | $.each = function(elements, callback){ 359 | var i, key 360 | if (likeArray(elements)) { 361 | for (i = 0; i < elements.length; i++) 362 | if (callback.call(elements[i], i, elements[i]) === false) return elements 363 | } else { 364 | for (key in elements) 365 | if (callback.call(elements[key], key, elements[key]) === false) return elements 366 | } 367 | 368 | return elements 369 | } 370 | 371 | $.grep = function(elements, callback){ 372 | return filter.call(elements, callback) 373 | } 374 | 375 | if (window.JSON) $.parseJSON = JSON.parse 376 | 377 | // Populate the class2type map 378 | $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { 379 | class2type[ "[object " + name + "]" ] = name.toLowerCase() 380 | }) 381 | 382 | // Define methods that will be available on all 383 | // Zepto collections 384 | $.fn = { 385 | // Because a collection acts like an array 386 | // copy over these useful array functions. 387 | forEach: emptyArray.forEach, 388 | reduce: emptyArray.reduce, 389 | push: emptyArray.push, 390 | sort: emptyArray.sort, 391 | indexOf: emptyArray.indexOf, 392 | concat: emptyArray.concat, 393 | 394 | // `map` and `slice` in the jQuery API work differently 395 | // from their array counterparts 396 | map: function(fn){ 397 | return $($.map(this, function(el, i){ return fn.call(el, i, el) })) 398 | }, 399 | slice: function(){ 400 | return $(slice.apply(this, arguments)) 401 | }, 402 | 403 | ready: function(callback){ 404 | // need to check if document.body exists for IE as that browser reports 405 | // document ready when it hasn't yet created the body element 406 | if (readyRE.test(document.readyState) && document.body) callback($) 407 | else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false) 408 | return this 409 | }, 410 | get: function(idx){ 411 | return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] 412 | }, 413 | toArray: function(){ return this.get() }, 414 | size: function(){ 415 | return this.length 416 | }, 417 | remove: function(){ 418 | return this.each(function(){ 419 | if (this.parentNode != null) 420 | this.parentNode.removeChild(this) 421 | }) 422 | }, 423 | each: function(callback){ 424 | emptyArray.every.call(this, function(el, idx){ 425 | return callback.call(el, idx, el) !== false 426 | }) 427 | return this 428 | }, 429 | filter: function(selector){ 430 | if (isFunction(selector)) return this.not(this.not(selector)) 431 | return $(filter.call(this, function(element){ 432 | return zepto.matches(element, selector) 433 | })) 434 | }, 435 | add: function(selector,context){ 436 | return $(uniq(this.concat($(selector,context)))) 437 | }, 438 | is: function(selector){ 439 | return this.length > 0 && zepto.matches(this[0], selector) 440 | }, 441 | not: function(selector){ 442 | var nodes=[] 443 | if (isFunction(selector) && selector.call !== undefined) 444 | this.each(function(idx){ 445 | if (!selector.call(this,idx)) nodes.push(this) 446 | }) 447 | else { 448 | var excludes = typeof selector == 'string' ? this.filter(selector) : 449 | (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) 450 | this.forEach(function(el){ 451 | if (excludes.indexOf(el) < 0) nodes.push(el) 452 | }) 453 | } 454 | return $(nodes) 455 | }, 456 | has: function(selector){ 457 | return this.filter(function(){ 458 | return isObject(selector) ? 459 | $.contains(this, selector) : 460 | $(this).find(selector).size() 461 | }) 462 | }, 463 | eq: function(idx){ 464 | return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) 465 | }, 466 | first: function(){ 467 | var el = this[0] 468 | return el && !isObject(el) ? el : $(el) 469 | }, 470 | last: function(){ 471 | var el = this[this.length - 1] 472 | return el && !isObject(el) ? el : $(el) 473 | }, 474 | find: function(selector){ 475 | var result, $this = this 476 | if (!selector) result = $() 477 | else if (typeof selector == 'object') 478 | result = $(selector).filter(function(){ 479 | var node = this 480 | return emptyArray.some.call($this, function(parent){ 481 | return $.contains(parent, node) 482 | }) 483 | }) 484 | else if (this.length == 1) result = $(zepto.qsa(this[0], selector)) 485 | else result = this.map(function(){ return zepto.qsa(this, selector) }) 486 | return result 487 | }, 488 | closest: function(selector, context){ 489 | var node = this[0], collection = false 490 | if (typeof selector == 'object') collection = $(selector) 491 | while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))) 492 | node = node !== context && !isDocument(node) && node.parentNode 493 | return $(node) 494 | }, 495 | parents: function(selector){ 496 | var ancestors = [], nodes = this 497 | while (nodes.length > 0) 498 | nodes = $.map(nodes, function(node){ 499 | if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) { 500 | ancestors.push(node) 501 | return node 502 | } 503 | }) 504 | return filtered(ancestors, selector) 505 | }, 506 | parent: function(selector){ 507 | return filtered(uniq(this.pluck('parentNode')), selector) 508 | }, 509 | children: function(selector){ 510 | return filtered(this.map(function(){ return children(this) }), selector) 511 | }, 512 | contents: function() { 513 | return this.map(function() { return slice.call(this.childNodes) }) 514 | }, 515 | siblings: function(selector){ 516 | return filtered(this.map(function(i, el){ 517 | return filter.call(children(el.parentNode), function(child){ return child!==el }) 518 | }), selector) 519 | }, 520 | empty: function(){ 521 | return this.each(function(){ this.innerHTML = '' }) 522 | }, 523 | // `pluck` is borrowed from Prototype.js 524 | pluck: function(property){ 525 | return $.map(this, function(el){ return el[property] }) 526 | }, 527 | show: function(){ 528 | return this.each(function(){ 529 | this.style.display == "none" && (this.style.display = '') 530 | if (getComputedStyle(this, '').getPropertyValue("display") == "none") 531 | this.style.display = defaultDisplay(this.nodeName) 532 | }) 533 | }, 534 | replaceWith: function(newContent){ 535 | return this.before(newContent).remove() 536 | }, 537 | wrap: function(structure){ 538 | var func = isFunction(structure) 539 | if (this[0] && !func) 540 | var dom = $(structure).get(0), 541 | clone = dom.parentNode || this.length > 1 542 | 543 | return this.each(function(index){ 544 | $(this).wrapAll( 545 | func ? structure.call(this, index) : 546 | clone ? dom.cloneNode(true) : dom 547 | ) 548 | }) 549 | }, 550 | wrapAll: function(structure){ 551 | if (this[0]) { 552 | $(this[0]).before(structure = $(structure)) 553 | var children 554 | // drill down to the inmost element 555 | while ((children = structure.children()).length) structure = children.first() 556 | $(structure).append(this) 557 | } 558 | return this 559 | }, 560 | wrapInner: function(structure){ 561 | var func = isFunction(structure) 562 | return this.each(function(index){ 563 | var self = $(this), contents = self.contents(), 564 | dom = func ? structure.call(this, index) : structure 565 | contents.length ? contents.wrapAll(dom) : self.append(dom) 566 | }) 567 | }, 568 | unwrap: function(){ 569 | this.parent().each(function(){ 570 | $(this).replaceWith($(this).children()) 571 | }) 572 | return this 573 | }, 574 | clone: function(){ 575 | return this.map(function(){ return this.cloneNode(true) }) 576 | }, 577 | hide: function(){ 578 | return this.css("display", "none") 579 | }, 580 | toggle: function(setting){ 581 | return this.each(function(){ 582 | var el = $(this) 583 | ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide() 584 | }) 585 | }, 586 | prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') }, 587 | next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') }, 588 | html: function(html){ 589 | return 0 in arguments ? 590 | this.each(function(idx){ 591 | var originHtml = this.innerHTML 592 | $(this).empty().append( funcArg(this, html, idx, originHtml) ) 593 | }) : 594 | (0 in this ? this[0].innerHTML : null) 595 | }, 596 | text: function(text){ 597 | return 0 in arguments ? 598 | this.each(function(idx){ 599 | var newText = funcArg(this, text, idx, this.textContent) 600 | this.textContent = newText == null ? '' : ''+newText 601 | }) : 602 | (0 in this ? this[0].textContent : null) 603 | }, 604 | attr: function(name, value){ 605 | var result 606 | return (typeof name == 'string' && !(1 in arguments)) ? 607 | (!this.length || this[0].nodeType !== 1 ? undefined : 608 | (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result 609 | ) : 610 | this.each(function(idx){ 611 | if (this.nodeType !== 1) return 612 | if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) 613 | else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) 614 | }) 615 | }, 616 | removeAttr: function(name){ 617 | return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){ 618 | setAttribute(this, attribute) 619 | }, this)}) 620 | }, 621 | prop: function(name, value){ 622 | name = propMap[name] || name 623 | return (1 in arguments) ? 624 | this.each(function(idx){ 625 | this[name] = funcArg(this, value, idx, this[name]) 626 | }) : 627 | (this[0] && this[0][name]) 628 | }, 629 | data: function(name, value){ 630 | var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase() 631 | 632 | var data = (1 in arguments) ? 633 | this.attr(attrName, value) : 634 | this.attr(attrName) 635 | 636 | return data !== null ? deserializeValue(data) : undefined 637 | }, 638 | val: function(value){ 639 | return 0 in arguments ? 640 | this.each(function(idx){ 641 | this.value = funcArg(this, value, idx, this.value) 642 | }) : 643 | (this[0] && (this[0].multiple ? 644 | $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') : 645 | this[0].value) 646 | ) 647 | }, 648 | offset: function(coordinates){ 649 | if (coordinates) return this.each(function(index){ 650 | var $this = $(this), 651 | coords = funcArg(this, coordinates, index, $this.offset()), 652 | parentOffset = $this.offsetParent().offset(), 653 | props = { 654 | top: coords.top - parentOffset.top, 655 | left: coords.left - parentOffset.left 656 | } 657 | 658 | if ($this.css('position') == 'static') props['position'] = 'relative' 659 | $this.css(props) 660 | }) 661 | if (!this.length) return null 662 | var obj = this[0].getBoundingClientRect() 663 | return { 664 | left: obj.left + window.pageXOffset, 665 | top: obj.top + window.pageYOffset, 666 | width: Math.round(obj.width), 667 | height: Math.round(obj.height) 668 | } 669 | }, 670 | css: function(property, value){ 671 | if (arguments.length < 2) { 672 | var computedStyle, element = this[0] 673 | if(!element) return 674 | computedStyle = getComputedStyle(element, '') 675 | if (typeof property == 'string') 676 | return element.style[camelize(property)] || computedStyle.getPropertyValue(property) 677 | else if (isArray(property)) { 678 | var props = {} 679 | $.each(property, function(_, prop){ 680 | props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop)) 681 | }) 682 | return props 683 | } 684 | } 685 | 686 | var css = '' 687 | if (type(property) == 'string') { 688 | if (!value && value !== 0) 689 | this.each(function(){ this.style.removeProperty(dasherize(property)) }) 690 | else 691 | css = dasherize(property) + ":" + maybeAddPx(property, value) 692 | } else { 693 | for (key in property) 694 | if (!property[key] && property[key] !== 0) 695 | this.each(function(){ this.style.removeProperty(dasherize(key)) }) 696 | else 697 | css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' 698 | } 699 | 700 | return this.each(function(){ this.style.cssText += ';' + css }) 701 | }, 702 | index: function(element){ 703 | return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) 704 | }, 705 | hasClass: function(name){ 706 | if (!name) return false 707 | return emptyArray.some.call(this, function(el){ 708 | return this.test(className(el)) 709 | }, classRE(name)) 710 | }, 711 | addClass: function(name){ 712 | if (!name) return this 713 | return this.each(function(idx){ 714 | if (!('className' in this)) return 715 | classList = [] 716 | var cls = className(this), newName = funcArg(this, name, idx, cls) 717 | newName.split(/\s+/g).forEach(function(klass){ 718 | if (!$(this).hasClass(klass)) classList.push(klass) 719 | }, this) 720 | classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) 721 | }) 722 | }, 723 | removeClass: function(name){ 724 | return this.each(function(idx){ 725 | if (!('className' in this)) return 726 | if (name === undefined) return className(this, '') 727 | classList = className(this) 728 | funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ 729 | classList = classList.replace(classRE(klass), " ") 730 | }) 731 | className(this, classList.trim()) 732 | }) 733 | }, 734 | toggleClass: function(name, when){ 735 | if (!name) return this 736 | return this.each(function(idx){ 737 | var $this = $(this), names = funcArg(this, name, idx, className(this)) 738 | names.split(/\s+/g).forEach(function(klass){ 739 | (when === undefined ? !$this.hasClass(klass) : when) ? 740 | $this.addClass(klass) : $this.removeClass(klass) 741 | }) 742 | }) 743 | }, 744 | scrollTop: function(value){ 745 | if (!this.length) return 746 | var hasScrollTop = 'scrollTop' in this[0] 747 | if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset 748 | return this.each(hasScrollTop ? 749 | function(){ this.scrollTop = value } : 750 | function(){ this.scrollTo(this.scrollX, value) }) 751 | }, 752 | scrollLeft: function(value){ 753 | if (!this.length) return 754 | var hasScrollLeft = 'scrollLeft' in this[0] 755 | if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset 756 | return this.each(hasScrollLeft ? 757 | function(){ this.scrollLeft = value } : 758 | function(){ this.scrollTo(value, this.scrollY) }) 759 | }, 760 | position: function() { 761 | if (!this.length) return 762 | 763 | var elem = this[0], 764 | // Get *real* offsetParent 765 | offsetParent = this.offsetParent(), 766 | // Get correct offsets 767 | offset = this.offset(), 768 | parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset() 769 | 770 | // Subtract element margins 771 | // note: when an element has margin: auto the offsetLeft and marginLeft 772 | // are the same in Safari causing offset.left to incorrectly be 0 773 | offset.top -= parseFloat( $(elem).css('margin-top') ) || 0 774 | offset.left -= parseFloat( $(elem).css('margin-left') ) || 0 775 | 776 | // Add offsetParent borders 777 | parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0 778 | parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0 779 | 780 | // Subtract the two offsets 781 | return { 782 | top: offset.top - parentOffset.top, 783 | left: offset.left - parentOffset.left 784 | } 785 | }, 786 | offsetParent: function() { 787 | return this.map(function(){ 788 | var parent = this.offsetParent || document.body 789 | while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static") 790 | parent = parent.offsetParent 791 | return parent 792 | }) 793 | } 794 | } 795 | 796 | // for now 797 | $.fn.detach = $.fn.remove 798 | 799 | // Generate the `width` and `height` functions 800 | ;['width', 'height'].forEach(function(dimension){ 801 | var dimensionProperty = 802 | dimension.replace(/./, function(m){ return m[0].toUpperCase() }) 803 | 804 | $.fn[dimension] = function(value){ 805 | var offset, el = this[0] 806 | if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] : 807 | isDocument(el) ? el.documentElement['scroll' + dimensionProperty] : 808 | (offset = this.offset()) && offset[dimension] 809 | else return this.each(function(idx){ 810 | el = $(this) 811 | el.css(dimension, funcArg(this, value, idx, el[dimension]())) 812 | }) 813 | } 814 | }) 815 | 816 | function traverseNode(node, fun) { 817 | fun(node) 818 | for (var i = 0, len = node.childNodes.length; i < len; i++) 819 | traverseNode(node.childNodes[i], fun) 820 | } 821 | 822 | // Generate the `after`, `prepend`, `before`, `append`, 823 | // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. 824 | adjacencyOperators.forEach(function(operator, operatorIndex) { 825 | var inside = operatorIndex % 2 //=> prepend, append 826 | 827 | $.fn[operator] = function(){ 828 | // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings 829 | var argType, nodes = $.map(arguments, function(arg) { 830 | argType = type(arg) 831 | return argType == "object" || argType == "array" || arg == null ? 832 | arg : zepto.fragment(arg) 833 | }), 834 | parent, copyByClone = this.length > 1 835 | if (nodes.length < 1) return this 836 | 837 | return this.each(function(_, target){ 838 | parent = inside ? target : target.parentNode 839 | 840 | // convert all methods to a "before" operation 841 | target = operatorIndex == 0 ? target.nextSibling : 842 | operatorIndex == 1 ? target.firstChild : 843 | operatorIndex == 2 ? target : 844 | null 845 | 846 | var parentInDocument = $.contains(document.documentElement, parent) 847 | 848 | nodes.forEach(function(node){ 849 | if (copyByClone) node = node.cloneNode(true) 850 | else if (!parent) return $(node).remove() 851 | 852 | parent.insertBefore(node, target) 853 | if (parentInDocument) traverseNode(node, function(el){ 854 | if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' && 855 | (!el.type || el.type === 'text/javascript') && !el.src) 856 | window['eval'].call(window, el.innerHTML) 857 | }) 858 | }) 859 | }) 860 | } 861 | 862 | // after => insertAfter 863 | // prepend => prependTo 864 | // before => insertBefore 865 | // append => appendTo 866 | $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){ 867 | $(html)[operator](this) 868 | return this 869 | } 870 | }) 871 | 872 | zepto.Z.prototype = $.fn 873 | 874 | // Export internal API functions in the `$.zepto` namespace 875 | zepto.uniq = uniq 876 | zepto.deserializeValue = deserializeValue 877 | $.zepto = zepto 878 | 879 | return $ 880 | })() 881 | 882 | window.Zepto = Zepto 883 | window.$ === undefined && (window.$ = Zepto) 884 | 885 | ;(function($){ 886 | var _zid = 1, undefined, 887 | slice = Array.prototype.slice, 888 | isFunction = $.isFunction, 889 | isString = function(obj){ return typeof obj == 'string' }, 890 | handlers = {}, 891 | specialEvents={}, 892 | focusinSupported = 'onfocusin' in window, 893 | focus = { focus: 'focusin', blur: 'focusout' }, 894 | hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' } 895 | 896 | specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' 897 | 898 | function zid(element) { 899 | return element._zid || (element._zid = _zid++) 900 | } 901 | function findHandlers(element, event, fn, selector) { 902 | event = parse(event) 903 | if (event.ns) var matcher = matcherFor(event.ns) 904 | return (handlers[zid(element)] || []).filter(function(handler) { 905 | return handler 906 | && (!event.e || handler.e == event.e) 907 | && (!event.ns || matcher.test(handler.ns)) 908 | && (!fn || zid(handler.fn) === zid(fn)) 909 | && (!selector || handler.sel == selector) 910 | }) 911 | } 912 | function parse(event) { 913 | var parts = ('' + event).split('.') 914 | return {e: parts[0], ns: parts.slice(1).sort().join(' ')} 915 | } 916 | function matcherFor(ns) { 917 | return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') 918 | } 919 | 920 | function eventCapture(handler, captureSetting) { 921 | return handler.del && 922 | (!focusinSupported && (handler.e in focus)) || 923 | !!captureSetting 924 | } 925 | 926 | function realEvent(type) { 927 | return hover[type] || (focusinSupported && focus[type]) || type 928 | } 929 | 930 | function add(element, events, fn, data, selector, delegator, capture){ 931 | var id = zid(element), set = (handlers[id] || (handlers[id] = [])) 932 | events.split(/\s/).forEach(function(event){ 933 | if (event == 'ready') return $(document).ready(fn) 934 | var handler = parse(event) 935 | handler.fn = fn 936 | handler.sel = selector 937 | // emulate mouseenter, mouseleave 938 | if (handler.e in hover) fn = function(e){ 939 | var related = e.relatedTarget 940 | if (!related || (related !== this && !$.contains(this, related))) 941 | return handler.fn.apply(this, arguments) 942 | } 943 | handler.del = delegator 944 | var callback = delegator || fn 945 | handler.proxy = function(e){ 946 | e = compatible(e) 947 | if (e.isImmediatePropagationStopped()) return 948 | e.data = data 949 | var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args)) 950 | if (result === false) e.preventDefault(), e.stopPropagation() 951 | return result 952 | } 953 | handler.i = set.length 954 | set.push(handler) 955 | if ('addEventListener' in element) 956 | element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 957 | }) 958 | } 959 | function remove(element, events, fn, selector, capture){ 960 | var id = zid(element) 961 | ;(events || '').split(/\s/).forEach(function(event){ 962 | findHandlers(element, event, fn, selector).forEach(function(handler){ 963 | delete handlers[id][handler.i] 964 | if ('removeEventListener' in element) 965 | element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 966 | }) 967 | }) 968 | } 969 | 970 | $.event = { add: add, remove: remove } 971 | 972 | $.proxy = function(fn, context) { 973 | var args = (2 in arguments) && slice.call(arguments, 2) 974 | if (isFunction(fn)) { 975 | var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) } 976 | proxyFn._zid = zid(fn) 977 | return proxyFn 978 | } else if (isString(context)) { 979 | if (args) { 980 | args.unshift(fn[context], fn) 981 | return $.proxy.apply(null, args) 982 | } else { 983 | return $.proxy(fn[context], fn) 984 | } 985 | } else { 986 | throw new TypeError("expected function") 987 | } 988 | } 989 | 990 | $.fn.bind = function(event, data, callback){ 991 | return this.on(event, data, callback) 992 | } 993 | $.fn.unbind = function(event, callback){ 994 | return this.off(event, callback) 995 | } 996 | $.fn.one = function(event, selector, data, callback){ 997 | return this.on(event, selector, data, callback, 1) 998 | } 999 | 1000 | var returnTrue = function(){return true}, 1001 | returnFalse = function(){return false}, 1002 | ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$)/, 1003 | eventMethods = { 1004 | preventDefault: 'isDefaultPrevented', 1005 | stopImmediatePropagation: 'isImmediatePropagationStopped', 1006 | stopPropagation: 'isPropagationStopped' 1007 | } 1008 | 1009 | function compatible(event, source) { 1010 | if (source || !event.isDefaultPrevented) { 1011 | source || (source = event) 1012 | 1013 | $.each(eventMethods, function(name, predicate) { 1014 | var sourceMethod = source[name] 1015 | event[name] = function(){ 1016 | this[predicate] = returnTrue 1017 | return sourceMethod && sourceMethod.apply(source, arguments) 1018 | } 1019 | event[predicate] = returnFalse 1020 | }) 1021 | 1022 | if (source.defaultPrevented !== undefined ? source.defaultPrevented : 1023 | 'returnValue' in source ? source.returnValue === false : 1024 | source.getPreventDefault && source.getPreventDefault()) 1025 | event.isDefaultPrevented = returnTrue 1026 | } 1027 | return event 1028 | } 1029 | 1030 | function createProxy(event) { 1031 | var key, proxy = { originalEvent: event } 1032 | for (key in event) 1033 | if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key] 1034 | 1035 | return compatible(proxy, event) 1036 | } 1037 | 1038 | $.fn.delegate = function(selector, event, callback){ 1039 | return this.on(event, selector, callback) 1040 | } 1041 | $.fn.undelegate = function(selector, event, callback){ 1042 | return this.off(event, selector, callback) 1043 | } 1044 | 1045 | $.fn.live = function(event, callback){ 1046 | $(document.body).delegate(this.selector, event, callback) 1047 | return this 1048 | } 1049 | $.fn.die = function(event, callback){ 1050 | $(document.body).undelegate(this.selector, event, callback) 1051 | return this 1052 | } 1053 | 1054 | $.fn.on = function(event, selector, data, callback, one){ 1055 | var autoRemove, delegator, $this = this 1056 | if (event && !isString(event)) { 1057 | $.each(event, function(type, fn){ 1058 | $this.on(type, selector, data, fn, one) 1059 | }) 1060 | return $this 1061 | } 1062 | 1063 | if (!isString(selector) && !isFunction(callback) && callback !== false) 1064 | callback = data, data = selector, selector = undefined 1065 | if (isFunction(data) || data === false) 1066 | callback = data, data = undefined 1067 | 1068 | if (callback === false) callback = returnFalse 1069 | 1070 | return $this.each(function(_, element){ 1071 | if (one) autoRemove = function(e){ 1072 | remove(element, e.type, callback) 1073 | return callback.apply(this, arguments) 1074 | } 1075 | 1076 | if (selector) delegator = function(e){ 1077 | var evt, match = $(e.target).closest(selector, element).get(0) 1078 | if (match && match !== element) { 1079 | evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) 1080 | return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1))) 1081 | } 1082 | } 1083 | 1084 | add(element, event, callback, data, selector, delegator || autoRemove) 1085 | }) 1086 | } 1087 | $.fn.off = function(event, selector, callback){ 1088 | var $this = this 1089 | if (event && !isString(event)) { 1090 | $.each(event, function(type, fn){ 1091 | $this.off(type, selector, fn) 1092 | }) 1093 | return $this 1094 | } 1095 | 1096 | if (!isString(selector) && !isFunction(callback) && callback !== false) 1097 | callback = selector, selector = undefined 1098 | 1099 | if (callback === false) callback = returnFalse 1100 | 1101 | return $this.each(function(){ 1102 | remove(this, event, callback, selector) 1103 | }) 1104 | } 1105 | 1106 | $.fn.trigger = function(event, args){ 1107 | event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event) 1108 | event._args = args 1109 | return this.each(function(){ 1110 | // handle focus(), blur() by calling them directly 1111 | if (event.type in focus && typeof this[event.type] == "function") this[event.type]() 1112 | // items in the collection might not be DOM elements 1113 | else if ('dispatchEvent' in this) this.dispatchEvent(event) 1114 | else $(this).triggerHandler(event, args) 1115 | }) 1116 | } 1117 | 1118 | // triggers event handlers on current element just as if an event occurred, 1119 | // doesn't trigger an actual event, doesn't bubble 1120 | $.fn.triggerHandler = function(event, args){ 1121 | var e, result 1122 | this.each(function(i, element){ 1123 | e = createProxy(isString(event) ? $.Event(event) : event) 1124 | e._args = args 1125 | e.target = element 1126 | $.each(findHandlers(element, event.type || event), function(i, handler){ 1127 | result = handler.proxy(e) 1128 | if (e.isImmediatePropagationStopped()) return false 1129 | }) 1130 | }) 1131 | return result 1132 | } 1133 | 1134 | // shortcut methods for `.bind(event, fn)` for each event type 1135 | ;('focusin focusout focus blur load resize scroll unload click dblclick '+ 1136 | 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+ 1137 | 'change select keydown keypress keyup error').split(' ').forEach(function(event) { 1138 | $.fn[event] = function(callback) { 1139 | return (0 in arguments) ? 1140 | this.bind(event, callback) : 1141 | this.trigger(event) 1142 | } 1143 | }) 1144 | 1145 | $.Event = function(type, props) { 1146 | if (!isString(type)) props = type, type = props.type 1147 | var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true 1148 | if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) 1149 | event.initEvent(type, bubbles, true) 1150 | return compatible(event) 1151 | } 1152 | 1153 | })(Zepto) 1154 | 1155 | ;(function($){ 1156 | var jsonpID = 0, 1157 | document = window.document, 1158 | key, 1159 | name, 1160 | rscript = /)<[^<]*)*<\/script>/gi, 1161 | scriptTypeRE = /^(?:text|application)\/javascript/i, 1162 | xmlTypeRE = /^(?:text|application)\/xml/i, 1163 | jsonType = 'application/json', 1164 | htmlType = 'text/html', 1165 | blankRE = /^\s*$/, 1166 | originAnchor = document.createElement('a') 1167 | 1168 | originAnchor.href = window.location.href 1169 | 1170 | // trigger a custom event and return false if it was cancelled 1171 | function triggerAndReturn(context, eventName, data) { 1172 | var event = $.Event(eventName) 1173 | $(context).trigger(event, data) 1174 | return !event.isDefaultPrevented() 1175 | } 1176 | 1177 | // trigger an Ajax "global" event 1178 | function triggerGlobal(settings, context, eventName, data) { 1179 | if (settings.global) return triggerAndReturn(context || document, eventName, data) 1180 | } 1181 | 1182 | // Number of active Ajax requests 1183 | $.active = 0 1184 | 1185 | function ajaxStart(settings) { 1186 | if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart') 1187 | } 1188 | function ajaxStop(settings) { 1189 | if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop') 1190 | } 1191 | 1192 | // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable 1193 | function ajaxBeforeSend(xhr, settings) { 1194 | var context = settings.context 1195 | if (settings.beforeSend.call(context, xhr, settings) === false || 1196 | triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false) 1197 | return false 1198 | 1199 | triggerGlobal(settings, context, 'ajaxSend', [xhr, settings]) 1200 | } 1201 | function ajaxSuccess(data, xhr, settings, deferred) { 1202 | var context = settings.context, status = 'success' 1203 | settings.success.call(context, data, status, xhr) 1204 | if (deferred) deferred.resolveWith(context, [data, status, xhr]) 1205 | triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data]) 1206 | ajaxComplete(status, xhr, settings) 1207 | } 1208 | // type: "timeout", "error", "abort", "parsererror" 1209 | function ajaxError(error, type, xhr, settings, deferred) { 1210 | var context = settings.context 1211 | settings.error.call(context, xhr, type, error) 1212 | if (deferred) deferred.rejectWith(context, [xhr, type, error]) 1213 | triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type]) 1214 | ajaxComplete(type, xhr, settings) 1215 | } 1216 | // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" 1217 | function ajaxComplete(status, xhr, settings) { 1218 | var context = settings.context 1219 | settings.complete.call(context, xhr, status) 1220 | triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings]) 1221 | ajaxStop(settings) 1222 | } 1223 | 1224 | // Empty function, used as default callback 1225 | function empty() {} 1226 | 1227 | $.ajaxJSONP = function(options, deferred){ 1228 | if (!('type' in options)) return $.ajax(options) 1229 | 1230 | var _callbackName = options.jsonpCallback, 1231 | callbackName = ($.isFunction(_callbackName) ? 1232 | _callbackName() : _callbackName) || ('jsonp' + (++jsonpID)), 1233 | script = document.createElement('script'), 1234 | originalCallback = window[callbackName], 1235 | responseData, 1236 | abort = function(errorType) { 1237 | $(script).triggerHandler('error', errorType || 'abort') 1238 | }, 1239 | xhr = { abort: abort }, abortTimeout 1240 | 1241 | if (deferred) deferred.promise(xhr) 1242 | 1243 | $(script).on('load error', function(e, errorType){ 1244 | clearTimeout(abortTimeout) 1245 | $(script).off().remove() 1246 | 1247 | if (e.type == 'error' || !responseData) { 1248 | ajaxError(null, errorType || 'error', xhr, options, deferred) 1249 | } else { 1250 | ajaxSuccess(responseData[0], xhr, options, deferred) 1251 | } 1252 | 1253 | window[callbackName] = originalCallback 1254 | if (responseData && $.isFunction(originalCallback)) 1255 | originalCallback(responseData[0]) 1256 | 1257 | originalCallback = responseData = undefined 1258 | }) 1259 | 1260 | if (ajaxBeforeSend(xhr, options) === false) { 1261 | abort('abort') 1262 | return xhr 1263 | } 1264 | 1265 | window[callbackName] = function(){ 1266 | responseData = arguments 1267 | } 1268 | 1269 | script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName) 1270 | document.head.appendChild(script) 1271 | 1272 | if (options.timeout > 0) abortTimeout = setTimeout(function(){ 1273 | abort('timeout') 1274 | }, options.timeout) 1275 | 1276 | return xhr 1277 | } 1278 | 1279 | $.ajaxSettings = { 1280 | // Default type of request 1281 | type: 'GET', 1282 | // Callback that is executed before request 1283 | beforeSend: empty, 1284 | // Callback that is executed if the request succeeds 1285 | success: empty, 1286 | // Callback that is executed the the server drops error 1287 | error: empty, 1288 | // Callback that is executed on request complete (both: error and success) 1289 | complete: empty, 1290 | // The context for the callbacks 1291 | context: null, 1292 | // Whether to trigger "global" Ajax events 1293 | global: true, 1294 | // Transport 1295 | xhr: function () { 1296 | return new window.XMLHttpRequest() 1297 | }, 1298 | // MIME types mapping 1299 | // IIS returns Javascript as "application/x-javascript" 1300 | accepts: { 1301 | script: 'text/javascript, application/javascript, application/x-javascript', 1302 | json: jsonType, 1303 | xml: 'application/xml, text/xml', 1304 | html: htmlType, 1305 | text: 'text/plain' 1306 | }, 1307 | // Whether the request is to another domain 1308 | crossDomain: false, 1309 | // Default timeout 1310 | timeout: 0, 1311 | // Whether data should be serialized to string 1312 | processData: true, 1313 | // Whether the browser should be allowed to cache GET responses 1314 | cache: true 1315 | } 1316 | 1317 | function mimeToDataType(mime) { 1318 | if (mime) mime = mime.split(';', 2)[0] 1319 | return mime && ( mime == htmlType ? 'html' : 1320 | mime == jsonType ? 'json' : 1321 | scriptTypeRE.test(mime) ? 'script' : 1322 | xmlTypeRE.test(mime) && 'xml' ) || 'text' 1323 | } 1324 | 1325 | function appendQuery(url, query) { 1326 | if (query == '') return url 1327 | return (url + '&' + query).replace(/[&?]{1,2}/, '?') 1328 | } 1329 | 1330 | // serialize payload and append it to the URL for GET requests 1331 | function serializeData(options) { 1332 | if (options.processData && options.data && $.type(options.data) != "string") 1333 | options.data = $.param(options.data, options.traditional) 1334 | if (options.data && (!options.type || options.type.toUpperCase() == 'GET')) 1335 | options.url = appendQuery(options.url, options.data), options.data = undefined 1336 | } 1337 | 1338 | $.ajax = function(options){ 1339 | var settings = $.extend({}, options || {}), 1340 | deferred = $.Deferred && $.Deferred(), 1341 | urlAnchor 1342 | for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key] 1343 | 1344 | ajaxStart(settings) 1345 | 1346 | if (!settings.crossDomain) { 1347 | urlAnchor = document.createElement('a') 1348 | urlAnchor.href = settings.url 1349 | urlAnchor.href = urlAnchor.href 1350 | settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host) 1351 | } 1352 | 1353 | if (!settings.url) settings.url = window.location.toString() 1354 | serializeData(settings) 1355 | 1356 | var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url) 1357 | if (hasPlaceholder) dataType = 'jsonp' 1358 | 1359 | if (settings.cache === false || ( 1360 | (!options || options.cache !== true) && 1361 | ('script' == dataType || 'jsonp' == dataType) 1362 | )) 1363 | settings.url = appendQuery(settings.url, '_=' + Date.now()) 1364 | 1365 | if ('jsonp' == dataType) { 1366 | if (!hasPlaceholder) 1367 | settings.url = appendQuery(settings.url, 1368 | settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?') 1369 | return $.ajaxJSONP(settings, deferred) 1370 | } 1371 | 1372 | var mime = settings.accepts[dataType], 1373 | headers = { }, 1374 | setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] }, 1375 | protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, 1376 | xhr = settings.xhr(), 1377 | nativeSetHeader = xhr.setRequestHeader, 1378 | abortTimeout 1379 | 1380 | if (deferred) deferred.promise(xhr) 1381 | 1382 | if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest') 1383 | setHeader('Accept', mime || '*/*') 1384 | if (mime = settings.mimeType || mime) { 1385 | if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0] 1386 | xhr.overrideMimeType && xhr.overrideMimeType(mime) 1387 | } 1388 | if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET')) 1389 | setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded') 1390 | 1391 | if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]) 1392 | xhr.setRequestHeader = setHeader 1393 | 1394 | xhr.onreadystatechange = function(){ 1395 | if (xhr.readyState == 4) { 1396 | xhr.onreadystatechange = empty 1397 | clearTimeout(abortTimeout) 1398 | var result, error = false 1399 | if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) { 1400 | dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type')) 1401 | result = xhr.responseText 1402 | 1403 | try { 1404 | // http://perfectionkills.com/global-eval-what-are-the-options/ 1405 | if (dataType == 'script') (1,eval)(result) 1406 | else if (dataType == 'xml') result = xhr.responseXML 1407 | else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result) 1408 | } catch (e) { error = e } 1409 | 1410 | if (error) ajaxError(error, 'parsererror', xhr, settings, deferred) 1411 | else ajaxSuccess(result, xhr, settings, deferred) 1412 | } else { 1413 | ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred) 1414 | } 1415 | } 1416 | } 1417 | 1418 | if (ajaxBeforeSend(xhr, settings) === false) { 1419 | xhr.abort() 1420 | ajaxError(null, 'abort', xhr, settings, deferred) 1421 | return xhr 1422 | } 1423 | 1424 | if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name] 1425 | 1426 | var async = 'async' in settings ? settings.async : true 1427 | xhr.open(settings.type, settings.url, async, settings.username, settings.password) 1428 | 1429 | for (name in headers) nativeSetHeader.apply(xhr, headers[name]) 1430 | 1431 | if (settings.timeout > 0) abortTimeout = setTimeout(function(){ 1432 | xhr.onreadystatechange = empty 1433 | xhr.abort() 1434 | ajaxError(null, 'timeout', xhr, settings, deferred) 1435 | }, settings.timeout) 1436 | 1437 | // avoid sending empty string (#319) 1438 | xhr.send(settings.data ? settings.data : null) 1439 | return xhr 1440 | } 1441 | 1442 | // handle optional data/success arguments 1443 | function parseArguments(url, data, success, dataType) { 1444 | if ($.isFunction(data)) dataType = success, success = data, data = undefined 1445 | if (!$.isFunction(success)) dataType = success, success = undefined 1446 | return { 1447 | url: url 1448 | , data: data 1449 | , success: success 1450 | , dataType: dataType 1451 | } 1452 | } 1453 | 1454 | $.get = function(/* url, data, success, dataType */){ 1455 | return $.ajax(parseArguments.apply(null, arguments)) 1456 | } 1457 | 1458 | $.post = function(/* url, data, success, dataType */){ 1459 | var options = parseArguments.apply(null, arguments) 1460 | options.type = 'POST' 1461 | return $.ajax(options) 1462 | } 1463 | 1464 | $.getJSON = function(/* url, data, success */){ 1465 | var options = parseArguments.apply(null, arguments) 1466 | options.dataType = 'json' 1467 | return $.ajax(options) 1468 | } 1469 | 1470 | $.fn.load = function(url, data, success){ 1471 | if (!this.length) return this 1472 | var self = this, parts = url.split(/\s/), selector, 1473 | options = parseArguments(url, data, success), 1474 | callback = options.success 1475 | if (parts.length > 1) options.url = parts[0], selector = parts[1] 1476 | options.success = function(response){ 1477 | self.html(selector ? 1478 | $('
').html(response.replace(rscript, "")).find(selector) 1479 | : response) 1480 | callback && callback.apply(self, arguments) 1481 | } 1482 | $.ajax(options) 1483 | return this 1484 | } 1485 | 1486 | var escape = encodeURIComponent 1487 | 1488 | function serialize(params, obj, traditional, scope){ 1489 | var type, array = $.isArray(obj), hash = $.isPlainObject(obj) 1490 | $.each(obj, function(key, value) { 1491 | type = $.type(value) 1492 | if (scope) key = traditional ? scope : 1493 | scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']' 1494 | // handle data in serializeArray() format 1495 | if (!scope && array) params.add(value.name, value.value) 1496 | // recurse into nested objects 1497 | else if (type == "array" || (!traditional && type == "object")) 1498 | serialize(params, value, traditional, key) 1499 | else params.add(key, value) 1500 | }) 1501 | } 1502 | 1503 | $.param = function(obj, traditional){ 1504 | var params = [] 1505 | params.add = function(key, value) { 1506 | if ($.isFunction(value)) value = value() 1507 | if (value == null) value = "" 1508 | this.push(escape(key) + '=' + escape(value)) 1509 | } 1510 | serialize(params, obj, traditional) 1511 | return params.join('&').replace(/%20/g, '+') 1512 | } 1513 | })(Zepto) 1514 | 1515 | ;(function($){ 1516 | $.fn.serializeArray = function() { 1517 | var name, type, result = [], 1518 | add = function(value) { 1519 | if (value.forEach) return value.forEach(add) 1520 | result.push({ name: name, value: value }) 1521 | } 1522 | if (this[0]) $.each(this[0].elements, function(_, field){ 1523 | type = field.type, name = field.name 1524 | if (name && field.nodeName.toLowerCase() != 'fieldset' && 1525 | !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' && 1526 | ((type != 'radio' && type != 'checkbox') || field.checked)) 1527 | add($(field).val()) 1528 | }) 1529 | return result 1530 | } 1531 | 1532 | $.fn.serialize = function(){ 1533 | var result = [] 1534 | this.serializeArray().forEach(function(elm){ 1535 | result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value)) 1536 | }) 1537 | return result.join('&') 1538 | } 1539 | 1540 | $.fn.submit = function(callback) { 1541 | if (0 in arguments) this.bind('submit', callback) 1542 | else if (this.length) { 1543 | var event = $.Event('submit') 1544 | this.eq(0).trigger(event) 1545 | if (!event.isDefaultPrevented()) this.get(0).submit() 1546 | } 1547 | return this 1548 | } 1549 | 1550 | })(Zepto) 1551 | 1552 | ;(function($){ 1553 | // __proto__ doesn't exist on IE<11, so redefine 1554 | // the Z function to use object extension instead 1555 | if (!('__proto__' in {})) { 1556 | $.extend($.zepto, { 1557 | Z: function(dom, selector){ 1558 | dom = dom || [] 1559 | $.extend(dom, $.fn) 1560 | dom.selector = selector || '' 1561 | dom.__Z = true 1562 | return dom 1563 | }, 1564 | // this is a kludge but works 1565 | isZ: function(object){ 1566 | return $.type(object) === 'array' && '__Z' in object 1567 | } 1568 | }) 1569 | } 1570 | 1571 | // getComputedStyle shouldn't freak out when called 1572 | // without a valid element as argument 1573 | try { 1574 | getComputedStyle(undefined) 1575 | } catch(e) { 1576 | var nativeGetComputedStyle = getComputedStyle; 1577 | window.getComputedStyle = function(element){ 1578 | try { 1579 | return nativeGetComputedStyle(element) 1580 | } catch(e) { 1581 | return null 1582 | } 1583 | } 1584 | } 1585 | })(Zepto) 1586 | 1587 | ;(function($){ 1588 | var touch = {}, 1589 | touchTimeout, tapTimeout, swipeTimeout, longTapTimeout, 1590 | longTapDelay = 750, 1591 | gesture 1592 | 1593 | function swipeDirection(x1, x2, y1, y2) { 1594 | return Math.abs(x1 - x2) >= 1595 | Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down') 1596 | } 1597 | 1598 | function longTap() { 1599 | longTapTimeout = null 1600 | if (touch.last) { 1601 | touch.el.trigger('longTap') 1602 | touch = {} 1603 | } 1604 | } 1605 | 1606 | function cancelLongTap() { 1607 | if (longTapTimeout) clearTimeout(longTapTimeout) 1608 | longTapTimeout = null 1609 | } 1610 | 1611 | function cancelAll() { 1612 | if (touchTimeout) clearTimeout(touchTimeout) 1613 | if (tapTimeout) clearTimeout(tapTimeout) 1614 | if (swipeTimeout) clearTimeout(swipeTimeout) 1615 | if (longTapTimeout) clearTimeout(longTapTimeout) 1616 | touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null 1617 | touch = {} 1618 | } 1619 | 1620 | function isPrimaryTouch(event){ 1621 | return (event.pointerType == 'touch' || 1622 | event.pointerType == event.MSPOINTER_TYPE_TOUCH) 1623 | && event.isPrimary 1624 | } 1625 | 1626 | function isPointerEventType(e, type){ 1627 | return (e.type == 'pointer'+type || 1628 | e.type.toLowerCase() == 'mspointer'+type) 1629 | } 1630 | 1631 | $(document).ready(function(){ 1632 | var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType 1633 | 1634 | if ('MSGesture' in window) { 1635 | gesture = new MSGesture() 1636 | gesture.target = document.body 1637 | } 1638 | 1639 | $(document) 1640 | .bind('MSGestureEnd', function(e){ 1641 | var swipeDirectionFromVelocity = 1642 | e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null; 1643 | if (swipeDirectionFromVelocity) { 1644 | touch.el.trigger('swipe') 1645 | touch.el.trigger('swipe'+ swipeDirectionFromVelocity) 1646 | } 1647 | }) 1648 | .on('touchstart MSPointerDown pointerdown', function(e){ 1649 | if((_isPointerType = isPointerEventType(e, 'down')) && 1650 | !isPrimaryTouch(e)) return 1651 | firstTouch = _isPointerType ? e : e.touches[0] 1652 | if (e.touches && e.touches.length === 1 && touch.x2) { 1653 | // Clear out touch movement data if we have it sticking around 1654 | // This can occur if touchcancel doesn't fire due to preventDefault, etc. 1655 | touch.x2 = undefined 1656 | touch.y2 = undefined 1657 | } 1658 | now = Date.now() 1659 | delta = now - (touch.last || now) 1660 | touch.el = $('tagName' in firstTouch.target ? 1661 | firstTouch.target : firstTouch.target.parentNode) 1662 | touchTimeout && clearTimeout(touchTimeout) 1663 | touch.x1 = firstTouch.pageX 1664 | touch.y1 = firstTouch.pageY 1665 | if (delta > 0 && delta <= 250) touch.isDoubleTap = true 1666 | touch.last = now 1667 | longTapTimeout = setTimeout(longTap, longTapDelay) 1668 | // adds the current touch contact for IE gesture recognition 1669 | if (gesture && _isPointerType) gesture.addPointer(e.pointerId); 1670 | }) 1671 | .on('touchmove MSPointerMove pointermove', function(e){ 1672 | if((_isPointerType = isPointerEventType(e, 'move')) && 1673 | !isPrimaryTouch(e)) return 1674 | firstTouch = _isPointerType ? e : e.touches[0] 1675 | cancelLongTap() 1676 | touch.x2 = firstTouch.pageX 1677 | touch.y2 = firstTouch.pageY 1678 | 1679 | deltaX += Math.abs(touch.x1 - touch.x2) 1680 | deltaY += Math.abs(touch.y1 - touch.y2) 1681 | }) 1682 | .on('touchend MSPointerUp pointerup', function(e){ 1683 | if((_isPointerType = isPointerEventType(e, 'up')) && 1684 | !isPrimaryTouch(e)) return 1685 | cancelLongTap() 1686 | 1687 | // swipe 1688 | if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || 1689 | (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)) 1690 | 1691 | swipeTimeout = setTimeout(function() { 1692 | touch.el.trigger('swipe') 1693 | touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2))) 1694 | touch = {} 1695 | }, 0) 1696 | 1697 | // normal tap 1698 | else if ('last' in touch) 1699 | // don't fire tap when delta position changed by more than 30 pixels, 1700 | // for instance when moving to a point and back to origin 1701 | if (deltaX < 30 && deltaY < 30) { 1702 | // delay by one tick so we can cancel the 'tap' event if 'scroll' fires 1703 | // ('tap' fires before 'scroll') 1704 | tapTimeout = setTimeout(function() { 1705 | 1706 | // trigger universal 'tap' with the option to cancelTouch() 1707 | // (cancelTouch cancels processing of single vs double taps for faster 'tap' response) 1708 | var event = $.Event('tap') 1709 | event.cancelTouch = cancelAll 1710 | touch.el.trigger(event) 1711 | 1712 | // trigger double tap immediately 1713 | if (touch.isDoubleTap) { 1714 | if (touch.el) touch.el.trigger('doubleTap') 1715 | touch = {} 1716 | } 1717 | 1718 | // trigger single tap after 250ms of inactivity 1719 | else { 1720 | touchTimeout = setTimeout(function(){ 1721 | touchTimeout = null 1722 | if (touch.el) touch.el.trigger('singleTap') 1723 | touch = {} 1724 | }, 250) 1725 | } 1726 | }, 0) 1727 | } else { 1728 | touch = {} 1729 | } 1730 | deltaX = deltaY = 0 1731 | 1732 | }) 1733 | // when the browser window loses focus, 1734 | // for example when a modal dialog is shown, 1735 | // cancel all ongoing events 1736 | .on('touchcancel MSPointerCancel pointercancel', cancelAll) 1737 | 1738 | // scrolling the window indicates intention of the user 1739 | // to scroll, not tap or swipe, so cancel all ongoing events 1740 | $(window).on('scroll', cancelAll) 1741 | }) 1742 | 1743 | ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 1744 | 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){ 1745 | $.fn[eventName] = function(callback){ return this.on(eventName, callback) } 1746 | }) 1747 | })(Zepto) --------------------------------------------------------------------------------