├── .babelrc ├── .bowerrc ├── .csscomb.json ├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .npmignore ├── .release.json ├── .stylelintrc.json ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bower.json ├── config.js ├── dist ├── css │ ├── easing.css │ ├── easing.min.css │ ├── scrollToTop.css │ └── scrollToTop.min.css ├── images │ ├── cycle-hover.png │ ├── cycle.png │ ├── square-hover.png │ ├── square.png │ ├── text-hover.png │ ├── text.png │ ├── triangle-hover.png │ └── triangle.png ├── jquery-scrollToTop.es.js ├── jquery-scrollToTop.js ├── jquery-scrollToTop.min.js └── jquery-scrollToTop.min.js.map ├── examples ├── css │ ├── main.css │ └── normalize.css ├── index.html └── js │ ├── jquery.js │ └── jquery.min.js ├── gulp ├── tasks │ ├── archive.js │ ├── assets.js │ ├── browser.js │ ├── clean.js │ ├── deploy.js │ ├── images.js │ ├── lint-scripts.js │ ├── lint-styles.js │ ├── release.js │ ├── scripts.js │ ├── styles.js │ └── test.js └── util │ ├── getFolders.js │ ├── getSrcFiles.js │ └── handleErrors.js ├── gulpfile.babel.js ├── karma.conf.js ├── manifest.json ├── package-lock.json ├── package.json └── src ├── defaults.js ├── images ├── .gitignore ├── cycle-hover.png ├── cycle.png ├── square-hover.png ├── square.png ├── text-hover.png ├── text.png ├── triangle-hover.png └── triangle.png ├── info.js ├── main.js ├── scrollToTop.js ├── scss ├── easing.scss └── scrollToTop.scss ├── support.js └── util.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"] 3 | } 4 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.csscomb.json: -------------------------------------------------------------------------------- 1 | { 2 | "remove-empty-rulesets": true, 3 | "always-semicolon": true, 4 | "color-case": "lower", 5 | "block-indent": " ", 6 | "color-shorthand": true, 7 | "element-case": "lower", 8 | "eof-newline": true, 9 | "leading-zero": false, 10 | "quotes": "double", 11 | "space-before-colon": "", 12 | "space-after-colon": " ", 13 | "space-before-combinator": " ", 14 | "space-after-combinator": " ", 15 | "space-between-declarations": "\n", 16 | "space-before-opening-brace": " ", 17 | "space-after-opening-brace": "\n", 18 | "space-after-selector-delimiter": " ", 19 | "space-before-selector-delimiter": "", 20 | "space-before-closing-brace": "\n", 21 | "strip-spaces": true, 22 | "tab-size": true, 23 | "unitless-zero": true, 24 | "vendor-prefix-align": false, 25 | "sort-order": [ 26 | "position", 27 | "top", 28 | "right", 29 | "bottom", 30 | "left", 31 | "z-index", 32 | "-moz-box-sizing", 33 | "-webkit-box-sizing", 34 | "box-sizing", 35 | "display", 36 | "flex", 37 | "flex-align", 38 | "flex-basis", 39 | "flex-direction", 40 | "flex-flow", 41 | "flex-grow", 42 | "flex-order", 43 | "flex-pack", 44 | "float", 45 | "width", 46 | "min-width", 47 | "max-width", 48 | "height", 49 | "min-height", 50 | "max-height", 51 | "padding", 52 | "padding-top", 53 | "padding-right", 54 | "padding-bottom", 55 | "padding-left", 56 | "margin", 57 | "margin-top", 58 | "margin-right", 59 | "margin-bottom", 60 | "margin-left", 61 | "overflow", 62 | "overflow-x", 63 | "overflow-y", 64 | "-webkit-overflow-scrolling", 65 | "-ms-overflow-x", 66 | "-ms-overflow-y", 67 | "-ms-overflow-style", 68 | "clip", 69 | "clear", 70 | "font", 71 | "font-family", 72 | "font-size", 73 | "font-style", 74 | "font-weight", 75 | "font-variant", 76 | "font-size-adjust", 77 | "font-stretch", 78 | "font-effect", 79 | "font-emphasize", 80 | "font-emphasize-position", 81 | "font-emphasize-style", 82 | "font-smooth", 83 | "-webkit-hyphens", 84 | "-moz-hyphens", 85 | "hyphens", 86 | "line-height", 87 | "color", 88 | "text-align", 89 | "-webkit-text-align-last", 90 | "-moz-text-align-last", 91 | "-ms-text-align-last", 92 | "text-align-last", 93 | "text-emphasis", 94 | "text-emphasis-color", 95 | "text-emphasis-style", 96 | "text-emphasis-position", 97 | "text-decoration", 98 | "text-indent", 99 | "text-justify", 100 | "text-outline", 101 | "-ms-text-overflow", 102 | "text-overflow", 103 | "text-overflow-ellipsis", 104 | "text-overflow-mode", 105 | "text-shadow", 106 | "text-transform", 107 | "text-wrap", 108 | "-webkit-text-size-adjust", 109 | "-ms-text-size-adjust", 110 | "letter-spacing", 111 | "-ms-word-break", 112 | "word-break", 113 | "word-spacing", 114 | "-ms-word-wrap", 115 | "word-wrap", 116 | "-moz-tab-size", 117 | "-o-tab-size", 118 | "tab-size", 119 | "white-space", 120 | "vertical-align", 121 | "list-style", 122 | "list-style-position", 123 | "list-style-type", 124 | "list-style-image", 125 | "pointer-events", 126 | "-ms-touch-action", 127 | "touch-action", 128 | "cursor", 129 | "visibility", 130 | "zoom", 131 | "table-layout", 132 | "empty-cells", 133 | "caption-side", 134 | "border-spacing", 135 | "border-collapse", 136 | "content", 137 | "quotes", 138 | "counter-reset", 139 | "counter-increment", 140 | "resize", 141 | "-webkit-user-select", 142 | "-moz-user-select", 143 | "-ms-user-select", 144 | "-o-user-select", 145 | "user-select", 146 | "nav-index", 147 | "nav-up", 148 | "nav-right", 149 | "nav-down", 150 | "nav-left", 151 | "background", 152 | "background-color", 153 | "background-image", 154 | "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient", 155 | "filter:progid:DXImageTransform.Microsoft.gradient", 156 | "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader", 157 | "filter", 158 | "background-repeat", 159 | "background-attachment", 160 | "background-position", 161 | "background-position-x", 162 | "background-position-y", 163 | "-moz-background-clip", 164 | "-webkit-background-clip", 165 | "background-clip", 166 | "background-origin", 167 | "-moz-background-size", 168 | "-o-background-size", 169 | "-webkit-background-size", 170 | "background-size", 171 | "border", 172 | "border-color", 173 | "border-style", 174 | "border-width", 175 | "border-top", 176 | "border-top-color", 177 | "border-top-style", 178 | "border-top-width", 179 | "border-right", 180 | "border-right-color", 181 | "border-right-style", 182 | "border-right-width", 183 | "border-bottom", 184 | "border-bottom-color", 185 | "border-bottom-style", 186 | "border-bottom-width", 187 | "border-left", 188 | "border-left-color", 189 | "border-left-style", 190 | "border-left-width", 191 | "-moz-border-radius", 192 | "-o-border-radius", 193 | "-webkit-border-radius", 194 | "border-radius", 195 | "border-top-left-radius", 196 | "border-top-right-radius", 197 | "border-bottom-right-radius", 198 | "border-bottom-left-radius", 199 | "-moz-border-image", 200 | "-o-border-image", 201 | "-webkit-border-image", 202 | "border-image", 203 | "-moz-border-image-source", 204 | "-o-border-image-source", 205 | "-webkit-border-image-source", 206 | "border-image-source", 207 | "-moz-border-image-slice", 208 | "-o-border-image-slice", 209 | "-webkit-border-image-slice", 210 | "border-image-slice", 211 | "-moz-border-image-width", 212 | "-o-border-image-width", 213 | "-webkit-border-image-width", 214 | "border-image-width", 215 | "-moz-border-image-outset", 216 | "-o-border-image-outset", 217 | "-webkit-border-image-outset", 218 | "border-image-outset", 219 | "-moz-border-image-repeat", 220 | "-o-border-image-repeat", 221 | "-webkit-border-image-repeat", 222 | "border-image-repeat", 223 | "outline", 224 | "outline-width", 225 | "outline-style", 226 | "outline-color", 227 | "outline-offset", 228 | "-webkit-box-shadow", 229 | "-moz-box-shadow", 230 | "box-shadow", 231 | "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity", 232 | "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha", 233 | "opacity", 234 | "-ms-interpolation-mode", 235 | "-moz-transition", 236 | "-ms-transition", 237 | "-o-transition", 238 | "-webkit-transition", 239 | "transition", 240 | "-moz-transition-delay", 241 | "-ms-transition-delay", 242 | "-o-transition-delay", 243 | "-webkit-transition-delay", 244 | "transition-delay", 245 | "-moz-transition-timing-function", 246 | "-ms-transition-timing-function", 247 | "-o-transition-timing-function", 248 | "-webkit-transition-timing-function", 249 | "transition-timing-function", 250 | "-moz-transition-duration", 251 | "-ms-transition-duration", 252 | "-o-transition-duration", 253 | "-webkit-transition-duration", 254 | "transition-duration", 255 | "-moz-transition-property", 256 | "-ms-transition-property", 257 | "-o-transition-property", 258 | "-webkit-transition-property", 259 | "transition-property", 260 | "-moz-transform", 261 | "-ms-transform", 262 | "-o-transform", 263 | "-webkit-transform", 264 | "transform", 265 | "-moz-transform-origin", 266 | "-ms-transform-origin", 267 | "-o-transform-origin", 268 | "-webkit-transform-origin", 269 | "transform-origin", 270 | "-webkit-animation", 271 | "-moz-animation", 272 | "-ms-animation", 273 | "-o-animation", 274 | "animation", 275 | "-moz-animation-name", 276 | "-ms-animation-name", 277 | "-o-animation-name", 278 | "-webkit-animation-name", 279 | "animation-name", 280 | "-moz-animation-duration", 281 | "-ms-animation-duration", 282 | "-o-animation-duration", 283 | "-webkit-animation-duration", 284 | "animation-duration", 285 | "-moz-animation-play-state", 286 | "-ms-animation-play-state", 287 | "-o-animation-play-state", 288 | "-webkit-animation-play-state", 289 | "animation-play-state", 290 | "-moz-animation-timing-function", 291 | "-ms-animation-timing-function", 292 | "-o-animation-timing-function", 293 | "-webkit-animation-timing-function", 294 | "animation-timing-function", 295 | "-moz-animation-delay", 296 | "-ms-animation-delay", 297 | "-o-animation-delay", 298 | "-webkit-animation-delay", 299 | "animation-delay", 300 | "-moz-animation-iteration-count", 301 | "-ms-animation-iteration-count", 302 | "-o-animation-iteration-count", 303 | "-webkit-animation-iteration-count", 304 | "animation-iteration-count", 305 | "-moz-animation-direction", 306 | "-ms-animation-direction", 307 | "-o-animation-direction", 308 | "-webkit-animation-direction" 309 | ] 310 | } 311 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # End every file with a newline 7 | [*] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | 15 | [*.{css,less,scss}] 16 | indent_style = space 17 | indent_size = 2 18 | 19 | [*.{js,json}] 20 | indent_style = space 21 | indent_size = 2 22 | 23 | [*.{html,hbs}] 24 | indent_style = tab 25 | indent_size = 2 26 | 27 | [*.md] 28 | indent_style = space 29 | indent_size = 2 30 | insert_final_newline = false 31 | trim_trailing_whitespace = false 32 | 33 | [*.xml] 34 | indent_style = space 35 | indent_size = 2 36 | 37 | [*.yml] 38 | indent_style = space 39 | indent_size = 2 40 | 41 | [*.inc] 42 | indent_style = tab 43 | indent_size = 2 -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "babel-eslint", 4 | "env": { 5 | "browser": true, 6 | "es6": true, 7 | "jquery": true, 8 | "builtin": true, 9 | "mocha": true, 10 | "node": true 11 | }, 12 | "extends": "eslint:recommended", 13 | "parserOptions": { 14 | "ecmaVersion": 8, 15 | "sourceType": "module" 16 | }, 17 | // "plugins": [ 18 | // "prettier" 19 | // ], 20 | "rules": { 21 | // Prettier 22 | // "prettier/prettier": "error", 23 | // Possible Errors 24 | "no-inner-declarations": "off", 25 | "no-await-in-loop": "error", 26 | "no-compare-neg-zero": "error", 27 | "no-extra-parens": ["error", "all", { 28 | "returnAssign": false, 29 | "enforceForArrowConditionals": false 30 | } 31 | ], 32 | "no-prototype-builtins": "off", 33 | "no-template-curly-in-string": "error", 34 | "valid-jsdoc": "off", 35 | 36 | // Best Practices 37 | "accessor-pairs": "error", 38 | "array-callback-return": "error", 39 | "block-scoped-var": "error", 40 | "class-methods-use-this": "off", 41 | "complexity": "error", 42 | "consistent-return": "error", 43 | "curly": "error", 44 | "default-case": "error", 45 | "dot-location": ["error", "property"], 46 | "dot-notation": "error", 47 | "eqeqeq": "error", 48 | "guard-for-in": "error", 49 | "no-alert": "error", 50 | "no-caller": "error", 51 | "no-div-regex": "error", 52 | "no-else-return": "error", 53 | "no-empty-function": "error", 54 | "no-eq-null": "error", 55 | "no-eval": "error", 56 | "no-extend-native": "error", 57 | "no-extra-bind": "error", 58 | "no-extra-label": "error", 59 | "no-floating-decimal": "error", 60 | "no-implicit-coercion": "error", 61 | "no-implicit-globals": "error", 62 | "no-implied-eval": "error", 63 | "no-invalid-this": "off", 64 | "no-iterator": "error", 65 | "no-labels": "error", 66 | "no-lone-blocks": "error", 67 | "no-loop-func": "error", 68 | "no-magic-numbers": "off", 69 | "no-multi-spaces": ["error", { 70 | "exceptions": { 71 | "AssignmentExpression": true, 72 | "ArrowFunctionExpression": true, 73 | "CallExpression": true, 74 | "VariableDeclarator": true 75 | } 76 | } 77 | ], 78 | "no-multi-str": "error", 79 | "no-new": "error", 80 | "no-new-func": "error", 81 | "no-new-wrappers": "error", 82 | "no-octal-escape": "error", 83 | "no-param-reassign": "off", 84 | "no-proto": "error", 85 | "no-restricted-properties": "error", 86 | "no-return-assign": "off", 87 | "no-return-await": "error", 88 | "no-script-url": "error", 89 | "no-self-compare": "error", 90 | "no-sequences": "error", 91 | "no-throw-literal": "error", 92 | "no-unmodified-loop-condition": "error", 93 | "no-unused-expressions": "error", 94 | "no-useless-call": "error", 95 | "no-useless-concat": "error", 96 | "no-useless-escape": "error", 97 | "no-useless-return": "off", 98 | "no-void": "error", 99 | "no-warning-comments": "off", 100 | "no-with": "error", 101 | "prefer-promise-reject-errors": "error", 102 | "radix": "error", 103 | "require-await": "error", 104 | "vars-on-top": "error", 105 | "wrap-iife": "error", 106 | "yoda": "error", 107 | 108 | // Strict Mode 109 | "strict": "error", 110 | 111 | // Variables 112 | "init-declarations": "off", 113 | "no-catch-shadow": "error", 114 | "no-label-var": "error", 115 | "no-restricted-globals": "error", 116 | "no-shadow": "off", 117 | "no-shadow-restricted-names": "error", 118 | "no-undef-init": "error", 119 | "no-undefined": "off", 120 | "no-use-before-define": "off", 121 | 122 | // Node.js and CommonJS 123 | "callback-return": "off", 124 | "global-require": "error", 125 | "handle-callback-err": "error", 126 | "no-mixed-requires": "error", 127 | "no-new-require": "error", 128 | "no-path-concat": "error", 129 | "no-process-env": "error", 130 | "no-process-exit": "error", 131 | "no-restricted-modules": "error", 132 | "no-sync": "error", 133 | 134 | // Stylistic Issues 135 | "array-bracket-spacing": "error", 136 | "block-spacing": "error", 137 | "brace-style": "error", 138 | "camelcase": "error", 139 | "capitalized-comments": "off", 140 | "comma-dangle": "error", 141 | "comma-spacing": "error", 142 | "comma-style": "error", 143 | "computed-property-spacing": "error", 144 | "consistent-this": "error", 145 | "eol-last": "error", 146 | "func-call-spacing": "error", 147 | "func-name-matching": "error", 148 | "func-names": "off", 149 | "func-style": ["error", "declaration", { 150 | "allowArrowFunctions": true 151 | }], 152 | "id-blacklist": "error", 153 | "id-length": "off", 154 | "id-match": "error", 155 | "indent": "off", 156 | "indent-legacy": ["error", 2, { "SwitchCase": 1 }], 157 | "jsx-quotes": "error", 158 | "key-spacing": "off", 159 | "keyword-spacing": "error", 160 | "line-comment-position": "off", 161 | "linebreak-style": ["error", "unix"], 162 | "lines-around-comment": "off", 163 | "lines-around-directive": "error", 164 | "max-depth": ["error", 10], 165 | "max-len": "off", 166 | "max-lines": "off", 167 | "max-nested-callbacks": "error", 168 | "max-params": "off", 169 | "max-statements": "off", 170 | "max-statements-per-line": "error", 171 | "multiline-ternary": "off", 172 | "new-cap": ["error", { "capIsNewExceptionPattern": "$.*" }], 173 | "new-parens": "error", 174 | "newline-after-var": "off", 175 | "newline-before-return": "off", 176 | "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 5 }], 177 | "no-array-constructor": "error", 178 | "no-bitwise": "error", 179 | "no-continue": "off", 180 | "no-inline-comments": "off", 181 | "no-lonely-if": "error", 182 | "no-mixed-operators": "off", 183 | "no-multi-assign": "error", 184 | "no-multiple-empty-lines": "error", 185 | "no-negated-condition": "off", 186 | "no-nested-ternary": "error", 187 | "no-new-object": "error", 188 | "no-plusplus": "off", 189 | "no-restricted-syntax": "error", 190 | "no-tabs": "error", 191 | "no-ternary": "off", 192 | "no-trailing-spaces": "error", 193 | "no-underscore-dangle": "off", 194 | "no-unneeded-ternary": "error", 195 | "no-whitespace-before-property": "error", 196 | "nonblock-statement-body-position": "error", 197 | "object-curly-newline": ["error", { "minProperties": 1 }], 198 | "object-curly-spacing": ["error", "always"], 199 | "object-property-newline": "error", 200 | "one-var": ["error", "never"], 201 | "one-var-declaration-per-line": "error", 202 | "operator-assignment": "error", 203 | "operator-linebreak": "off", 204 | "padded-blocks": "off", 205 | "quote-props": ["error", "as-needed"], 206 | "quotes": ["error", "single", { "allowTemplateLiterals": true }], 207 | "require-jsdoc": "off", 208 | "semi": ["error", "always"], 209 | "semi-spacing": ["error", {"before": false, "after": true}], 210 | "sort-keys": "off", 211 | "sort-vars": "error", 212 | "space-before-blocks": "error", 213 | "space-before-function-paren": ["error", { 214 | "anonymous": "always", 215 | "named": "never" 216 | }], 217 | "space-in-parens": "error", 218 | "space-infix-ops": "error", 219 | "space-unary-ops": "error", 220 | "spaced-comment": "error", 221 | "template-tag-spacing": "error", 222 | "unicode-bom": "error", 223 | "wrap-regex": "off", 224 | 225 | // ECMAScript 6 226 | "arrow-body-style": "off", 227 | "arrow-parens": "error", 228 | "arrow-spacing": "error", 229 | "generator-star-spacing": "error", 230 | "no-confusing-arrow": ["error", { "allowParens": true }], 231 | "no-duplicate-imports": "error", 232 | "no-restricted-imports": "error", 233 | "no-useless-computed-key": "error", 234 | "no-useless-constructor": "error", 235 | "no-useless-rename": "error", 236 | "no-var": "error", 237 | "object-shorthand": "error", 238 | "prefer-arrow-callback": "error", 239 | "prefer-const": "error", 240 | "prefer-destructuring": "off", 241 | "prefer-numeric-literals": "error", 242 | "prefer-rest-params": "error", 243 | "prefer-spread": "error", 244 | "prefer-template": "error", 245 | "rest-spread-spacing": "error", 246 | "sort-imports": "off", 247 | "symbol-description": "error", 248 | "template-curly-spacing": "error", 249 | "yield-star-spacing": "error" 250 | } 251 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ################################## 2 | # project-specific.gitattributes # 3 | ################################## 4 | 5 | 6 | ########################### 7 | # documents.gitattributes # 8 | ########################### 9 | *.doc diff=astextplain 10 | *.docx diff=astextplain 11 | *.dot diff=astextplain 12 | *.pdf diff=astextplain 13 | *.rtf diff=astextplain 14 | *.css text eol=lf 15 | *.scss text eol=lf 16 | *.less text eol=lf 17 | *.html text eol=lf 18 | *.js text eol=lf 19 | *.json text eol=lf 20 | *.md text eol=lf 21 | *.txt text eol=lf 22 | *.hbs text eol=lf 23 | *.mustache text eol=lf 24 | *.xml text eol=lf 25 | *.csv text eol=lf 26 | *.tab text eol=lf 27 | *.tsv text eol=lf 28 | *.sql text eol=lf 29 | 30 | ############################ 31 | ### graphics.gitattributes # 32 | ############################ 33 | *.png binary 34 | *.jpg binary 35 | *.jpeg binary 36 | *.gif binary 37 | *.tif binary 38 | *.tiff binary 39 | *.ico binary 40 | *.svg binary 41 | *.eps binary 42 | *.psd binary 43 | *.ai binary 44 | 45 | ########################### 46 | # git-crypt.gitattributes # 47 | ########################### 48 | vault_* binary filter=git-crypt diff=git-crypt 49 | vault.* binary filter=git-crypt diff=git-crypt 50 | 51 | ####################### 52 | # shell.gitattributes # 53 | ####################### 54 | # Linux 55 | *.sh text eol=lf 56 | 57 | # Windows 58 | *.bat text eol=crlf 59 | *.cmd text eol=crlf 60 | *.ps1 text eol=crlf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | _[Remove this line and all of the above before submitting your issue]_ 7 | 8 | ### Checklist 9 | * [ ] I'm using **version** [x.x.x] 10 | * [ ] My **browser** is: 11 | * [ ] This is a **Sass** issue: I'm using version [x.x.x] 12 | * [ ] I am sure this issue is **not a duplicate**? 13 | 14 | ### Description 15 | 16 | [Description of the bug, enhancement, or question] 17 | [Please tag accordingly] 18 | 19 | ### How can we reproduce this bug? 20 | 21 | 1. [First Step] 22 | 2. [Second Step] 23 | 3. [and so on...] 24 | 25 | ### What did you expect to happen? 26 | 27 | ### What happened instead? 28 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | _[Remove this line and all of the above before submitting your PR]_ 15 | 16 | ### Pull Request 17 | 18 | Fixes # 19 | 20 | Changes proposed: 21 | 22 | * [ ] Add 23 | * [ ] Fix 24 | * [ ] Remove 25 | * [ ] Update 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #################### 2 | # project-specific # 3 | #################### 4 | 5 | 6 | #################### 7 | # Generated source # 8 | #################### 9 | _build/ 10 | archives/ 11 | results 12 | screenshots 13 | 14 | ########################## 15 | # Dependency directories # 16 | ########################## 17 | bower_components 18 | node_modules 19 | 20 | ####### 21 | # OSX # 22 | ####### 23 | .DS_Store 24 | .AppleDouble 25 | .LSOverride 26 | 27 | # Icon must end with two \r 28 | Icon 29 | 30 | # Thumbnails 31 | ._* 32 | 33 | # Files that might appear in the root of a volume 34 | .DocumentRevisions-V100 35 | .fseventsd 36 | .Spotlight-V100 37 | .TemporaryItems 38 | .Trashes 39 | .VolumeIcon.icns 40 | 41 | # Directories potentially created on remote AFP share 42 | .AppleDB 43 | .AppleDesktop 44 | Network Trash Folder 45 | Temporary Items 46 | .apdisk 47 | 48 | ########### 49 | # Windows # 50 | ########### 51 | # Windows image file caches 52 | Thumbs.db 53 | ehthumbs.db 54 | 55 | # Folder config file 56 | Desktop.ini 57 | 58 | # Recycle Bin used on file shares 59 | $RECYCLE.BIN/ 60 | 61 | # Windows Installer files 62 | *.cab 63 | *.msi 64 | *.msm 65 | *.msp 66 | 67 | # Windows shortcuts 68 | *.lnk 69 | 70 | ######## 71 | # Node # 72 | ######## 73 | # Logs 74 | logs 75 | *.log 76 | npm-debug.log* 77 | 78 | # Runtime data 79 | pids 80 | *.pid 81 | *.seed 82 | 83 | # Directory for instrumented libs generated by jscoverage/JSCover 84 | lib-cov 85 | 86 | # Coverage directory used by tools like istanbul 87 | coverage 88 | 89 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 90 | .grunt 91 | 92 | # Sass 93 | .sass-cache/ 94 | *.css.map 95 | 96 | # node-waf configuration 97 | .lock-wscript 98 | 99 | # Compiled binary addons (http://nodejs.org/api/addons.html) 100 | build/Release 101 | 102 | # Dependency directory 103 | node_modules 104 | 105 | # JSPM 106 | jspm_packages 107 | 108 | # Optional npm cache directory 109 | .npm 110 | 111 | ############### 112 | # SublimeText # 113 | ############### 114 | # cache files for sublime text 115 | *.tmlanguage.cache 116 | *.tmPreferences.cache 117 | *.stTheme.cache 118 | 119 | # workspace files are user-specific 120 | *.sublime-workspace 121 | 122 | # project files should be checked into the repository, unless a significant 123 | # proportion of contributors will probably not be using SublimeText 124 | # *.sublime-project 125 | 126 | # sftp configuration file 127 | sftp-config.json 128 | 129 | ####### 130 | # Vim # 131 | ####### 132 | # swap 133 | [._]*.s[a-w][a-z] 134 | [._]s[a-w][a-z] 135 | # persistent undo 136 | *.un~ 137 | # session 138 | Session.vim 139 | # temporary 140 | .netrwhist 141 | *~ 142 | 143 | ############# 144 | # NotepadPP # 145 | ############## 146 | *.bak 147 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .travis.xml 2 | yarn.lock 3 | package-lock.json 4 | .editorconfig 5 | .babelrc 6 | .beautifyrc 7 | .sass-cache 8 | .bowerrc 9 | .eslintrc.yml 10 | .github 11 | .gitattributes 12 | .release.json 13 | _build 14 | bower.json 15 | composer.json 16 | gulpfile.js 17 | gulpfile.babel.js 18 | README.md 19 | CONTRIBUTING.md 20 | coverage 21 | docs 22 | test 23 | gulp 24 | test 25 | demo 26 | libs 27 | archives 28 | config.js 29 | karma.conf.js 30 | bower_components 31 | -------------------------------------------------------------------------------- /.release.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": false, 3 | "force": false, 4 | "pkgFiles": ["package.json", "bower.json"], 5 | "increment": "patch", 6 | "commitMessage": "Release v%s", 7 | "tagName": "v%s", 8 | "tagAnnotation": "Release v%s", 9 | "buildCommand": "gulp build", 10 | "npm": { 11 | "publish": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-bootstrap" 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "5.10" 4 | - "6.2" 5 | - "stable" 6 | sudo: false 7 | 8 | script: 9 | - npm run test 10 | 11 | cache: 12 | directories: 13 | - node_modules 14 | 15 | addons: 16 | sauce_connect: true 17 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this project 2 | 3 | Please take a moment to review this document in order to make the contribution 4 | process easy and effective for everyone involved. 5 | 6 | Following these guidelines helps to communicate that you respect the time of 7 | the developers managing and developing this open source project. In return, 8 | they should reciprocate that respect in addressing your issue or assessing 9 | patches and features. 10 | 11 | 12 | ## Using the issue tracker 13 | 14 | The issue tracker is the preferred channel for [bug reports](#bug-reports), 15 | [features requests](#feature-requests) and submitting pull requests, but please 16 | respect the following restrictions: 17 | 18 | * Please **do not** use the issue tracker for personal support requests (use 19 | [Stack Overflow](http://stackoverflow.com) or IRC). 20 | 21 | * Please **do not** derail or troll issues. Keep the discussion on topic and 22 | respect the opinions of others. 23 | 24 | 25 | ## Bug reports 26 | 27 | A bug is a _demonstrable problem_ that is caused by the code in the repository. 28 | Good bug reports are extremely helpful - thank you! 29 | 30 | Guidelines for bug reports: 31 | 32 | 1. **Use the GitHub issue search.** Check if the issue has already been 33 | reported. 34 | 35 | 2. **Check if the issue has been fixed.** Try to reproduce it using the 36 | latest `master` or development branch in the repository. 37 | 38 | 3. **Provide environment details.** Provide your operating system, browser(s), 39 | devices, and jquery-scrollToTop version. 40 | 41 | 4. **Create an isolated and reproducible test case.** Create a [reduced test 42 | case](http://css-tricks.com/6263-reduced-test-cases/). 43 | 44 | 5. **Include a live example.** Make use of jsFiddle or jsBin to share your 45 | isolated test cases. 46 | 47 | A good bug report shouldn't leave others needing to chase you up for more 48 | information. Please try to be as detailed as possible in your report. What is 49 | your environment? What steps will reproduce the issue? What browser(s) and OS 50 | experience the problem? What would you expect to be the outcome? All these 51 | details will help people to fix any potential bugs. 52 | 53 | Example: 54 | 55 | > Short and descriptive example bug report title 56 | > 57 | > A summary of the issue and the browser/OS environment in which it occurs. If 58 | > suitable, include the steps required to reproduce the bug. 59 | > 60 | > 1. This is the first step 61 | > 2. This is the second step 62 | > 3. Further steps, etc. 63 | > 64 | > `` - a link to the reduced test case 65 | > 66 | > Any other information you want to share that is relevant to the issue being 67 | > reported. This might include the lines of code that you have identified as 68 | > causing the bug, and potential solutions (and your opinions on their 69 | > merits). 70 | 71 | 72 | ## Feature requests 73 | 74 | Feature requests are welcome. But take a moment to find out whether your idea 75 | fits with the scope and aims of the project. It's up to *you* to make a strong 76 | case to convince the project's developers of the merits of this feature. Please 77 | provide as much detail and context as possible. 78 | 79 | 80 | ## Pull Requests 81 | 82 | **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 83 | 84 | Good pull requests - patches, improvements, new features - are a fantastic 85 | help. They should remain focused in scope and avoid containing unrelated 86 | commits. 87 | 88 | **Please ask first** before embarking on any significant pull request (e.g. 89 | implementing features, refactoring code, porting to a different language), 90 | otherwise you risk spending a lot of time working on something that the 91 | project's developers might not want to merge into the project. 92 | 93 | Please adhere to the coding conventions used throughout a project (indentation, 94 | accurate comments, etc.) and any other requirements (such as test coverage). 95 | 96 | Follow this process if you'd like your work considered for inclusion in the 97 | project: 98 | 99 | 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, 100 | and configure the remotes: 101 | 102 | ```bash 103 | # Clone your fork of the repo into the current directory 104 | git clone https://github.com// 105 | # Navigate to the newly cloned directory 106 | cd 107 | # Assign the original repo to a remote called "upstream" 108 | git remote add upstream https://github.com// 109 | ``` 110 | 111 | 2. If you cloned a while ago, get the latest changes from upstream: 112 | 113 | ```bash 114 | git checkout 115 | git pull upstream 116 | ``` 117 | 118 | 3. Create a new topic branch (off the main project development branch) to 119 | contain your feature, change, or fix: 120 | 121 | ```bash 122 | git checkout -b 123 | ``` 124 | 125 | 4. Commit your changes in logical chunks. Please adhere to these [git commit 126 | message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) 127 | or your code is unlikely be merged into the main project. Use Git's 128 | [interactive rebase](https://help.github.com/articles/interactive-rebase) 129 | feature to tidy up your commits before making them public. 130 | 131 | 5. Locally merge (or rebase) the upstream development branch into your topic branch: 132 | 133 | ```bash 134 | git pull [--rebase] upstream 135 | ``` 136 | 137 | 6. Push your topic branch up to your fork: 138 | 139 | ```bash 140 | git push origin 141 | ``` 142 | 143 | 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) 144 | with a clear title and description. 145 | 146 | **IMPORTANT**: By submitting a patch, you agree to allow the project owner to 147 | license your work under the same license as that used by the project. 148 | 149 | 150 | ## Code Consitency 151 | 152 | To help create consistent looking code throughout the project, we use a few tools to help us. 153 | 154 | #### ESlint 155 | We use [ESlint](http://eslint.org) on each build to find easy-to-catch errors and potential problems in our js. You can find our ESlint settings in the `.eslintrc.yml` file in the root of the project. 156 | 157 | #### EditorConfig 158 | 159 | We use [EditorConfig](http://EditorConfig.org) to maintain consistent coding styles between various editors and IDEs. You can find our settings in the `.editorconfig` file in the root of the project. 160 | 161 | 162 | ## Development 163 | 164 | We are using node, gulp and babel to build and (in the future) test this project. This means that you must setup a local development environment: 165 | 166 | 1. Install `node` and `npm` using your preferred method 167 | 2. Install the gulp CLI: `npm install -g gulp-cli` 168 | 3. Install the Babel CLI: `npm install -g babel-cli` 169 | 4. Install the project's development dependencies: `npm install` 170 | 171 | #### Available Tasks 172 | - `gulp` or `gulp watch` Start watch for changes and server with Browsersync. 173 | - `gulp build` Run all development tasks 174 | - `gulp serve` Start server with Browsersync. 175 | - `gulp clean` Clean output directories. 176 | - `gulp bundler` Bundle javasript modules. 177 | - `gulp scripts` Concatenate and minify JavaScript to `dist`. 178 | - `gulp lint:script` Lint ES6 files using eslint. 179 | - `gulp clean` Clean out distribution javascript files. 180 | - `gulp tdd` Test for Test Driven Development purposes. 181 | - `gulp test` Test for Continuous Integration purposes. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [jQuery scrollToTop](https://github.com/amazingSurge/jquery-scrollToTop) ![bower][bower-image] [![NPM version][npm-image]][npm-url] [![Dependency Status][daviddm-image]][daviddm-url] [![prs-welcome]](#contributing) 2 | 3 | > A jquery plugin that automatically add a button to scroll to top. 4 | 5 | ## Table of contents 6 | - [Main files](#main-files) 7 | - [Quick start](#quick-start) 8 | - [Requirements](#requirements) 9 | - [Usage](#usage) 10 | - [Examples](#examples) 11 | - [Options](#options) 12 | - [Methods](#methods) 13 | - [Events](#events) 14 | - [No conflict](#no-conflict) 15 | - [Browser support](#browser-support) 16 | - [Contributing](#contributing) 17 | - [Development](#development) 18 | - [Changelog](#changelog) 19 | - [Copyright and license](#copyright-and-license) 20 | 21 | ## Main files 22 | ``` 23 | dist/ 24 | ├── jquery-scrollToTop.js 25 | ├── jquery-scrollToTop.es.js 26 | ├── jquery-scrollToTop.min.js 27 | └── css/ 28 |    ├── scrollToTop.css 29 |    └── scrollToTop.min.css 30 | ``` 31 | 32 | ## Quick start 33 | Several quick start options are available: 34 | #### Download the latest build 35 | 36 | * [Development](https://raw.githubusercontent.com/amazingSurge/jquery-scrollToTop/master/dist/jquery-scrollToTop.js) - unminified 37 | * [Production](https://raw.githubusercontent.com/amazingSurge/jquery-scrollToTop/master/dist/jquery-scrollToTop.min.js) - minified 38 | 39 | #### Install From Bower 40 | ```sh 41 | bower install jquery-scrollToTop --save 42 | ``` 43 | 44 | #### Install From Npm 45 | ```sh 46 | npm install jquery-scrollToTop --save 47 | ``` 48 | 49 | #### Install From Yarn 50 | ```sh 51 | yarn add jquery-scrollToTop 52 | ``` 53 | 54 | #### Build From Source 55 | If you want build from source: 56 | 57 | ```sh 58 | git clone git@github.com:amazingSurge/jquery-scrollToTop.git 59 | cd jquery-scrollToTop 60 | npm install 61 | npm install -g gulp-cli babel-cli 62 | gulp build 63 | ``` 64 | 65 | Done! 66 | 67 | ## Requirements 68 | `jquery-scrollToTop` requires the latest version of [`jQuery`](https://jquery.com/download/). 69 | 70 | ## Usage 71 | #### Including files: 72 | 73 | ```html 74 | 75 | 76 | 77 | ``` 78 | 79 | #### Initialization 80 | All you need to do is call the plugin on the element: 81 | 82 | ```javascript 83 | jQuery(function($) { 84 | $('body').scrollToTop({ 85 | skin: 'cycle' 86 | }); 87 | }); 88 | ``` 89 | 90 | ## Examples 91 | There are some example usages that you can look at to get started. They can be found in the 92 | [examples folder](https://github.com/amazingSurge/jquery-scrollToTop/tree/master/examples). 93 | 94 | ## Options 95 | `jquery-scrollToTop` can accept an options object to alter the way it behaves. You can see the default options by call `$.scrollToTop.setDefaults()`. The structure of an options object is as follows: 96 | 97 | ``` 98 | { 99 | distance: 200, 100 | speed: 1000, 101 | easing: 'linear', 102 | animation: 'fade', // fade, slide, none 103 | animationSpeed: 500, 104 | 105 | mobile: { 106 | width: 768, 107 | distance: 100, 108 | speed: 1000, 109 | easing: 'easeInOutElastic', 110 | animation: 'slide', 111 | animationSpeed: 200 112 | }, 113 | 114 | trigger: null, // Set a custom triggering element. Can be an HTML string or jQuery object 115 | target: null, // Set a custom target element for scrolling to. Can be element or number 116 | text: 'Scroll To Top', // Text for element, can contain HTML 117 | 118 | skin: null, 119 | throttle: 250, 120 | 121 | namespace: 'scrollToTop' 122 | } 123 | ``` 124 | 125 | ## Methods 126 | Methods are called on scrollToTop instances through the scrollToTop method itself. 127 | You can also save the instances to variable for further use. 128 | 129 | ```javascript 130 | // call directly 131 | $().scrollToTop('destroy'); 132 | 133 | // or 134 | var api = $().data('scrollToTop'); 135 | api.destroy(); 136 | ``` 137 | 138 | #### jump() 139 | Jump to top. 140 | ```javascript 141 | $().scrollToTop('jump'); 142 | ``` 143 | 144 | #### enable() 145 | Enable the scrollbar functions. 146 | ```javascript 147 | $().scrollToTop('enable'); 148 | ``` 149 | 150 | #### disable() 151 | Disable the scrollbar functions. 152 | ```javascript 153 | $().scrollToTop('disable'); 154 | ``` 155 | 156 | #### destroy() 157 | Destroy the scrollbar instance. 158 | ```javascript 159 | $().scrollToTop('destroy'); 160 | ``` 161 | 162 | ## Events 163 | `jquery-scrollToTop` provides custom events for the plugin’s unique actions. 164 | 165 | ```javascript 166 | $('.the-element').on('scrollToTop::jump', function (e) { 167 | // on jump to top 168 | }); 169 | ``` 170 | 171 | Event | Description 172 | ------- | ----------- 173 | enable | Fired when the `enable` instance method has been called. 174 | disable | Fired when the `disable` instance method has been called. 175 | show | Fired when showing the toggle. 176 | hide | Fired when hiding the toggle. 177 | jump | Fired when jumping to the top. 178 | destroy | Fires when an instance is destroyed. 179 | 180 | ## No conflict 181 | If you have to use other plugin with the same namespace, just call the `$.scrollToTop.noConflict` method to revert to it. 182 | 183 | ```html 184 | 185 | 186 | 190 | ``` 191 | 192 | ## Browser support 193 | 194 | Tested on all major browsers. 195 | 196 | | Safari | Chrome | Firefox | Edge | IE | Opera | 197 | |:--:|:--:|:--:|:--:|:--:|:--:| 198 | | Latest ✓ | Latest ✓ | Latest ✓ | Latest ✓ | 9-11 ✓ | Latest ✓ | 199 | 200 | As a jQuery plugin, you also need to see the [jQuery Browser Support](http://jquery.com/browser-support/). 201 | 202 | ## Contributing 203 | Anyone and everyone is welcome to contribute. Please take a moment to 204 | review the [guidelines for contributing](CONTRIBUTING.md). Make sure you're using the latest version of `jquery-scrollToTop` before submitting an issue. There are several ways to help out: 205 | 206 | * [Bug reports](CONTRIBUTING.md#bug-reports) 207 | * [Feature requests](CONTRIBUTING.md#feature-requests) 208 | * [Pull requests](CONTRIBUTING.md#pull-requests) 209 | * Write test cases for open bug issues 210 | * Contribute to the documentation 211 | 212 | ## Development 213 | `jquery-scrollToTop` is built modularly and uses Gulp as a build system to build its distributable files. To install the necessary dependencies for the build system, please run: 214 | 215 | ```sh 216 | npm install -g gulp 217 | npm install -g babel-cli 218 | npm install 219 | ``` 220 | 221 | Then you can generate new distributable files from the sources, using: 222 | ``` 223 | gulp build 224 | ``` 225 | 226 | More gulp tasks can be found [here](CONTRIBUTING.md#available-tasks). 227 | 228 | ## Changelog 229 | To see the list of recent changes, see [Releases section](https://github.com/amazingSurge/jquery-scrollToTop/releases). 230 | 231 | ## Copyright and license 232 | Copyright (C) 2016 amazingSurge. 233 | 234 | Licensed under [the LGPL license](LICENSE). 235 | 236 | [⬆ back to top](#table-of-contents) 237 | 238 | [bower-image]: https://img.shields.io/bower/v/jquery-scrollToTop.svg?style=flat 239 | [bower-link]: https://david-dm.org/amazingSurge/jquery-scrollToTop/dev-status.svg 240 | [npm-image]: https://badge.fury.io/js/jquery-scrollToTop.svg?style=flat 241 | [npm-url]: https://npmjs.org/package/jquery-scrollToTop 242 | [license]: https://img.shields.io/npm/l/jquery-scrollToTop.svg?style=flat 243 | [prs-welcome]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg 244 | [daviddm-image]: https://david-dm.org/amazingSurge/jquery-scrollToTop.svg?style=flat 245 | [daviddm-url]: https://david-dm.org/amazingSurge/jquery-scrollToTop 246 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-scrollToTop", 3 | "version": "0.4.3", 4 | "description": "A jquery plugin that automatically add a button to scroll to top.", 5 | "main": "dist/jquery-scrollToTop.js", 6 | "copyright": "amazingSurge", 7 | "license": "LGPL-3.0", 8 | "ignore": [ 9 | "**/.*", 10 | "node_modules", 11 | "bower_components", 12 | "test", 13 | "demo", 14 | "gulp", 15 | "CONTRIBUTING.md", 16 | "manifest.json", 17 | "karma.conf.js", 18 | "config.js", 19 | "package.json", 20 | "gulpfile.babel.js", 21 | "tests" 22 | ], 23 | "homepage": "https://github.com/amazingSurge/jquery-scrollToTop", 24 | "authors": [ 25 | "amazingSurge " 26 | ], 27 | "moduleType": [ 28 | "globals" 29 | ], 30 | "dependencies": { 31 | "jquery": ">=2.2.0", 32 | "easing": "git@github.com:amazingSurge/easing.css.git" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import fs from 'graceful-fs'; 4 | import {argv} from 'yargs'; 5 | 6 | const production = argv.production || argv.prod || false; 7 | 8 | export default { 9 | getConfig: function(pkg, src, dest) { 10 | return { 11 | version: pkg.version, 12 | name: pkg.name, 13 | title: pkg.title, 14 | description: pkg.description, 15 | author: pkg.author, 16 | banner: `/** 17 | * ${pkg.title} v${pkg.version} 18 | * ${pkg.homepage} 19 | * 20 | * Copyright (c) ${pkg.author.name} 21 | * Released under the ${pkg.license} license 22 | */ 23 | `, 24 | // basic locations 25 | paths: { 26 | root: './', 27 | srcDir: `${src}/`, 28 | destDir: `${dest}/`, 29 | }, 30 | 31 | styles: { 32 | files: '**/*.scss', 33 | src: `${src}/scss`, 34 | dest: `${dest}/css`, 35 | prodSourcemap: false, 36 | sassIncludePaths: [], 37 | autoprefixer: { 38 | browsers: ['last 2 versions', 'ie >= 9', 'Android >= 2.3'] 39 | } 40 | }, 41 | 42 | scripts: { 43 | input: 'main.js', 44 | version: 'info.js', 45 | files: '**/*.js', 46 | src: `${src}`, 47 | dest: `${dest}`, 48 | prodSourcemap: false, 49 | test: './test', 50 | gulp: './gulp' 51 | }, 52 | 53 | images: { 54 | files: '**/*.{png,jpg,gif,svg}', 55 | src: `${src}/images`, 56 | dest: `${dest}/images` 57 | }, 58 | 59 | archive: { 60 | src: `${dest}/**/*`, 61 | dest: './archives/', 62 | zip: {} 63 | }, 64 | 65 | browser: { 66 | baseDir: './', 67 | startPath: "examples/index.html", 68 | browserPort: 3000, 69 | UIPort: 3001, 70 | testPort: 3002, 71 | }, 72 | 73 | deploy: { 74 | versionFiles: ['package.json', 'bower.json'], 75 | increment: "patch", // major, minor, patch, premajor, preminor, prepatch, or prerelease. 76 | }, 77 | 78 | notify: { 79 | title: pkg.title 80 | }, 81 | 82 | env: 'development', 83 | production: production, 84 | setEnv: function(env) { 85 | if (typeof env !== 'string') return; 86 | this.env = env; 87 | this.production = env === 'production'; 88 | process.env.NODE_ENV = env; 89 | }, 90 | 91 | test: {}, 92 | }; 93 | }, 94 | 95 | init: function() { 96 | const pkg = JSON.parse(fs.readFileSync('./package.json', { encoding: 'utf-8' })); 97 | 98 | let src = 'src'; 99 | let dest = 'dist'; 100 | 101 | Object.assign(this, this.getConfig(pkg, src, dest, production)); 102 | this.setEnv(production? 'production': 'development'); 103 | 104 | return this; 105 | } 106 | 107 | }.init(); 108 | -------------------------------------------------------------------------------- /dist/css/easing.css: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery scrollToTop v0.4.3 3 | * https://github.com/amazingSurge/jquery-scrollToTop 4 | * 5 | * Copyright (c) amazingSurge 6 | * Released under the LGPL-3.0 license 7 | */ 8 | .easing_linear { 9 | -webkit-transition-timing-function: cubic-bezier(.25, .25, .75, .75); 10 | transition-timing-function: cubic-bezier(.25, .25, .75, .75); 11 | } 12 | 13 | .easing_ease { 14 | -webkit-transition-timing-function: cubic-bezier(.25, .1, .25, 1); 15 | transition-timing-function: cubic-bezier(.25, .1, .25, 1); 16 | } 17 | 18 | .easing_easeIn { 19 | -webkit-transition-timing-function: cubic-bezier(.42, 0, 1, 1); 20 | transition-timing-function: cubic-bezier(.42, 0, 1, 1); 21 | } 22 | 23 | .easing_easeOut { 24 | -webkit-transition-timing-function: cubic-bezier(0, 0, .58, 1); 25 | transition-timing-function: cubic-bezier(0, 0, .58, 1); 26 | } 27 | 28 | .easing_easeInOut { 29 | -webkit-transition-timing-function: cubic-bezier(.42, 0, .58, 1); 30 | transition-timing-function: cubic-bezier(.42, 0, .58, 1); 31 | } 32 | 33 | .easing_easeInQuad { 34 | -webkit-transition-timing-function: cubic-bezier(.55, .085, .68, .53); 35 | transition-timing-function: cubic-bezier(.55, .085, .68, .53); 36 | } 37 | 38 | .easing_easeInCubic { 39 | -webkit-transition-timing-function: cubic-bezier(.55, .055, .675, .19); 40 | transition-timing-function: cubic-bezier(.55, .055, .675, .19); 41 | } 42 | 43 | .easing_easeInQuart { 44 | -webkit-transition-timing-function: cubic-bezier(.895, .03, .685, .22); 45 | transition-timing-function: cubic-bezier(.895, .03, .685, .22); 46 | } 47 | 48 | .easing_easeInQuint { 49 | -webkit-transition-timing-function: cubic-bezier(.755, .05, .855, .06); 50 | transition-timing-function: cubic-bezier(.755, .05, .855, .06); 51 | } 52 | 53 | .easing_easeInSine { 54 | -webkit-transition-timing-function: cubic-bezier(.47, 0, .745, .715); 55 | transition-timing-function: cubic-bezier(.47, 0, .745, .715); 56 | } 57 | 58 | .easing_easeInExpo { 59 | -webkit-transition-timing-function: cubic-bezier(.95, .05, .795, .035); 60 | transition-timing-function: cubic-bezier(.95, .05, .795, .035); 61 | } 62 | 63 | .easing_easeInCirc { 64 | -webkit-transition-timing-function: cubic-bezier(.6, .04, .98, .335); 65 | transition-timing-function: cubic-bezier(.6, .04, .98, .335); 66 | } 67 | 68 | .easing_easeInBack { 69 | -webkit-transition-timing-function: cubic-bezier(.6, -.28, .735, .045); 70 | transition-timing-function: cubic-bezier(.6, -.28, .735, .045); 71 | } 72 | 73 | .easing_eastOutQuad { 74 | -webkit-transition-timing-function: cubic-bezier(.25, .46, .45, .94); 75 | transition-timing-function: cubic-bezier(.25, .46, .45, .94); 76 | } 77 | 78 | .easing_easeOutCubic { 79 | -webkit-transition-timing-function: cubic-bezier(.215, .61, .355, 1); 80 | transition-timing-function: cubic-bezier(.215, .61, .355, 1); 81 | } 82 | 83 | .easing_easeOutQuart { 84 | -webkit-transition-timing-function: cubic-bezier(.165, .84, .44, 1); 85 | transition-timing-function: cubic-bezier(.165, .84, .44, 1); 86 | } 87 | 88 | .easing_easeOutQuint { 89 | -webkit-transition-timing-function: cubic-bezier(.23, 1, .32, 1); 90 | transition-timing-function: cubic-bezier(.23, 1, .32, 1); 91 | } 92 | 93 | .easing_easeOutSine { 94 | -webkit-transition-timing-function: cubic-bezier(.39, .575, .565, 1); 95 | transition-timing-function: cubic-bezier(.39, .575, .565, 1); 96 | } 97 | 98 | .easing_easeOutExpo { 99 | -webkit-transition-timing-function: cubic-bezier(.19, 1, .22, 1); 100 | transition-timing-function: cubic-bezier(.19, 1, .22, 1); 101 | } 102 | 103 | .easing_easeOutCirc { 104 | -webkit-transition-timing-function: cubic-bezier(.075, .82, .165, 1); 105 | transition-timing-function: cubic-bezier(.075, .82, .165, 1); 106 | } 107 | 108 | .easing_easeOutBack { 109 | -webkit-transition-timing-function: cubic-bezier(.175, .885, .32, 1.275); 110 | transition-timing-function: cubic-bezier(.175, .885, .32, 1.275); 111 | } 112 | 113 | .easing_easeInOutQuad { 114 | -webkit-transition-timing-function: cubic-bezier(.455, .03, .515, .955); 115 | transition-timing-function: cubic-bezier(.455, .03, .515, .955); 116 | } 117 | 118 | .easing_easeInOutCubic { 119 | -webkit-transition-timing-function: cubic-bezier(.645, .045, .355, 1); 120 | transition-timing-function: cubic-bezier(.645, .045, .355, 1); 121 | } 122 | 123 | .easing_easeInOutQuart { 124 | -webkit-transition-timing-function: cubic-bezier(.77, 0, .175, 1); 125 | transition-timing-function: cubic-bezier(.77, 0, .175, 1); 126 | } 127 | 128 | .easing_easeInOutQuint { 129 | -webkit-transition-timing-function: cubic-bezier(.86, 0, .07, 1); 130 | transition-timing-function: cubic-bezier(.86, 0, .07, 1); 131 | } 132 | 133 | .easing_easeInOutSine { 134 | -webkit-transition-timing-function: cubic-bezier(.445, .05, .55, .95); 135 | transition-timing-function: cubic-bezier(.445, .05, .55, .95); 136 | } 137 | 138 | .easing_easeInOutExpo { 139 | -webkit-transition-timing-function: cubic-bezier(1, 0, 0, 1); 140 | transition-timing-function: cubic-bezier(1, 0, 0, 1); 141 | } 142 | 143 | .easing_easeInOutCirc { 144 | -webkit-transition-timing-function: cubic-bezier(.785, .135, .15, .86); 145 | transition-timing-function: cubic-bezier(.785, .135, .15, .86); 146 | } 147 | 148 | .easing_easeInOutBack { 149 | -webkit-transition-timing-function: cubic-bezier(.68, -.55, .265, 1.55); 150 | transition-timing-function: cubic-bezier(.68, -.55, .265, 1.55); 151 | } 152 | 153 | .easing_easeInOutElastic { 154 | -webkit-transition-timing-function: cubic-bezier(1, -.56, 0, 1.455); 155 | transition-timing-function: cubic-bezier(1, -.56, 0, 1.455); 156 | } 157 | 158 | .easing_custom { 159 | -webkit-transition-timing-function: cubic-bezier(.5, .25, .5, .75); 160 | transition-timing-function: cubic-bezier(.5, .25, .5, .75); 161 | } 162 | -------------------------------------------------------------------------------- /dist/css/easing.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery scrollToTop v0.4.3 3 | * https://github.com/amazingSurge/jquery-scrollToTop 4 | * 5 | * Copyright (c) amazingSurge 6 | * Released under the LGPL-3.0 license 7 | */ 8 | .easing_linear{-webkit-transition-timing-function:cubic-bezier(.25,.25,.75,.75);transition-timing-function:cubic-bezier(.25,.25,.75,.75)}.easing_ease{-webkit-transition-timing-function:ease;transition-timing-function:ease}.easing_easeIn{-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in}.easing_easeOut{-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out}.easing_easeInOut{-webkit-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out}.easing_easeInQuad{-webkit-transition-timing-function:cubic-bezier(.55,.085,.68,.53);transition-timing-function:cubic-bezier(.55,.085,.68,.53)}.easing_easeInCubic{-webkit-transition-timing-function:cubic-bezier(.55,.055,.675,.19);transition-timing-function:cubic-bezier(.55,.055,.675,.19)}.easing_easeInQuart{-webkit-transition-timing-function:cubic-bezier(.895,.03,.685,.22);transition-timing-function:cubic-bezier(.895,.03,.685,.22)}.easing_easeInQuint{-webkit-transition-timing-function:cubic-bezier(.755,.05,.855,.06);transition-timing-function:cubic-bezier(.755,.05,.855,.06)}.easing_easeInSine{-webkit-transition-timing-function:cubic-bezier(.47,0,.745,.715);transition-timing-function:cubic-bezier(.47,0,.745,.715)}.easing_easeInExpo{-webkit-transition-timing-function:cubic-bezier(.95,.05,.795,.035);transition-timing-function:cubic-bezier(.95,.05,.795,.035)}.easing_easeInCirc{-webkit-transition-timing-function:cubic-bezier(.6,.04,.98,.335);transition-timing-function:cubic-bezier(.6,.04,.98,.335)}.easing_easeInBack{-webkit-transition-timing-function:cubic-bezier(.6,-.28,.735,.045);transition-timing-function:cubic-bezier(.6,-.28,.735,.045)}.easing_eastOutQuad{-webkit-transition-timing-function:cubic-bezier(.25,.46,.45,.94);transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.easing_easeOutCubic{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1)}.easing_easeOutQuart{-webkit-transition-timing-function:cubic-bezier(.165,.84,.44,1);transition-timing-function:cubic-bezier(.165,.84,.44,1)}.easing_easeOutQuint{-webkit-transition-timing-function:cubic-bezier(.23,1,.32,1);transition-timing-function:cubic-bezier(.23,1,.32,1)}.easing_easeOutSine{-webkit-transition-timing-function:cubic-bezier(.39,.575,.565,1);transition-timing-function:cubic-bezier(.39,.575,.565,1)}.easing_easeOutExpo{-webkit-transition-timing-function:cubic-bezier(.19,1,.22,1);transition-timing-function:cubic-bezier(.19,1,.22,1)}.easing_easeOutCirc{-webkit-transition-timing-function:cubic-bezier(.075,.82,.165,1);transition-timing-function:cubic-bezier(.075,.82,.165,1)}.easing_easeOutBack{-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.275);transition-timing-function:cubic-bezier(.175,.885,.32,1.275)}.easing_easeInOutQuad{-webkit-transition-timing-function:cubic-bezier(.455,.03,.515,.955);transition-timing-function:cubic-bezier(.455,.03,.515,.955)}.easing_easeInOutCubic{-webkit-transition-timing-function:cubic-bezier(.645,.045,.355,1);transition-timing-function:cubic-bezier(.645,.045,.355,1)}.easing_easeInOutQuart{-webkit-transition-timing-function:cubic-bezier(.77,0,.175,1);transition-timing-function:cubic-bezier(.77,0,.175,1)}.easing_easeInOutQuint{-webkit-transition-timing-function:cubic-bezier(.86,0,.07,1);transition-timing-function:cubic-bezier(.86,0,.07,1)}.easing_easeInOutSine{-webkit-transition-timing-function:cubic-bezier(.445,.05,.55,.95);transition-timing-function:cubic-bezier(.445,.05,.55,.95)}.easing_easeInOutExpo{-webkit-transition-timing-function:cubic-bezier(1,0,0,1);transition-timing-function:cubic-bezier(1,0,0,1)}.easing_easeInOutCirc{-webkit-transition-timing-function:cubic-bezier(.785,.135,.15,.86);transition-timing-function:cubic-bezier(.785,.135,.15,.86)}.easing_easeInOutBack{-webkit-transition-timing-function:cubic-bezier(.68,-.55,.265,1.55);transition-timing-function:cubic-bezier(.68,-.55,.265,1.55)}.easing_easeInOutElastic{-webkit-transition-timing-function:cubic-bezier(1,-.56,0,1.455);transition-timing-function:cubic-bezier(1,-.56,0,1.455)}.easing_custom{-webkit-transition-timing-function:cubic-bezier(.5,.25,.5,.75);transition-timing-function:cubic-bezier(.5,.25,.5,.75)} 9 | /*# sourceMappingURL=easing.min.css.map */ 10 | -------------------------------------------------------------------------------- /dist/css/scrollToTop.css: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery scrollToTop v0.4.3 3 | * https://github.com/amazingSurge/jquery-scrollToTop 4 | * 5 | * Copyright (c) amazingSurge 6 | * Released under the LGPL-3.0 license 7 | */ 8 | html { 9 | overflow-y: scroll; 10 | } 11 | 12 | /* core */ 13 | .scrollToTop { 14 | position: fixed; 15 | right: 20px; 16 | bottom: -100px; 17 | overflow: hidden; 18 | outline: none; 19 | opacity: 0; 20 | } 21 | .scrollToTop_show { 22 | bottom: 20px; 23 | opacity: 1; 24 | } 25 | .scrollToTop_animating, .scrollToTop_animating * { 26 | pointer-events: none !important; 27 | } 28 | 29 | @-webkit-keyframes scrollToTop_fade { 30 | 0% { 31 | opacity: 0; 32 | } 33 | 100% { 34 | opacity: 1; 35 | } 36 | } 37 | 38 | @keyframes scrollToTop_fade { 39 | 0% { 40 | opacity: 0; 41 | } 42 | 100% { 43 | opacity: 1; 44 | } 45 | } 46 | 47 | @-webkit-keyframes scrollToTop_slide { 48 | 0% { 49 | bottom: -100px; 50 | } 51 | 100% { 52 | bottom: 20px; 53 | } 54 | } 55 | 56 | @keyframes scrollToTop_slide { 57 | 0% { 58 | bottom: -100px; 59 | } 60 | 100% { 61 | bottom: 20px; 62 | } 63 | } 64 | 65 | /* skins */ 66 | .scrollToTop { 67 | width: 50px; 68 | height: 50px; 69 | font-family: sans-serif; 70 | font-size: 12px; 71 | color: #000; 72 | text-decoration: none; 73 | text-indent: 100%; 74 | text-transform: uppercase; 75 | white-space: nowrap; 76 | background: no-repeat center center transparent; 77 | outline: none; 78 | } 79 | .scrollToTop_default { 80 | display: block; 81 | width: auto; 82 | height: auto; 83 | padding: 10px; 84 | text-indent: 0; 85 | background: #eee; 86 | border-radius: 10px; 87 | } 88 | .scrollToTop_default :hover { 89 | background-color: #ddd; 90 | } 91 | .scrollToTop_cycle { 92 | background-image: url("../images/cycle.png"); 93 | } 94 | .scrollToTop_cycle:hover { 95 | background-image: url("../images/cycle-hover.png"); 96 | } 97 | .scrollToTop_square { 98 | background-image: url("../images/square.png"); 99 | } 100 | .scrollToTop_square:hover { 101 | background-image: url("../images/square-hover.png"); 102 | } 103 | .scrollToTop_text { 104 | background-image: url("../images/text.png"); 105 | } 106 | .scrollToTop_text:hover { 107 | background-image: url("../images/text-hover.png"); 108 | } 109 | .scrollToTop_triangle { 110 | background-image: url("../images/triangle.png"); 111 | } 112 | .scrollToTop_triangle:hover { 113 | background-image: url("../images/triangle-hover.png"); 114 | } 115 | -------------------------------------------------------------------------------- /dist/css/scrollToTop.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery scrollToTop v0.4.3 3 | * https://github.com/amazingSurge/jquery-scrollToTop 4 | * 5 | * Copyright (c) amazingSurge 6 | * Released under the LGPL-3.0 license 7 | */ 8 | html{overflow-y:scroll}.scrollToTop{position:fixed;right:20px;bottom:-100px;overflow:hidden;opacity:0}.scrollToTop_show{bottom:20px;opacity:1}.scrollToTop_animating,.scrollToTop_animating *{pointer-events:none!important}@-webkit-keyframes scrollToTop_fade{0%{opacity:0}to{opacity:1}}@keyframes scrollToTop_fade{0%{opacity:0}to{opacity:1}}@-webkit-keyframes scrollToTop_slide{0%{bottom:-100px}to{bottom:20px}}@keyframes scrollToTop_slide{0%{bottom:-100px}to{bottom:20px}}.scrollToTop{width:50px;height:50px;font-family:sans-serif;font-size:12px;color:#000;text-decoration:none;text-indent:100%;text-transform:uppercase;white-space:nowrap;background:no-repeat 50% transparent;outline:none}.scrollToTop_default{display:block;width:auto;height:auto;padding:10px;text-indent:0;background:#eee;border-radius:10px}.scrollToTop_default :hover{background-color:#ddd}.scrollToTop_cycle{background-image:url(../images/cycle.png)}.scrollToTop_cycle:hover{background-image:url(../images/cycle-hover.png)}.scrollToTop_square{background-image:url(../images/square.png)}.scrollToTop_square:hover{background-image:url(../images/square-hover.png)}.scrollToTop_text{background-image:url(../images/text.png)}.scrollToTop_text:hover{background-image:url(../images/text-hover.png)}.scrollToTop_triangle{background-image:url(../images/triangle.png)}.scrollToTop_triangle:hover{background-image:url(../images/triangle-hover.png)} 9 | /*# sourceMappingURL=scrollToTop.min.css.map */ 10 | -------------------------------------------------------------------------------- /dist/images/cycle-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/dist/images/cycle-hover.png -------------------------------------------------------------------------------- /dist/images/cycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/dist/images/cycle.png -------------------------------------------------------------------------------- /dist/images/square-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/dist/images/square-hover.png -------------------------------------------------------------------------------- /dist/images/square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/dist/images/square.png -------------------------------------------------------------------------------- /dist/images/text-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/dist/images/text-hover.png -------------------------------------------------------------------------------- /dist/images/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/dist/images/text.png -------------------------------------------------------------------------------- /dist/images/triangle-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/dist/images/triangle-hover.png -------------------------------------------------------------------------------- /dist/images/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/dist/images/triangle.png -------------------------------------------------------------------------------- /dist/jquery-scrollToTop.es.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery scrollToTop v0.4.3 3 | * https://github.com/amazingSurge/jquery-scrollToTop 4 | * 5 | * Copyright (c) amazingSurge 6 | * Released under the LGPL-3.0 license 7 | */ 8 | import $ from 'jquery'; 9 | 10 | var DEFAULTS = { 11 | distance: 200, 12 | speed: 1000, 13 | easing: 'linear', 14 | animation: 'fade', // fade, slide, none 15 | animationSpeed: 500, 16 | 17 | mobile: { 18 | width: 768, 19 | distance: 100, 20 | speed: 1000, 21 | easing: 'easeInOutElastic', 22 | animation: 'slide', 23 | animationSpeed: 200 24 | }, 25 | 26 | trigger: null, // Set a custom triggering element. Can be an HTML string or jQuery object 27 | target: null, // Set a custom target element for scrolling to. Can be element or number 28 | text: 'Scroll To Top', // Text for element, can contain HTML 29 | 30 | skin: null, 31 | throttle: 250, 32 | 33 | namespace: 'scrollToTop' 34 | }; 35 | 36 | function transition() { 37 | let e; 38 | let end; 39 | let prefix = ''; 40 | let supported = false; 41 | const el = document.createElement("fakeelement"); 42 | 43 | const transitions = { 44 | "WebkitTransition": "webkitTransitionEnd", 45 | "MozTransition": "transitionend", 46 | "OTransition": "oTransitionend", 47 | "transition": "transitionend" 48 | }; 49 | 50 | for (e in transitions) { 51 | if (el.style[e] !== undefined) { 52 | end = transitions[e]; 53 | supported = true; 54 | break; 55 | } 56 | } 57 | if (/(WebKit)/i.test(window.navigator.userAgent)) { 58 | prefix = '-webkit-'; 59 | } 60 | return { 61 | prefix, 62 | end, 63 | supported 64 | }; 65 | } 66 | 67 | function throttle(func, wait) { 68 | const _now = Date.now || function() { 69 | return new Date().getTime(); 70 | }; 71 | 72 | let timeout; 73 | let context; 74 | let args; 75 | let result; 76 | let previous = 0; 77 | let later = function() { 78 | previous = _now(); 79 | timeout = null; 80 | result = func.apply(context, args); 81 | if (!timeout) { 82 | context = args = null; 83 | } 84 | }; 85 | 86 | return (...params) => { 87 | /*eslint consistent-this: "off"*/ 88 | let now = _now(); 89 | let remaining = wait - (now - previous); 90 | context = this; 91 | args = params; 92 | if (remaining <= 0 || remaining > wait) { 93 | if (timeout) { 94 | clearTimeout(timeout); 95 | timeout = null; 96 | } 97 | previous = now; 98 | result = func.apply(context, args); 99 | if (!timeout) { 100 | context = args = null; 101 | } 102 | } else if (!timeout) { 103 | timeout = setTimeout(later, remaining); 104 | } 105 | return result; 106 | }; 107 | } 108 | 109 | /** 110 | * Plugin constructor 111 | **/ 112 | class ScrollToTop { 113 | constructor(options = {}) { 114 | this.$doc = $('body'); 115 | this.options = $.extend(true, {}, DEFAULTS, options); 116 | 117 | const namespace = this.options.namespace; 118 | 119 | if (this.options.skin === null) { 120 | this.options.skin = 'default'; 121 | } 122 | 123 | this.classes = { 124 | skin: `${namespace}_${this.options.skin}`, 125 | trigger: namespace, 126 | animating: `${namespace}_animating`, 127 | show: `${namespace}_show` 128 | }; 129 | 130 | this.disabled = false; 131 | this.useMobile = false; 132 | this.isShow = false; 133 | 134 | this._init(); 135 | } 136 | 137 | _init() { 138 | this.transition = transition(); 139 | this._build(); 140 | 141 | if (this.options.target) { 142 | if (typeof this.options.target === 'number') { 143 | this.target = this.options.target; 144 | } else if (typeof this.options.target === 'string') { 145 | this.target = Math.floor($(this.options.target).offset().top); 146 | } 147 | } else { 148 | this.target = 0; 149 | } 150 | 151 | this._bindEvents(); 152 | 153 | this._toggle(); 154 | } 155 | 156 | _bindEvents() { 157 | this.$trigger.on('click.scrollToTop', () => { 158 | this.$doc.trigger('ScrollToTop::jump'); 159 | return false; 160 | }); 161 | 162 | // bind events 163 | this.$doc.on('ScrollToTop::jump', () => { 164 | if (this.disabled) { 165 | return; 166 | } 167 | 168 | this.checkMobile(); 169 | 170 | let speed; 171 | let easing; 172 | 173 | if (this.useMobile) { 174 | speed = this.options.mobile.speed; 175 | easing = this.options.mobile.easing; 176 | } else { 177 | speed = this.options.speed; 178 | easing = this.options.easing; 179 | } 180 | 181 | this.$doc.addClass(this.classes.animating); 182 | 183 | if (this.transition.supported) { 184 | const pos = $(window).scrollTop(); 185 | 186 | this.$doc.css({ 187 | 'margin-top': `${-pos + this.target}px` 188 | }); 189 | $(window).scrollTop(this.target); 190 | 191 | this._insertRule(`.duration_${speed}{${this.transition.prefix}transition-duration: ${speed}ms;}`); 192 | 193 | this.$doc.addClass(`easing_${easing} duration_${speed}`).css({ 194 | 'margin-top': '' 195 | }).one(this.transition.end, () => { 196 | this.$doc.removeClass(`${this.classes.animating} easing_${easing} duration_${speed}`); 197 | }); 198 | } else { 199 | $('html, body').stop(true, false).animate({ 200 | scrollTop: this.target 201 | }, speed, () => { 202 | this.$doc.removeClass(this.classes.animating); 203 | }); 204 | return; 205 | } 206 | }) 207 | .on('ScrollToTop::show', () => { 208 | if (this.isShow) { 209 | return; 210 | } 211 | this.isShow = true; 212 | 213 | this.$trigger.addClass(this.classes.show); 214 | }) 215 | .on('ScrollToTop::hide', () => { 216 | if (!this.isShow) { 217 | return; 218 | } 219 | this.isShow = false; 220 | this.$trigger.removeClass(this.classes.show); 221 | }) 222 | .on('ScrollToTop::disable', () => { 223 | this.disabled = true; 224 | this.$doc.trigger('ScrollToTop::hide'); 225 | }) 226 | .on('ScrollToTop::enable', () => { 227 | this.disabled = false; 228 | this._toggle(); 229 | }); 230 | 231 | $(window).on('scroll.ScrollToTop', throttle(() => { 232 | if (this.disabled) { 233 | return; 234 | } 235 | 236 | this._toggle(); 237 | }, this.options.throttle)); 238 | 239 | if (this.options.mobile) { 240 | $(window).on('resize.ScrollToTop orientationchange.ScrollToTop', throttle(() => { 241 | if (this.disabled) { 242 | return; 243 | } 244 | 245 | this.checkMobile(); 246 | }, this.options.throttle)); 247 | } 248 | } 249 | 250 | _build() { 251 | if (this.options.trigger) { 252 | this.$trigger = $(this.options.trigger); 253 | } else { 254 | this.$trigger = $(`${this.options.text}`).appendTo($('body')); 255 | } 256 | 257 | this._insertRule(`.${this.classes.show}{${this.transition.prefix}animation-duration: ${this.options.animationSpeed}ms;${this.transition.prefix}animation-name: ${this.options.namespace}_${this.options.animation};}`); 258 | 259 | if (this.options.mobile) { 260 | this._insertRule(`@media (max-width: ${this.options.mobile.width}px){.${this.classes.show}{${this.transition.prefix}animation-duration: ${this.options.mobile.animationSpeed}ms !important;${this.transition.prefix}animation-name: ${this.options.namespace}_${this.options.mobile.animation} !important;}}`); 261 | } 262 | } 263 | 264 | checkMobile() { 265 | const width = $(window).width(); 266 | 267 | if (width < this.options.mobile.width) { 268 | this.useMobile = true; 269 | } else { 270 | this.useMobile = false; 271 | } 272 | } 273 | 274 | can() { 275 | let distance; 276 | if (this.useMobile) { 277 | distance = this.options.mobile.distance; 278 | } else { 279 | distance = this.options.distance; 280 | } 281 | if ($(window).scrollTop() > distance) { 282 | return true; 283 | } 284 | return false; 285 | } 286 | 287 | _toggle() { 288 | if (this.can()) { 289 | this.$doc.trigger('ScrollToTop::show'); 290 | } else { 291 | this.$doc.trigger('ScrollToTop::hide'); 292 | } 293 | } 294 | 295 | _insertRule(rule) { 296 | if (this.rules && this.rules[rule]) { 297 | return; 298 | } else if (this.rules === undefined) { 299 | this.rules = {}; 300 | } else { 301 | this.rules[rule] = true; 302 | } 303 | 304 | if (document.styleSheets && document.styleSheets.length) { 305 | document.styleSheets[0].insertRule(rule, 0); 306 | } else { 307 | const style = document.createElement('style'); 308 | style.innerHTML = rule; 309 | document.head.appendChild(style); 310 | } 311 | } 312 | 313 | jump() { 314 | this.$doc.trigger('ScrollToTop::jump'); 315 | } 316 | 317 | disable() { 318 | this.$doc.trigger('ScrollToTop::disable'); 319 | } 320 | 321 | enable() { 322 | this.$doc.trigger('ScrollToTop::enable'); 323 | } 324 | 325 | destroy() { 326 | this.$trigger.remove(); 327 | this.$doc.data('ScrollToTop', null); 328 | this.$doc.off('ScrollToTop::enable') 329 | .off('ScrollToTop::disable') 330 | .off('ScrollToTop::jump') 331 | .off('ScrollToTop::show') 332 | .off('ScrollToTop::hide'); 333 | $(window).off('.ScrollToTop'); 334 | } 335 | 336 | static setDefaults(options) { 337 | $.extend(true, DEFAULTS, $.isPlainObject(options) && options); 338 | } 339 | } 340 | 341 | var info = { 342 | version:'0.4.3' 343 | }; 344 | 345 | const NAMESPACE = 'scrollToTop'; 346 | const OtherScrollToTop = $.fn.scrollToTop; 347 | 348 | const jQueryScrollToTop = function(options, ...args) { 349 | if (typeof options === 'string') { 350 | const method = options; 351 | 352 | if (/^_/.test(method)) { 353 | return false; 354 | } else if ((/^(get)/.test(method))) { 355 | const instance = this.first().data(NAMESPACE); 356 | if (instance && typeof instance[method] === 'function') { 357 | return instance[method](...args); 358 | } 359 | } else { 360 | return this.each(function() { 361 | const instance = $.data(this, NAMESPACE); 362 | if (instance && typeof instance[method] === 'function') { 363 | instance[method](...args); 364 | } 365 | }); 366 | } 367 | } 368 | 369 | return this.each(function() { 370 | if (!$(this).data(NAMESPACE)) { 371 | $(this).data(NAMESPACE, new ScrollToTop(options)); 372 | } 373 | }); 374 | }; 375 | 376 | $.fn.scrollToTop = jQueryScrollToTop; 377 | 378 | $.scrollToTop = $.extend({ 379 | setDefaults: ScrollToTop.setDefaults, 380 | noConflict: function() { 381 | $.fn.scrollToTop = OtherScrollToTop; 382 | return jQueryScrollToTop; 383 | } 384 | }, info); 385 | -------------------------------------------------------------------------------- /dist/jquery-scrollToTop.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery scrollToTop v0.4.3 3 | * https://github.com/amazingSurge/jquery-scrollToTop 4 | * 5 | * Copyright (c) amazingSurge 6 | * Released under the LGPL-3.0 license 7 | */ 8 | (function(global, factory) { 9 | if (typeof define === 'function' && define.amd) { 10 | define(['jquery'], factory); 11 | } else if (typeof exports !== 'undefined') { 12 | factory(require('jquery')); 13 | } else { 14 | var mod = { 15 | exports: {} 16 | }; 17 | factory(global.jQuery); 18 | global.jqueryScrollToTopEs = mod.exports; 19 | } 20 | })(this, function(_jquery) { 21 | 'use strict'; 22 | 23 | var _jquery2 = _interopRequireDefault(_jquery); 24 | 25 | function _interopRequireDefault(obj) { 26 | return obj && obj.__esModule 27 | ? obj 28 | : { 29 | default: obj 30 | }; 31 | } 32 | 33 | function _classCallCheck(instance, Constructor) { 34 | if (!(instance instanceof Constructor)) { 35 | throw new TypeError('Cannot call a class as a function'); 36 | } 37 | } 38 | 39 | var _createClass = (function() { 40 | function defineProperties(target, props) { 41 | for (var i = 0; i < props.length; i++) { 42 | var descriptor = props[i]; 43 | descriptor.enumerable = descriptor.enumerable || false; 44 | descriptor.configurable = true; 45 | if ('value' in descriptor) descriptor.writable = true; 46 | Object.defineProperty(target, descriptor.key, descriptor); 47 | } 48 | } 49 | 50 | return function(Constructor, protoProps, staticProps) { 51 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 52 | if (staticProps) defineProperties(Constructor, staticProps); 53 | return Constructor; 54 | }; 55 | })(); 56 | 57 | var DEFAULTS = { 58 | distance: 200, 59 | speed: 1000, 60 | easing: 'linear', 61 | animation: 'fade', // fade, slide, none 62 | animationSpeed: 500, 63 | 64 | mobile: { 65 | width: 768, 66 | distance: 100, 67 | speed: 1000, 68 | easing: 'easeInOutElastic', 69 | animation: 'slide', 70 | animationSpeed: 200 71 | }, 72 | 73 | trigger: null, // Set a custom triggering element. Can be an HTML string or jQuery object 74 | target: null, // Set a custom target element for scrolling to. Can be element or number 75 | text: 'Scroll To Top', // Text for element, can contain HTML 76 | 77 | skin: null, 78 | throttle: 250, 79 | 80 | namespace: 'scrollToTop' 81 | }; 82 | 83 | function transition() { 84 | var e = void 0; 85 | var end = void 0; 86 | var prefix = ''; 87 | var supported = false; 88 | var el = document.createElement('fakeelement'); 89 | 90 | var transitions = { 91 | WebkitTransition: 'webkitTransitionEnd', 92 | MozTransition: 'transitionend', 93 | OTransition: 'oTransitionend', 94 | transition: 'transitionend' 95 | }; 96 | 97 | for (e in transitions) { 98 | if (el.style[e] !== undefined) { 99 | end = transitions[e]; 100 | supported = true; 101 | break; 102 | } 103 | } 104 | if (/(WebKit)/i.test(window.navigator.userAgent)) { 105 | prefix = '-webkit-'; 106 | } 107 | return { 108 | prefix: prefix, 109 | end: end, 110 | supported: supported 111 | }; 112 | } 113 | 114 | function throttle(func, wait) { 115 | var _this = this; 116 | 117 | var _now = 118 | Date.now || 119 | function() { 120 | return new Date().getTime(); 121 | }; 122 | 123 | var timeout = void 0; 124 | var context = void 0; 125 | var args = void 0; 126 | var result = void 0; 127 | var previous = 0; 128 | var later = function later() { 129 | previous = _now(); 130 | timeout = null; 131 | result = func.apply(context, args); 132 | if (!timeout) { 133 | context = args = null; 134 | } 135 | }; 136 | 137 | return function() { 138 | for ( 139 | var _len = arguments.length, params = Array(_len), _key = 0; 140 | _key < _len; 141 | _key++ 142 | ) { 143 | params[_key] = arguments[_key]; 144 | } 145 | 146 | /*eslint consistent-this: "off"*/ 147 | var now = _now(); 148 | var remaining = wait - (now - previous); 149 | context = _this; 150 | args = params; 151 | if (remaining <= 0 || remaining > wait) { 152 | if (timeout) { 153 | clearTimeout(timeout); 154 | timeout = null; 155 | } 156 | previous = now; 157 | result = func.apply(context, args); 158 | if (!timeout) { 159 | context = args = null; 160 | } 161 | } else if (!timeout) { 162 | timeout = setTimeout(later, remaining); 163 | } 164 | return result; 165 | }; 166 | } 167 | 168 | /** 169 | * Plugin constructor 170 | **/ 171 | 172 | var ScrollToTop = (function() { 173 | function ScrollToTop() { 174 | var options = 175 | arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 176 | 177 | _classCallCheck(this, ScrollToTop); 178 | 179 | this.$doc = (0, _jquery2.default)('body'); 180 | this.options = _jquery2.default.extend(true, {}, DEFAULTS, options); 181 | 182 | var namespace = this.options.namespace; 183 | 184 | if (this.options.skin === null) { 185 | this.options.skin = 'default'; 186 | } 187 | 188 | this.classes = { 189 | skin: namespace + '_' + this.options.skin, 190 | trigger: namespace, 191 | animating: namespace + '_animating', 192 | show: namespace + '_show' 193 | }; 194 | 195 | this.disabled = false; 196 | this.useMobile = false; 197 | this.isShow = false; 198 | 199 | this._init(); 200 | } 201 | 202 | _createClass( 203 | ScrollToTop, 204 | [ 205 | { 206 | key: '_init', 207 | value: function _init() { 208 | this.transition = transition(); 209 | this._build(); 210 | 211 | if (this.options.target) { 212 | if (typeof this.options.target === 'number') { 213 | this.target = this.options.target; 214 | } else if (typeof this.options.target === 'string') { 215 | this.target = Math.floor( 216 | (0, _jquery2.default)(this.options.target).offset().top 217 | ); 218 | } 219 | } else { 220 | this.target = 0; 221 | } 222 | 223 | this._bindEvents(); 224 | 225 | this._toggle(); 226 | } 227 | }, 228 | { 229 | key: '_bindEvents', 230 | value: function _bindEvents() { 231 | var _this2 = this; 232 | 233 | this.$trigger.on('click.scrollToTop', function() { 234 | _this2.$doc.trigger('ScrollToTop::jump'); 235 | return false; 236 | }); 237 | 238 | // bind events 239 | this.$doc 240 | .on('ScrollToTop::jump', function() { 241 | if (_this2.disabled) { 242 | return; 243 | } 244 | 245 | _this2.checkMobile(); 246 | 247 | var speed = void 0; 248 | var easing = void 0; 249 | 250 | if (_this2.useMobile) { 251 | speed = _this2.options.mobile.speed; 252 | easing = _this2.options.mobile.easing; 253 | } else { 254 | speed = _this2.options.speed; 255 | easing = _this2.options.easing; 256 | } 257 | 258 | _this2.$doc.addClass(_this2.classes.animating); 259 | 260 | if (_this2.transition.supported) { 261 | var pos = (0, _jquery2.default)(window).scrollTop(); 262 | 263 | _this2.$doc.css({ 264 | 'margin-top': -pos + _this2.target + 'px' 265 | }); 266 | (0, _jquery2.default)(window).scrollTop(_this2.target); 267 | 268 | _this2._insertRule( 269 | '.duration_' + 270 | speed + 271 | '{' + 272 | _this2.transition.prefix + 273 | 'transition-duration: ' + 274 | speed + 275 | 'ms;}' 276 | ); 277 | 278 | _this2.$doc 279 | .addClass('easing_' + easing + ' duration_' + speed) 280 | .css({ 281 | 'margin-top': '' 282 | }) 283 | .one(_this2.transition.end, function() { 284 | _this2.$doc.removeClass( 285 | _this2.classes.animating + 286 | ' easing_' + 287 | easing + 288 | ' duration_' + 289 | speed 290 | ); 291 | }); 292 | } else { 293 | (0, _jquery2.default)('html, body') 294 | .stop(true, false) 295 | .animate( 296 | { 297 | scrollTop: _this2.target 298 | }, 299 | speed, 300 | function() { 301 | _this2.$doc.removeClass(_this2.classes.animating); 302 | } 303 | ); 304 | return; 305 | } 306 | }) 307 | .on('ScrollToTop::show', function() { 308 | if (_this2.isShow) { 309 | return; 310 | } 311 | _this2.isShow = true; 312 | 313 | _this2.$trigger.addClass(_this2.classes.show); 314 | }) 315 | .on('ScrollToTop::hide', function() { 316 | if (!_this2.isShow) { 317 | return; 318 | } 319 | _this2.isShow = false; 320 | _this2.$trigger.removeClass(_this2.classes.show); 321 | }) 322 | .on('ScrollToTop::disable', function() { 323 | _this2.disabled = true; 324 | _this2.$doc.trigger('ScrollToTop::hide'); 325 | }) 326 | .on('ScrollToTop::enable', function() { 327 | _this2.disabled = false; 328 | _this2._toggle(); 329 | }); 330 | 331 | (0, _jquery2.default)(window).on( 332 | 'scroll.ScrollToTop', 333 | throttle(function() { 334 | if (_this2.disabled) { 335 | return; 336 | } 337 | 338 | _this2._toggle(); 339 | }, this.options.throttle) 340 | ); 341 | 342 | if (this.options.mobile) { 343 | (0, _jquery2.default)(window).on( 344 | 'resize.ScrollToTop orientationchange.ScrollToTop', 345 | throttle(function() { 346 | if (_this2.disabled) { 347 | return; 348 | } 349 | 350 | _this2.checkMobile(); 351 | }, this.options.throttle) 352 | ); 353 | } 354 | } 355 | }, 356 | { 357 | key: '_build', 358 | value: function _build() { 359 | if (this.options.trigger) { 360 | this.$trigger = (0, _jquery2.default)(this.options.trigger); 361 | } else { 362 | this.$trigger = (0, _jquery2.default)( 363 | '' + 368 | this.options.text + 369 | '' 370 | ).appendTo((0, _jquery2.default)('body')); 371 | } 372 | 373 | this._insertRule( 374 | '.' + 375 | this.classes.show + 376 | '{' + 377 | this.transition.prefix + 378 | 'animation-duration: ' + 379 | this.options.animationSpeed + 380 | 'ms;' + 381 | this.transition.prefix + 382 | 'animation-name: ' + 383 | this.options.namespace + 384 | '_' + 385 | this.options.animation + 386 | ';}' 387 | ); 388 | 389 | if (this.options.mobile) { 390 | this._insertRule( 391 | '@media (max-width: ' + 392 | this.options.mobile.width + 393 | 'px){.' + 394 | this.classes.show + 395 | '{' + 396 | this.transition.prefix + 397 | 'animation-duration: ' + 398 | this.options.mobile.animationSpeed + 399 | 'ms !important;' + 400 | this.transition.prefix + 401 | 'animation-name: ' + 402 | this.options.namespace + 403 | '_' + 404 | this.options.mobile.animation + 405 | ' !important;}}' 406 | ); 407 | } 408 | } 409 | }, 410 | { 411 | key: 'checkMobile', 412 | value: function checkMobile() { 413 | var width = (0, _jquery2.default)(window).width(); 414 | 415 | if (width < this.options.mobile.width) { 416 | this.useMobile = true; 417 | } else { 418 | this.useMobile = false; 419 | } 420 | } 421 | }, 422 | { 423 | key: 'can', 424 | value: function can() { 425 | var distance = void 0; 426 | if (this.useMobile) { 427 | distance = this.options.mobile.distance; 428 | } else { 429 | distance = this.options.distance; 430 | } 431 | if ((0, _jquery2.default)(window).scrollTop() > distance) { 432 | return true; 433 | } 434 | return false; 435 | } 436 | }, 437 | { 438 | key: '_toggle', 439 | value: function _toggle() { 440 | if (this.can()) { 441 | this.$doc.trigger('ScrollToTop::show'); 442 | } else { 443 | this.$doc.trigger('ScrollToTop::hide'); 444 | } 445 | } 446 | }, 447 | { 448 | key: '_insertRule', 449 | value: function _insertRule(rule) { 450 | if (this.rules && this.rules[rule]) { 451 | return; 452 | } else if (this.rules === undefined) { 453 | this.rules = {}; 454 | } else { 455 | this.rules[rule] = true; 456 | } 457 | 458 | if (document.styleSheets && document.styleSheets.length) { 459 | document.styleSheets[0].insertRule(rule, 0); 460 | } else { 461 | var style = document.createElement('style'); 462 | style.innerHTML = rule; 463 | document.head.appendChild(style); 464 | } 465 | } 466 | }, 467 | { 468 | key: 'jump', 469 | value: function jump() { 470 | this.$doc.trigger('ScrollToTop::jump'); 471 | } 472 | }, 473 | { 474 | key: 'disable', 475 | value: function disable() { 476 | this.$doc.trigger('ScrollToTop::disable'); 477 | } 478 | }, 479 | { 480 | key: 'enable', 481 | value: function enable() { 482 | this.$doc.trigger('ScrollToTop::enable'); 483 | } 484 | }, 485 | { 486 | key: 'destroy', 487 | value: function destroy() { 488 | this.$trigger.remove(); 489 | this.$doc.data('ScrollToTop', null); 490 | this.$doc 491 | .off('ScrollToTop::enable') 492 | .off('ScrollToTop::disable') 493 | .off('ScrollToTop::jump') 494 | .off('ScrollToTop::show') 495 | .off('ScrollToTop::hide'); 496 | (0, _jquery2.default)(window).off('.ScrollToTop'); 497 | } 498 | } 499 | ], 500 | [ 501 | { 502 | key: 'setDefaults', 503 | value: function setDefaults(options) { 504 | _jquery2.default.extend( 505 | true, 506 | DEFAULTS, 507 | _jquery2.default.isPlainObject(options) && options 508 | ); 509 | } 510 | } 511 | ] 512 | ); 513 | 514 | return ScrollToTop; 515 | })(); 516 | 517 | var info = { 518 | version: '0.4.3' 519 | }; 520 | 521 | var NAMESPACE = 'scrollToTop'; 522 | var OtherScrollToTop = _jquery2.default.fn.scrollToTop; 523 | 524 | var jQueryScrollToTop = function jQueryScrollToTop(options) { 525 | for ( 526 | var _len2 = arguments.length, 527 | args = Array(_len2 > 1 ? _len2 - 1 : 0), 528 | _key2 = 1; 529 | _key2 < _len2; 530 | _key2++ 531 | ) { 532 | args[_key2 - 1] = arguments[_key2]; 533 | } 534 | 535 | if (typeof options === 'string') { 536 | var method = options; 537 | 538 | if (/^_/.test(method)) { 539 | return false; 540 | } else if (/^(get)/.test(method)) { 541 | var instance = this.first().data(NAMESPACE); 542 | if (instance && typeof instance[method] === 'function') { 543 | return instance[method].apply(instance, args); 544 | } 545 | } else { 546 | return this.each(function() { 547 | var instance = _jquery2.default.data(this, NAMESPACE); 548 | if (instance && typeof instance[method] === 'function') { 549 | instance[method].apply(instance, args); 550 | } 551 | }); 552 | } 553 | } 554 | 555 | return this.each(function() { 556 | if (!(0, _jquery2.default)(this).data(NAMESPACE)) { 557 | (0, _jquery2.default)(this).data(NAMESPACE, new ScrollToTop(options)); 558 | } 559 | }); 560 | }; 561 | 562 | _jquery2.default.fn.scrollToTop = jQueryScrollToTop; 563 | 564 | _jquery2.default.scrollToTop = _jquery2.default.extend( 565 | { 566 | setDefaults: ScrollToTop.setDefaults, 567 | noConflict: function noConflict() { 568 | _jquery2.default.fn.scrollToTop = OtherScrollToTop; 569 | return jQueryScrollToTop; 570 | } 571 | }, 572 | info 573 | ); 574 | }); 575 | -------------------------------------------------------------------------------- /dist/jquery-scrollToTop.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery scrollToTop v0.4.3 3 | * https://github.com/amazingSurge/jquery-scrollToTop 4 | * 5 | * Copyright (c) amazingSurge 6 | * Released under the LGPL-3.0 license 7 | */ 8 | !function(t,o){if("function"==typeof define&&define.amd)define(["jquery"],o);else if("undefined"!=typeof exports)o(require("jquery"));else{var i={exports:{}};o(t.jQuery),t.jqueryScrollToTopEs=i.exports}}(this,function(t){"use strict";function o(t,o){if(!(t instanceof o))throw new TypeError("Cannot call a class as a function")}function i(){var t=void 0,o=void 0,i="",e=!1,n=document.createElement("fakeelement"),s={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionend",transition:"transitionend"};for(t in s)if(void 0!==n.style[t]){o=s[t],e=!0;break}return/(WebKit)/i.test(window.navigator.userAgent)&&(i="-webkit-"),{prefix:i,end:o,supported:e}}function e(t,o){var i=this,e=Date.now||function(){return(new Date).getTime()},n=void 0,s=void 0,a=void 0,l=void 0,r=0,u=function(){r=e(),n=null,l=t.apply(s,a),n||(s=a=null)};return function(){for(var d=arguments.length,c=Array(d),f=0;fo?(n&&(clearTimeout(n),n=null),r=p,l=t.apply(s,a),n||(s=a=null)):n||(n=setTimeout(u,h)),l}}var n=function(t){return t&&t.__esModule?t:{default:t}}(t),s=function(){function t(t,o){for(var i=0;i0&&void 0!==arguments[0]?arguments[0]:{};o(this,t),this.$doc=(0,n.default)("body"),this.options=n.default.extend(!0,{},a,i);var e=this.options.namespace;null===this.options.skin&&(this.options.skin="default"),this.classes={skin:e+"_"+this.options.skin,trigger:e,animating:e+"_animating",show:e+"_show"},this.disabled=!1,this.useMobile=!1,this.isShow=!1,this._init()}return s(t,[{key:"_init",value:function(){this.transition=i(),this._build(),this.options.target?"number"==typeof this.options.target?this.target=this.options.target:"string"==typeof this.options.target&&(this.target=Math.floor((0,n.default)(this.options.target).offset().top)):this.target=0,this._bindEvents(),this._toggle()}},{key:"_bindEvents",value:function(){var t=this;this.$trigger.on("click.scrollToTop",function(){return t.$doc.trigger("ScrollToTop::jump"),!1}),this.$doc.on("ScrollToTop::jump",function(){if(!t.disabled){t.checkMobile();var o=void 0,i=void 0;if(t.useMobile?(o=t.options.mobile.speed,i=t.options.mobile.easing):(o=t.options.speed,i=t.options.easing),t.$doc.addClass(t.classes.animating),t.transition.supported){var e=(0,n.default)(window).scrollTop();t.$doc.css({"margin-top":-e+t.target+"px"}),(0,n.default)(window).scrollTop(t.target),t._insertRule(".duration_"+o+"{"+t.transition.prefix+"transition-duration: "+o+"ms;}"),t.$doc.addClass("easing_"+i+" duration_"+o).css({"margin-top":""}).one(t.transition.end,function(){t.$doc.removeClass(t.classes.animating+" easing_"+i+" duration_"+o)})}else(0,n.default)("html, body").stop(!0,!1).animate({scrollTop:t.target},o,function(){t.$doc.removeClass(t.classes.animating)})}}).on("ScrollToTop::show",function(){t.isShow||(t.isShow=!0,t.$trigger.addClass(t.classes.show))}).on("ScrollToTop::hide",function(){t.isShow&&(t.isShow=!1,t.$trigger.removeClass(t.classes.show))}).on("ScrollToTop::disable",function(){t.disabled=!0,t.$doc.trigger("ScrollToTop::hide")}).on("ScrollToTop::enable",function(){t.disabled=!1,t._toggle()}),(0,n.default)(window).on("scroll.ScrollToTop",e(function(){t.disabled||t._toggle()},this.options.throttle)),this.options.mobile&&(0,n.default)(window).on("resize.ScrollToTop orientationchange.ScrollToTop",e(function(){t.disabled||t.checkMobile()},this.options.throttle))}},{key:"_build",value:function(){this.options.trigger?this.$trigger=(0,n.default)(this.options.trigger):this.$trigger=(0,n.default)(''+this.options.text+"").appendTo((0,n.default)("body")),this._insertRule("."+this.classes.show+"{"+this.transition.prefix+"animation-duration: "+this.options.animationSpeed+"ms;"+this.transition.prefix+"animation-name: "+this.options.namespace+"_"+this.options.animation+";}"),this.options.mobile&&this._insertRule("@media (max-width: "+this.options.mobile.width+"px){."+this.classes.show+"{"+this.transition.prefix+"animation-duration: "+this.options.mobile.animationSpeed+"ms !important;"+this.transition.prefix+"animation-name: "+this.options.namespace+"_"+this.options.mobile.animation+" !important;}}")}},{key:"checkMobile",value:function(){(0,n.default)(window).width()t}},{key:"_toggle",value:function(){this.can()?this.$doc.trigger("ScrollToTop::show"):this.$doc.trigger("ScrollToTop::hide")}},{key:"_insertRule",value:function(t){if(!this.rules||!this.rules[t])if(void 0===this.rules?this.rules={}:this.rules[t]=!0,document.styleSheets&&document.styleSheets.length)document.styleSheets[0].insertRule(t,0);else{var o=document.createElement("style");o.innerHTML=t,document.head.appendChild(o)}}},{key:"jump",value:function(){this.$doc.trigger("ScrollToTop::jump")}},{key:"disable",value:function(){this.$doc.trigger("ScrollToTop::disable")}},{key:"enable",value:function(){this.$doc.trigger("ScrollToTop::enable")}},{key:"destroy",value:function(){this.$trigger.remove(),this.$doc.data("ScrollToTop",null),this.$doc.off("ScrollToTop::enable").off("ScrollToTop::disable").off("ScrollToTop::jump").off("ScrollToTop::show").off("ScrollToTop::hide"),(0,n.default)(window).off(".ScrollToTop")}}],[{key:"setDefaults",value:function(t){n.default.extend(!0,a,n.default.isPlainObject(t)&&t)}}]),t}(),r={version:"0.4.3"},u=n.default.fn.scrollToTop,d=function(t){for(var o=arguments.length,i=Array(o>1?o-1:0),e=1;e {\n /*eslint consistent-this: \"off\"*/\n let now = _now();\n let remaining = wait - (now - previous);\n context = this;\n args = params;\n if (remaining <= 0 || remaining > wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n result = func.apply(context, args);\n if (!timeout) {\n context = args = null;\n }\n } else if (!timeout) {\n timeout = setTimeout(later, remaining);\n }\n return result;\n };\n}\n\n/**\n * Plugin constructor\n **/\nclass ScrollToTop {\n constructor(options = {}) {\n this.$doc = $('body');\n this.options = $.extend(true, {}, DEFAULTS, options);\n\n const namespace = this.options.namespace;\n\n if (this.options.skin === null) {\n this.options.skin = 'default';\n }\n\n this.classes = {\n skin: `${namespace}_${this.options.skin}`,\n trigger: namespace,\n animating: `${namespace}_animating`,\n show: `${namespace}_show`\n };\n\n this.disabled = false;\n this.useMobile = false;\n this.isShow = false;\n\n this._init();\n }\n\n _init() {\n this.transition = transition();\n this._build();\n\n if (this.options.target) {\n if (typeof this.options.target === 'number') {\n this.target = this.options.target;\n } else if (typeof this.options.target === 'string') {\n this.target = Math.floor($(this.options.target).offset().top);\n }\n } else {\n this.target = 0;\n }\n\n this._bindEvents();\n\n this._toggle();\n }\n\n _bindEvents() {\n this.$trigger.on('click.scrollToTop', () => {\n this.$doc.trigger('ScrollToTop::jump');\n return false;\n });\n\n // bind events\n this.$doc.on('ScrollToTop::jump', () => {\n if (this.disabled) {\n return;\n }\n\n this.checkMobile();\n\n let speed;\n let easing;\n\n if (this.useMobile) {\n speed = this.options.mobile.speed;\n easing = this.options.mobile.easing;\n } else {\n speed = this.options.speed;\n easing = this.options.easing;\n }\n\n this.$doc.addClass(this.classes.animating);\n\n if (this.transition.supported) {\n const pos = $(window).scrollTop();\n\n this.$doc.css({\n 'margin-top': `${-pos + this.target}px`\n });\n $(window).scrollTop(this.target);\n\n this._insertRule(`.duration_${speed}{${this.transition.prefix}transition-duration: ${speed}ms;}`);\n\n this.$doc.addClass(`easing_${easing} duration_${speed}`).css({\n 'margin-top': ''\n }).one(this.transition.end, () => {\n this.$doc.removeClass(`${this.classes.animating} easing_${easing} duration_${speed}`);\n });\n } else {\n $('html, body').stop(true, false).animate({\n scrollTop: this.target\n }, speed, () => {\n this.$doc.removeClass(this.classes.animating);\n });\n return;\n }\n })\n .on('ScrollToTop::show', () => {\n if (this.isShow) {\n return;\n }\n this.isShow = true;\n\n this.$trigger.addClass(this.classes.show);\n })\n .on('ScrollToTop::hide', () => {\n if (!this.isShow) {\n return;\n }\n this.isShow = false;\n this.$trigger.removeClass(this.classes.show);\n })\n .on('ScrollToTop::disable', () => {\n this.disabled = true;\n this.$doc.trigger('ScrollToTop::hide');\n })\n .on('ScrollToTop::enable', () => {\n this.disabled = false;\n this._toggle();\n });\n\n $(window).on('scroll.ScrollToTop', throttle(() => {\n if (this.disabled) {\n return;\n }\n\n this._toggle();\n }, this.options.throttle));\n\n if (this.options.mobile) {\n $(window).on('resize.ScrollToTop orientationchange.ScrollToTop', throttle(() => {\n if (this.disabled) {\n return;\n }\n\n this.checkMobile();\n }, this.options.throttle));\n }\n }\n\n _build() {\n if (this.options.trigger) {\n this.$trigger = $(this.options.trigger);\n } else {\n this.$trigger = $(`${this.options.text}`).appendTo($('body'));\n }\n\n this._insertRule(`.${this.classes.show}{${this.transition.prefix}animation-duration: ${this.options.animationSpeed}ms;${this.transition.prefix}animation-name: ${this.options.namespace}_${this.options.animation};}`);\n\n if (this.options.mobile) {\n this._insertRule(`@media (max-width: ${this.options.mobile.width}px){.${this.classes.show}{${this.transition.prefix}animation-duration: ${this.options.mobile.animationSpeed}ms !important;${this.transition.prefix}animation-name: ${this.options.namespace}_${this.options.mobile.animation} !important;}}`);\n }\n }\n\n checkMobile() {\n const width = $(window).width();\n\n if (width < this.options.mobile.width) {\n this.useMobile = true;\n } else {\n this.useMobile = false;\n }\n }\n\n can() {\n let distance;\n if (this.useMobile) {\n distance = this.options.mobile.distance;\n } else {\n distance = this.options.distance;\n }\n if ($(window).scrollTop() > distance) {\n return true;\n }\n return false;\n }\n\n _toggle() {\n if (this.can()) {\n this.$doc.trigger('ScrollToTop::show');\n } else {\n this.$doc.trigger('ScrollToTop::hide');\n }\n }\n\n _insertRule(rule) {\n if (this.rules && this.rules[rule]) {\n return;\n } else if (this.rules === undefined) {\n this.rules = {};\n } else {\n this.rules[rule] = true;\n }\n\n if (document.styleSheets && document.styleSheets.length) {\n document.styleSheets[0].insertRule(rule, 0);\n } else {\n const style = document.createElement('style');\n style.innerHTML = rule;\n document.head.appendChild(style);\n }\n }\n\n jump() {\n this.$doc.trigger('ScrollToTop::jump');\n }\n\n disable() {\n this.$doc.trigger('ScrollToTop::disable');\n }\n\n enable() {\n this.$doc.trigger('ScrollToTop::enable');\n }\n\n destroy() {\n this.$trigger.remove();\n this.$doc.data('ScrollToTop', null);\n this.$doc.off('ScrollToTop::enable')\n .off('ScrollToTop::disable')\n .off('ScrollToTop::jump')\n .off('ScrollToTop::show')\n .off('ScrollToTop::hide');\n $(window).off('.ScrollToTop');\n }\n\n static setDefaults(options) {\n $.extend(true, DEFAULTS, $.isPlainObject(options) && options);\n }\n}\n\nvar info = {\n version:'0.4.3'\n};\n\nconst NAMESPACE = 'scrollToTop';\nconst OtherScrollToTop = $.fn.scrollToTop;\n\nconst jQueryScrollToTop = function(options, ...args) {\n if (typeof options === 'string') {\n const method = options;\n\n if (/^_/.test(method)) {\n return false;\n } else if ((/^(get)/.test(method))) {\n const instance = this.first().data(NAMESPACE);\n if (instance && typeof instance[method] === 'function') {\n return instance[method](...args);\n }\n } else {\n return this.each(function() {\n const instance = $.data(this, NAMESPACE);\n if (instance && typeof instance[method] === 'function') {\n instance[method](...args);\n }\n });\n }\n }\n\n return this.each(function() {\n if (!$(this).data(NAMESPACE)) {\n $(this).data(NAMESPACE, new ScrollToTop(options));\n }\n });\n};\n\n$.fn.scrollToTop = jQueryScrollToTop;\n\n$.scrollToTop = $.extend({\n setDefaults: ScrollToTop.setDefaults,\n noConflict: function() {\n $.fn.scrollToTop = OtherScrollToTop;\n return jQueryScrollToTop;\n }\n}, info);\n"]} -------------------------------------------------------------------------------- /examples/css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | * HTML5 Boilerplate 3 | * 4 | * What follows is the result of much research on cross-browser styling. 5 | * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, 6 | * Kroc Camen, and the H5BP dev community and team. 7 | */ 8 | 9 | /* ========================================================================== 10 | Base styles: opinionated defaults 11 | ========================================================================== */ 12 | 13 | html, 14 | button, 15 | input, 16 | select, 17 | textarea { 18 | color: #222; 19 | } 20 | 21 | body { 22 | font-size: 1em; 23 | line-height: 1.4; 24 | } 25 | 26 | /* 27 | * Remove text-shadow in selection highlight: h5bp.com/i 28 | * These selection rule sets have to be separate. 29 | * Customize the background color to match your design. 30 | */ 31 | 32 | ::-moz-selection { 33 | background: #b3d4fc; 34 | text-shadow: none; 35 | } 36 | 37 | ::selection { 38 | background: #b3d4fc; 39 | text-shadow: none; 40 | } 41 | 42 | /* 43 | * A better looking default horizontal rule 44 | */ 45 | 46 | hr { 47 | display: block; 48 | height: 1px; 49 | border: 0; 50 | border-top: 1px solid #ccc; 51 | margin: 1em 0; 52 | padding: 0; 53 | } 54 | 55 | /* 56 | * Remove the gap between images, videos, audio and canvas and the bottom of 57 | * their containers: h5bp.com/i/440 58 | */ 59 | 60 | audio, 61 | canvas, 62 | img, 63 | video { 64 | vertical-align: middle; 65 | } 66 | 67 | /* 68 | * Remove default fieldset styles. 69 | */ 70 | 71 | fieldset { 72 | border: 0; 73 | margin: 0; 74 | padding: 0; 75 | } 76 | 77 | /* 78 | * Allow only vertical resizing of textareas. 79 | */ 80 | 81 | textarea { 82 | resize: vertical; 83 | } 84 | 85 | /* ========================================================================== 86 | Browse Happy prompt 87 | ========================================================================== */ 88 | 89 | .browsehappy { 90 | margin: 0.2em 0; 91 | background: #ccc; 92 | color: #000; 93 | padding: 0.2em 0; 94 | } 95 | 96 | /* ========================================================================== 97 | Author's custom styles 98 | ========================================================================== */ 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | /* ========================================================================== 117 | Helper classes 118 | ========================================================================== */ 119 | 120 | /* 121 | * Image replacement 122 | */ 123 | 124 | .ir { 125 | background-color: transparent; 126 | border: 0; 127 | overflow: hidden; 128 | /* IE 6/7 fallback */ 129 | *text-indent: -9999px; 130 | } 131 | 132 | .ir:before { 133 | content: ""; 134 | display: block; 135 | width: 0; 136 | height: 150%; 137 | } 138 | 139 | /* 140 | * Hide from both screenreaders and browsers: h5bp.com/u 141 | */ 142 | 143 | .hidden { 144 | display: none !important; 145 | visibility: hidden; 146 | } 147 | 148 | /* 149 | * Hide only visually, but have it available for screenreaders: h5bp.com/v 150 | */ 151 | 152 | .visuallyhidden { 153 | border: 0; 154 | clip: rect(0 0 0 0); 155 | height: 1px; 156 | margin: -1px; 157 | overflow: hidden; 158 | padding: 0; 159 | position: absolute; 160 | width: 1px; 161 | } 162 | 163 | /* 164 | * Extends the .visuallyhidden class to allow the element to be focusable 165 | * when navigated to via the keyboard: h5bp.com/p 166 | */ 167 | 168 | .visuallyhidden.focusable:active, 169 | .visuallyhidden.focusable:focus { 170 | clip: auto; 171 | height: auto; 172 | margin: 0; 173 | overflow: visible; 174 | position: static; 175 | width: auto; 176 | } 177 | 178 | /* 179 | * Hide visually and from screenreaders, but maintain layout 180 | */ 181 | 182 | .invisible { 183 | visibility: hidden; 184 | } 185 | 186 | /* 187 | * Clearfix: contain floats 188 | * 189 | * For modern browsers 190 | * 1. The space content is one way to avoid an Opera bug when the 191 | * `contenteditable` attribute is included anywhere else in the document. 192 | * Otherwise it causes space to appear at the top and bottom of elements 193 | * that receive the `clearfix` class. 194 | * 2. The use of `table` rather than `block` is only necessary if using 195 | * `:before` to contain the top-margins of child elements. 196 | */ 197 | 198 | .clearfix:before, 199 | .clearfix:after { 200 | content: " "; /* 1 */ 201 | display: table; /* 2 */ 202 | } 203 | 204 | .clearfix:after { 205 | clear: both; 206 | } 207 | 208 | /* 209 | * For IE 6/7 only 210 | * Include this rule to trigger hasLayout and contain floats. 211 | */ 212 | 213 | .clearfix { 214 | *zoom: 1; 215 | } 216 | 217 | /* ========================================================================== 218 | EXAMPLE Media Queries for Responsive Design. 219 | These examples override the primary ('mobile first') styles. 220 | Modify as content requires. 221 | ========================================================================== */ 222 | 223 | @media only screen and (min-width: 35em) { 224 | /* Style adjustments for viewports that meet the condition */ 225 | } 226 | 227 | @media print, 228 | (-o-min-device-pixel-ratio: 5/4), 229 | (-webkit-min-device-pixel-ratio: 1.25), 230 | (min-resolution: 120dpi) { 231 | /* Style adjustments for high resolution devices */ 232 | } 233 | 234 | /* ========================================================================== 235 | Print styles. 236 | Inlined to avoid required HTTP connection: h5bp.com/r 237 | ========================================================================== */ 238 | 239 | @media print { 240 | * { 241 | background: transparent !important; 242 | color: #000 !important; /* Black prints faster: h5bp.com/s */ 243 | box-shadow: none !important; 244 | text-shadow: none !important; 245 | } 246 | 247 | a, 248 | a:visited { 249 | text-decoration: underline; 250 | } 251 | 252 | a[href]:after { 253 | content: " (" attr(href) ")"; 254 | } 255 | 256 | abbr[title]:after { 257 | content: " (" attr(title) ")"; 258 | } 259 | 260 | /* 261 | * Don't show links for images, or javascript/internal links 262 | */ 263 | 264 | .ir a:after, 265 | a[href^="javascript:"]:after, 266 | a[href^="#"]:after { 267 | content: ""; 268 | } 269 | 270 | pre, 271 | blockquote { 272 | border: 1px solid #999; 273 | page-break-inside: avoid; 274 | } 275 | 276 | thead { 277 | display: table-header-group; /* h5bp.com/t */ 278 | } 279 | 280 | tr, 281 | img { 282 | page-break-inside: avoid; 283 | } 284 | 285 | img { 286 | max-width: 100% !important; 287 | } 288 | 289 | @page { 290 | margin: 0.5cm; 291 | } 292 | 293 | p, 294 | h2, 295 | h3 { 296 | orphans: 3; 297 | widows: 3; 298 | } 299 | 300 | h2, 301 | h3 { 302 | page-break-after: avoid; 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /examples/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /** 4 | * 1. Change the default font family in all browsers (opinionated). 5 | * 2. Correct the line height in all browsers. 6 | * 3. Prevent adjustments of font size after orientation changes in IE and iOS. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | line-height: 1.15; /* 2 */ 12 | -ms-text-size-adjust: 100%; /* 3 */ 13 | -webkit-text-size-adjust: 100%; /* 3 */ 14 | } 15 | 16 | /** 17 | * Remove the margin in all browsers (opinionated). 18 | */ 19 | 20 | body { 21 | margin: 0; 22 | } 23 | 24 | /* HTML5 display definitions 25 | ========================================================================== */ 26 | 27 | /** 28 | * Add the correct display in IE 9-. 29 | * 1. Add the correct display in Edge, IE, and Firefox. 30 | * 2. Add the correct display in IE. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, /* 1 */ 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | main, /* 2 */ 41 | menu, 42 | nav, 43 | section, 44 | summary { /* 1 */ 45 | display: block; 46 | } 47 | 48 | /** 49 | * Add the correct display in IE 9-. 50 | */ 51 | 52 | audio, 53 | canvas, 54 | progress, 55 | video { 56 | display: inline-block; 57 | } 58 | 59 | /** 60 | * Add the correct display in iOS 4-7. 61 | */ 62 | 63 | audio:not([controls]) { 64 | display: none; 65 | height: 0; 66 | } 67 | 68 | /** 69 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 70 | */ 71 | 72 | progress { 73 | vertical-align: baseline; 74 | } 75 | 76 | /** 77 | * Add the correct display in IE 10-. 78 | * 1. Add the correct display in IE. 79 | */ 80 | 81 | template, /* 1 */ 82 | [hidden] { 83 | display: none; 84 | } 85 | 86 | /* Links 87 | ========================================================================== */ 88 | 89 | /** 90 | * 1. Remove the gray background on active links in IE 10. 91 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 92 | */ 93 | 94 | a { 95 | background-color: transparent; /* 1 */ 96 | -webkit-text-decoration-skip: objects; /* 2 */ 97 | } 98 | 99 | /** 100 | * Remove the outline on focused links when they are also active or hovered 101 | * in all browsers (opinionated). 102 | */ 103 | 104 | a:active, 105 | a:hover { 106 | outline-width: 0; 107 | } 108 | 109 | /* Text-level semantics 110 | ========================================================================== */ 111 | 112 | /** 113 | * 1. Remove the bottom border in Firefox 39-. 114 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 115 | */ 116 | 117 | abbr[title] { 118 | border-bottom: none; /* 1 */ 119 | text-decoration: underline; /* 2 */ 120 | text-decoration: underline dotted; /* 2 */ 121 | } 122 | 123 | /** 124 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 125 | */ 126 | 127 | b, 128 | strong { 129 | font-weight: inherit; 130 | } 131 | 132 | /** 133 | * Add the correct font weight in Chrome, Edge, and Safari. 134 | */ 135 | 136 | b, 137 | strong { 138 | font-weight: bolder; 139 | } 140 | 141 | /** 142 | * Add the correct font style in Android 4.3-. 143 | */ 144 | 145 | dfn { 146 | font-style: italic; 147 | } 148 | 149 | /** 150 | * Correct the font size and margin on `h1` elements within `section` and 151 | * `article` contexts in Chrome, Firefox, and Safari. 152 | */ 153 | 154 | h1 { 155 | font-size: 2em; 156 | margin: 0.67em 0; 157 | } 158 | 159 | /** 160 | * Add the correct background and color in IE 9-. 161 | */ 162 | 163 | mark { 164 | background-color: #ff0; 165 | color: #000; 166 | } 167 | 168 | /** 169 | * Add the correct font size in all browsers. 170 | */ 171 | 172 | small { 173 | font-size: 80%; 174 | } 175 | 176 | /** 177 | * Prevent `sub` and `sup` elements from affecting the line height in 178 | * all browsers. 179 | */ 180 | 181 | sub, 182 | sup { 183 | font-size: 75%; 184 | line-height: 0; 185 | position: relative; 186 | vertical-align: baseline; 187 | } 188 | 189 | sub { 190 | bottom: -0.25em; 191 | } 192 | 193 | sup { 194 | top: -0.5em; 195 | } 196 | 197 | /* Embedded content 198 | ========================================================================== */ 199 | 200 | /** 201 | * Remove the border on images inside links in IE 10-. 202 | */ 203 | 204 | img { 205 | border-style: none; 206 | } 207 | 208 | /** 209 | * Hide the overflow in IE. 210 | */ 211 | 212 | svg:not(:root) { 213 | overflow: hidden; 214 | } 215 | 216 | /* Grouping content 217 | ========================================================================== */ 218 | 219 | /** 220 | * 1. Correct the inheritance and scaling of font size in all browsers. 221 | * 2. Correct the odd `em` font sizing in all browsers. 222 | */ 223 | 224 | code, 225 | kbd, 226 | pre, 227 | samp { 228 | font-family: monospace, monospace; /* 1 */ 229 | font-size: 1em; /* 2 */ 230 | } 231 | 232 | /** 233 | * Add the correct margin in IE 8. 234 | */ 235 | 236 | figure { 237 | margin: 1em 40px; 238 | } 239 | 240 | /** 241 | * 1. Add the correct box sizing in Firefox. 242 | * 2. Show the overflow in Edge and IE. 243 | */ 244 | 245 | hr { 246 | box-sizing: content-box; /* 1 */ 247 | height: 0; /* 1 */ 248 | overflow: visible; /* 2 */ 249 | } 250 | 251 | /* Forms 252 | ========================================================================== */ 253 | 254 | /** 255 | * 1. Change font properties to `inherit` in all browsers (opinionated). 256 | * 2. Remove the margin in Firefox and Safari. 257 | */ 258 | 259 | button, 260 | input, 261 | optgroup, 262 | select, 263 | textarea { 264 | font: inherit; /* 1 */ 265 | margin: 0; /* 2 */ 266 | } 267 | 268 | /** 269 | * Restore the font weight unset by the previous rule. 270 | */ 271 | 272 | optgroup { 273 | font-weight: bold; 274 | } 275 | 276 | /** 277 | * Show the overflow in IE. 278 | * 1. Show the overflow in Edge. 279 | */ 280 | 281 | button, 282 | input { /* 1 */ 283 | overflow: visible; 284 | } 285 | 286 | /** 287 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 288 | * 1. Remove the inheritance of text transform in Firefox. 289 | */ 290 | 291 | button, 292 | select { /* 1 */ 293 | text-transform: none; 294 | } 295 | 296 | /** 297 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 298 | * controls in Android 4. 299 | * 2. Correct the inability to style clickable types in iOS and Safari. 300 | */ 301 | 302 | button, 303 | html [type="button"], /* 1 */ 304 | [type="reset"], 305 | [type="submit"] { 306 | -webkit-appearance: button; /* 2 */ 307 | } 308 | 309 | /** 310 | * Remove the inner border and padding in Firefox. 311 | */ 312 | 313 | button::-moz-focus-inner, 314 | [type="button"]::-moz-focus-inner, 315 | [type="reset"]::-moz-focus-inner, 316 | [type="submit"]::-moz-focus-inner { 317 | border-style: none; 318 | padding: 0; 319 | } 320 | 321 | /** 322 | * Restore the focus styles unset by the previous rule. 323 | */ 324 | 325 | button:-moz-focusring, 326 | [type="button"]:-moz-focusring, 327 | [type="reset"]:-moz-focusring, 328 | [type="submit"]:-moz-focusring { 329 | outline: 1px dotted ButtonText; 330 | } 331 | 332 | /** 333 | * Change the border, margin, and padding in all browsers (opinionated). 334 | */ 335 | 336 | fieldset { 337 | border: 1px solid #c0c0c0; 338 | margin: 0 2px; 339 | padding: 0.35em 0.625em 0.75em; 340 | } 341 | 342 | /** 343 | * 1. Correct the text wrapping in Edge and IE. 344 | * 2. Correct the color inheritance from `fieldset` elements in IE. 345 | * 3. Remove the padding so developers are not caught out when they zero out 346 | * `fieldset` elements in all browsers. 347 | */ 348 | 349 | legend { 350 | box-sizing: border-box; /* 1 */ 351 | color: inherit; /* 2 */ 352 | display: table; /* 1 */ 353 | max-width: 100%; /* 1 */ 354 | padding: 0; /* 3 */ 355 | white-space: normal; /* 1 */ 356 | } 357 | 358 | /** 359 | * Remove the default vertical scrollbar in IE. 360 | */ 361 | 362 | textarea { 363 | overflow: auto; 364 | } 365 | 366 | /** 367 | * 1. Add the correct box sizing in IE 10-. 368 | * 2. Remove the padding in IE 10-. 369 | */ 370 | 371 | [type="checkbox"], 372 | [type="radio"] { 373 | box-sizing: border-box; /* 1 */ 374 | padding: 0; /* 2 */ 375 | } 376 | 377 | /** 378 | * Correct the cursor style of increment and decrement buttons in Chrome. 379 | */ 380 | 381 | [type="number"]::-webkit-inner-spin-button, 382 | [type="number"]::-webkit-outer-spin-button { 383 | height: auto; 384 | } 385 | 386 | /** 387 | * 1. Correct the odd appearance in Chrome and Safari. 388 | * 2. Correct the outline style in Safari. 389 | */ 390 | 391 | [type="search"] { 392 | -webkit-appearance: textfield; /* 1 */ 393 | outline-offset: -2px; /* 2 */ 394 | } 395 | 396 | /** 397 | * Remove the inner padding and cancel buttons in Chrome and Safari on OS X. 398 | */ 399 | 400 | [type="search"]::-webkit-search-cancel-button, 401 | [type="search"]::-webkit-search-decoration { 402 | -webkit-appearance: none; 403 | } 404 | 405 | /** 406 | * Correct the text style of placeholders in Chrome, Edge, and Safari. 407 | */ 408 | 409 | ::-webkit-input-placeholder { 410 | color: inherit; 411 | opacity: 0.54; 412 | } 413 | 414 | /** 415 | * 1. Correct the inability to style clickable types in iOS and Safari. 416 | * 2. Change font properties to `inherit` in Safari. 417 | */ 418 | 419 | ::-webkit-file-upload-button { 420 | -webkit-appearance: button; /* 1 */ 421 | font: inherit; /* 2 */ 422 | } 423 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | 24 |
25 |
26 |

Css3/html5

27 |

Built-on CSS3 and HTML5 semantics to allow you to start captializing on a next generation standard.

28 |
29 |
30 |

Quick Start

31 |

First, clone the AdaptGrid from Github. Then add the grid and class in your web. Lastly, compile the Less and view the awesome changes in your browser

32 |
33 |
34 |

Semantic

35 |

Everything is now semantic. Now you can have the cleanest markup without sacrificing the utility and speed of AdaptGrid.

36 |
37 |
38 |

Mobile Fisrt

39 |

Now you can build for small devices first. Then, as devices get larger and larger, layer in more complexity.

40 |
41 |
42 |

Responsive

43 |

Make Responsive Theme part of your website design, or upgrade your current one to a mobile friendly Theme that automatically adapts to any screen resolution or device.

44 |
45 |
46 |

Less

47 |

You don't have to know a ton about Less to take this class. The first hour covers an introduction, with the second hour focused on implementing it. You'll be writing Less in no time.

48 |
49 |
50 |

Css3/html5

51 |

Built-on CSS3 and HTML5 semantics to allow you to start captializing on a next generation standard.

52 |
53 |
54 |

Quick Start

55 |

First, clone the AdaptGrid from Github. Then add the grid and class in your web. Lastly, compile the Less and view the awesome changes in your browser

56 |
57 |
58 |

Semantic

59 |

Everything is now semantic. Now you can have the cleanest markup without sacrificing the utility and speed of AdaptGrid.

60 |
61 |
62 |

Mobile Fisrt

63 |

Now you can build for small devices first. Then, as devices get larger and larger, layer in more complexity.

64 |
65 |
66 |

Responsive

67 |

Make Responsive Theme part of your website design, or upgrade your current one to a mobile friendly Theme that automatically adapts to any screen resolution or device.

68 |
69 |
70 |

Less

71 |

You don't have to know a ton about Less to take this class. The first hour covers an introduction, with the second hour focused on implementing it. You'll be writing Less in no time.

72 |
73 |
74 |

Css3/html5

75 |

Built-on CSS3 and HTML5 semantics to allow you to start captializing on a next generation standard.

76 |
77 |
78 |

Quick Start

79 |

First, clone the AdaptGrid from Github. Then add the grid and class in your web. Lastly, compile the Less and view the awesome changes in your browser

80 |
81 |
82 |

Semantic

83 |

Everything is now semantic. Now you can have the cleanest markup without sacrificing the utility and speed of AdaptGrid.

84 |
85 |
86 |

Mobile Fisrt

87 |

Now you can build for small devices first. Then, as devices get larger and larger, layer in more complexity.

88 |
89 |
90 |

Responsive

91 |

Make Responsive Theme part of your website design, or upgrade your current one to a mobile friendly Theme that automatically adapts to any screen resolution or device.

92 |
93 |
94 |

Less

95 |

You don't have to know a ton about Less to take this class. The first hour covers an introduction, with the second hour focused on implementing it. You'll be writing Less in no time.

96 |
97 |
98 |

Css3/html5

99 |

Built-on CSS3 and HTML5 semantics to allow you to start captializing on a next generation standard.

100 |
101 |
102 |

Quick Start

103 |

First, clone the AdaptGrid from Github. Then add the grid and class in your web. Lastly, compile the Less and view the awesome changes in your browser

104 |
105 |
106 |

Semantic

107 |

Everything is now semantic. Now you can have the cleanest markup without sacrificing the utility and speed of AdaptGrid.

108 |
109 |
110 |

Mobile Fisrt

111 |

Now you can build for small devices first. Then, as devices get larger and larger, layer in more complexity.

112 |
113 |
114 |

Responsive

115 |

Make Responsive Theme part of your website design, or upgrade your current one to a mobile friendly Theme that automatically adapts to any screen resolution or device.

116 |
117 |
118 |

Less

119 |

You don't have to know a ton about Less to take this class. The first hour covers an introduction, with the second hour focused on implementing it. You'll be writing Less in no time.

120 |
121 |
122 |

Css3/html5

123 |

Built-on CSS3 and HTML5 semantics to allow you to start captializing on a next generation standard.

124 |
125 |
126 |

Quick Start

127 |

First, clone the AdaptGrid from Github. Then add the grid and class in your web. Lastly, compile the Less and view the awesome changes in your browser

128 |
129 |
130 |

Semantic

131 |

Everything is now semantic. Now you can have the cleanest markup without sacrificing the utility and speed of AdaptGrid.

132 |
133 |
134 |

Mobile Fisrt

135 |

Now you can build for small devices first. Then, as devices get larger and larger, layer in more complexity.

136 |
137 |
138 |

Responsive

139 |

Make Responsive Theme part of your website design, or upgrade your current one to a mobile friendly Theme that automatically adapts to any screen resolution or device.

140 |
141 |
142 |

Less

143 |

You don't have to know a ton about Less to take this class. The first hour covers an introduction, with the second hour focused on implementing it. You'll be writing Less in no time.

144 |
145 |
146 |

Css3/html5

147 |

Built-on CSS3 and HTML5 semantics to allow you to start captializing on a next generation standard.

148 |
149 |
150 |

Quick Start

151 |

First, clone the AdaptGrid from Github. Then add the grid and class in your web. Lastly, compile the Less and view the awesome changes in your browser

152 |
153 |
154 |

Semantic

155 |

Everything is now semantic. Now you can have the cleanest markup without sacrificing the utility and speed of AdaptGrid.

156 |
157 |
158 |

Mobile Fisrt

159 |

Now you can build for small devices first. Then, as devices get larger and larger, layer in more complexity.

160 |
161 |
162 |

Responsive

163 |

Make Responsive Theme part of your website design, or upgrade your current one to a mobile friendly Theme that automatically adapts to any screen resolution or device.

164 |
165 |
166 |

Less

167 |

You don't have to know a ton about Less to take this class. The first hour covers an introduction, with the second hour focused on implementing it. You'll be writing Less in no time.

168 |
169 |
170 |

Css3/html5

171 |

Built-on CSS3 and HTML5 semantics to allow you to start captializing on a next generation standard.

172 |
173 |
174 |

Quick Start

175 |

First, clone the AdaptGrid from Github. Then add the grid and class in your web. Lastly, compile the Less and view the awesome changes in your browser

176 |
177 |
178 |

Semantic

179 |

Everything is now semantic. Now you can have the cleanest markup without sacrificing the utility and speed of AdaptGrid.

180 |
181 |
182 |

Mobile Fisrt

183 |

Now you can build for small devices first. Then, as devices get larger and larger, layer in more complexity.

184 |
185 |
186 |

Responsive

187 |

Make Responsive Theme part of your website design, or upgrade your current one to a mobile friendly Theme that automatically adapts to any screen resolution or device.

188 |
189 |
190 |

Less

191 |

You don't have to know a ton about Less to take this class. The first hour covers an introduction, with the second hour focused on implementing it. You'll be writing Less in no time.

192 |
193 |
194 |

Css3/html5

195 |

Built-on CSS3 and HTML5 semantics to allow you to start captializing on a next generation standard.

196 |
197 |
198 |

Quick Start

199 |

First, clone the AdaptGrid from Github. Then add the grid and class in your web. Lastly, compile the Less and view the awesome changes in your browser

200 |
201 |
202 |

Semantic

203 |

Everything is now semantic. Now you can have the cleanest markup without sacrificing the utility and speed of AdaptGrid.

204 |
205 |
206 |

Mobile Fisrt

207 |

Now you can build for small devices first. Then, as devices get larger and larger, layer in more complexity.

208 |
209 |
210 |

Responsive

211 |

Make Responsive Theme part of your website design, or upgrade your current one to a mobile friendly Theme that automatically adapts to any screen resolution or device.

212 |
213 |
214 |

Less

215 |

You don't have to know a ton about Less to take this class. The first hour covers an introduction, with the second hour focused on implementing it. You'll be writing Less in no time.

216 |
217 |
218 | 219 | 220 | 221 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /gulp/tasks/archive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import gulp from 'gulp'; 5 | import zip from 'gulp-zip'; 6 | import notify from 'gulp-notify'; 7 | 8 | export default function (src = config.archive.src, dest = config.archive.dest, message = 'Archive task complete') { 9 | return function () { 10 | return gulp.src(src) 11 | .pipe(zip(`${config.version}.zip`)) 12 | .pipe(gulp.dest(dest)) 13 | .pipe(notify({ 14 | title: config.notify.title, 15 | message: message 16 | })); 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /gulp/tasks/assets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import merge from 'merge-stream'; 5 | import gulp from 'gulp'; 6 | import notify from 'gulp-notify'; 7 | import AssetsManager from 'assets-manager'; 8 | import {argv} from 'yargs'; 9 | 10 | function getPackage() { 11 | if (argv.package) { 12 | return argv.package; 13 | } 14 | return null; 15 | } 16 | 17 | /* 18 | * Checkout https://github.com/amazingSurge/assets-manager 19 | */ 20 | export function copy(options = config.assets, message = 'Assets task complete') { 21 | return function (done) { 22 | let pkgName = getPackage(); 23 | const manager = new AssetsManager('manifest.json', options); 24 | 25 | if(pkgName) { 26 | manager.copyPackage(pkgName).then(()=>{ 27 | done(); 28 | }); 29 | } else { 30 | manager.copyPackages().then(()=>{ 31 | done(); 32 | }); 33 | } 34 | } 35 | } 36 | 37 | export function clean(options = config.assets, message = 'Assets clean task complete') { 38 | return function (done) { 39 | let pkgName = getPackage(); 40 | const manager = new AssetsManager('manifest.json', options); 41 | 42 | if(pkgName) { 43 | manager.cleanPackage(pkgName).then(()=>{ 44 | done(); 45 | }); 46 | } else { 47 | manager.cleanPackages().then(()=>{ 48 | done(); 49 | }); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /gulp/tasks/browser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import browser from 'browser-sync'; 5 | import notifier from 'node-notifier'; 6 | 7 | export function init(options = {}, message = 'Browser starting') { 8 | options = Object.assign(options, { 9 | server: { 10 | baseDir: config.browser.baseDir, 11 | }, 12 | startPath: config.browser.startPath, 13 | port: config.browser.browserPort, 14 | ui: { 15 | port: config.browser.UIPort 16 | }, 17 | ghostMode: { 18 | links: false 19 | } 20 | }); 21 | 22 | return function() { 23 | browser.init(options, () => { 24 | notifier.notify({ 25 | title: config.notify.title, 26 | message: message 27 | }); 28 | }); 29 | }; 30 | } 31 | 32 | export function reload(message = 'Browser reloaded') { 33 | return function(done) { 34 | browser.reload(); 35 | done(); 36 | 37 | notifier.notify({ 38 | title: config.notify.title, 39 | message: message 40 | }); 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /gulp/tasks/clean.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import del from 'del'; 5 | 6 | export default function (src = config.paths.destDir) { 7 | return function (done) { 8 | del.sync([src]); 9 | 10 | done(); 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /gulp/tasks/deploy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import gulp from 'gulp'; 5 | import inquirer from 'inquirer'; 6 | import replace from 'gulp-replace'; 7 | import { execSync as exec, spawnSync as spawn } from 'child_process'; 8 | import semver from 'semver'; 9 | import gutil from 'gulp-util'; 10 | 11 | const CURRENT_VERSION = config.version; 12 | let NEXT_VERSION; 13 | let NEXT_MESSAGE; 14 | 15 | export function prompt(done) { 16 | inquirer.prompt([{ 17 | type: 'input', 18 | name: 'version', 19 | message: `What version are we moving to? (Current version is ${CURRENT_VERSION})`, 20 | validate: function (input) { 21 | if(input === '') { 22 | input = CURRENT_VERSION; 23 | } 24 | return /^\d*[\d.]*\d*$/.test(input); 25 | } 26 | }]).then((answers) => { 27 | if (answers.version === '') { 28 | NEXT_VERSION = semver.inc(CURRENT_VERSION, config.deploy.increment); 29 | gutil.log(gutil.colors.green(`No version inputted, bump to version ${NEXT_VERSION}`)); 30 | } else { 31 | NEXT_VERSION = answers.version; 32 | } 33 | 34 | done(); 35 | }); 36 | } 37 | 38 | export function message(done) { 39 | inquirer.prompt([{ 40 | type: 'input', 41 | name: 'message', 42 | message: `What message are we going to commit?`, 43 | validate: function (input) { 44 | if(input === '' && NEXT_VERSION === CURRENT_VERSION) { 45 | return false; 46 | } 47 | return true; 48 | } 49 | }]).then((answers) => { 50 | if (answers.message !== '') { 51 | NEXT_MESSAGE = answers.message; 52 | } else { 53 | NEXT_MESSAGE = ''; 54 | } 55 | done(); 56 | }); 57 | } 58 | 59 | // Bumps the version number in any file that has one 60 | export function version() { 61 | return gulp.src(config.deploy.versionFiles, { 62 | base: process.cwd() 63 | }) 64 | // .pipe(replace(CURRENT_VERSION, NEXT_VERSION)) 65 | .pipe(replace(/Version\s*:\s*([\d.]+)/, `Version: ${NEXT_VERSION}`)) 66 | .pipe(replace(/("|')version\1\s*:\s*("|')([\d.]+)\2/, `$1version$1: $2${NEXT_VERSION}$2`)) 67 | .pipe(gulp.dest('.')); 68 | } 69 | 70 | export function init(done) { 71 | config.production = true; 72 | config.init(); 73 | 74 | done(); 75 | } 76 | 77 | // Writes a commit with the changes to the version numbers 78 | export function commit(done) { 79 | let message = `Release ${NEXT_VERSION}`; 80 | 81 | if (NEXT_VERSION === CURRENT_VERSION) { 82 | message = NEXT_MESSAGE; 83 | } else if(NEXT_MESSAGE !== '') { 84 | message = `${message}; ${NEXT_MESSAGE}`; 85 | } 86 | exec('git add .'); 87 | exec(`git commit -am "${message}"`); 88 | 89 | if (NEXT_VERSION !== CURRENT_VERSION) { 90 | exec(`git tag v${NEXT_VERSION}`); 91 | } 92 | 93 | exec('git push origin master --follow-tags'); 94 | done(); 95 | } 96 | -------------------------------------------------------------------------------- /gulp/tasks/images.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import gulp from 'gulp'; 5 | import path from 'path'; 6 | import notify from 'gulp-notify'; 7 | 8 | export default function (src = config.images.src, dest = config.images.dest, files = config.images.files, message = 'Images task complete') { 9 | return function () { 10 | return gulp.src(path.join(src, files)) 11 | .pipe(gulp.dest(dest)) 12 | .pipe(notify({ 13 | title: config.notify.title, 14 | message: message, 15 | onLast: true 16 | })); 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /gulp/tasks/lint-scripts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import gulp from 'gulp'; 5 | import eslint from 'gulp-eslint'; 6 | import getSrcFiles from '../util/getSrcFiles'; 7 | 8 | export function es(src = config.scripts.src, options = {}, files = ['**/*.js', '!**/*.min.js']) { 9 | return function() { 10 | let srcFiles = getSrcFiles(src, files); 11 | 12 | options = Object.assign({ 13 | useEslintrc: true, 14 | configFile: '.eslintrc.json', 15 | fix: true 16 | }, options); 17 | 18 | return gulp.src(srcFiles, { 19 | base: './' 20 | }) 21 | .pipe(eslint(options)) 22 | .pipe(eslint.format()) 23 | .pipe(eslint.failAfterError()); 24 | }; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /gulp/tasks/lint-styles.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import gulp from 'gulp'; 5 | import stylelint from 'gulp-stylelint'; 6 | import getSrcFiles from '../util/getSrcFiles'; 7 | 8 | export function style(src = config.styles.src, files = '**/*.scss') { 9 | return function() { 10 | let srcFiles = getSrcFiles(src, files); 11 | 12 | return gulp.src(srcFiles) 13 | .pipe(stylelint({ 14 | reporters: [{ 15 | formatter: 'string', 16 | console: true 17 | }] 18 | })); 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /gulp/tasks/release.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import releaseIt from 'release-it'; 5 | import handleErrors from '../util/handleErrors'; 6 | import {argv} from 'yargs'; 7 | 8 | export default function release() { 9 | let options = {}; 10 | options.increment = argv.increment || "patch"; 11 | options.verbose = argv.verbose || true; 12 | options.debug = argv.debug || false; 13 | options.force = argv.force || false; 14 | options['dry-run'] = argv['dry-run'] || false; 15 | 16 | config.setEnv('production'); 17 | 18 | return function(done) { 19 | releaseIt.execute(options).catch(handleErrors).finally(done); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gulp/tasks/scripts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import gulp from 'gulp'; 5 | import babel from 'gulp-babel'; 6 | import gulpif from 'gulp-if'; 7 | import sourcemaps from 'gulp-sourcemaps'; 8 | import handleErrors from '../util/handleErrors'; 9 | import getSrcFiles from '../util/getSrcFiles'; 10 | import browser from 'browser-sync'; 11 | import header from 'gulp-header'; 12 | import rename from 'gulp-rename'; 13 | import rollup from 'gulp-rollup'; 14 | import uglify from 'gulp-uglify'; 15 | import size from 'gulp-size'; 16 | import plumber from 'gulp-plumber'; 17 | import prettier from 'gulp-nf-prettier'; 18 | import path from 'path'; 19 | import notify from 'gulp-notify'; 20 | import replace from 'gulp-replace'; 21 | 22 | export function bundler(src = config.scripts.src, dest = config.scripts.dest, input = config.scripts.input, files = config.scripts.files, message = 'Bundler task complete') { 23 | return function () { 24 | let srcFiles = getSrcFiles(src, files); 25 | 26 | return gulp.src(srcFiles) 27 | .on('error', handleErrors) 28 | .pipe(plumber({errorHandler: handleErrors})) 29 | .pipe(rollup({ 30 | input: `${src}/${input}`, 31 | format: 'es', 32 | globals: { 33 | jquery: 'jQuery' 34 | } 35 | })) 36 | .pipe(header(config.banner)) 37 | .pipe(rename({ 38 | basename: config.name, 39 | suffix: '.es' 40 | })) 41 | .pipe(gulp.dest(dest)) 42 | .pipe(notify({ 43 | title: config.notify.title, 44 | message: message, 45 | onLast: true 46 | })); 47 | }; 48 | } 49 | 50 | export function scripts(src = config.scripts.src, dest = config.scripts.dest, input = config.scripts.input, files = config.scripts.files, message = 'Scripts task complete') { 51 | const createSourcemap = config.deploy || config.scripts.prodSourcemap; 52 | 53 | return function () { 54 | let srcFiles = getSrcFiles(src, files); 55 | 56 | return gulp.src(`${dest}/${config.name}.es.js`) 57 | .on('error', handleErrors) 58 | .pipe(plumber({errorHandler: handleErrors})) 59 | // .pipe(rollup({ 60 | // input: `${src}/${input}`, 61 | // })) 62 | .pipe(babel({ 63 | "presets": ["es2015"], 64 | "plugins": [ 65 | ["transform-es2015-modules-umd", { 66 | "globals": { 67 | "jquery": "jQuery" 68 | } 69 | }] 70 | ] 71 | })) 72 | .pipe(header(config.banner)) 73 | .pipe( 74 | prettier({ 75 | parser: 'flow', 76 | tabWidth: 2, 77 | useTabs: false, 78 | semi: true, 79 | singleQuote: true, 80 | bracketSpacing: true, 81 | }) 82 | ) 83 | .pipe(rename({ 84 | basename: config.name 85 | })) 86 | .pipe(gulp.dest(dest)) 87 | .pipe(size({ 88 | title: 'scripts', 89 | showFiles: true 90 | })) 91 | .pipe(rename({ 92 | suffix: '.min' 93 | })) 94 | .pipe(gulpif(createSourcemap, sourcemaps.init())) 95 | .pipe(uglify()) 96 | .pipe(header(config.banner)) 97 | .pipe(gulpif( 98 | createSourcemap, 99 | sourcemaps.write(config.deploy ? './' : null)) 100 | ) 101 | .pipe(gulp.dest(dest)) 102 | .pipe(size({ 103 | title: 'minified scripts', 104 | showFiles: true 105 | })) 106 | .pipe(browser.stream()) 107 | .pipe(notify({ 108 | title: config.notify.title, 109 | message: message, 110 | onLast: true 111 | })); 112 | }; 113 | } 114 | 115 | export function version(src = config.scripts.src, file = config.scripts.version) { 116 | return function() { 117 | return gulp.src(path.join(src, file), {base: "./"}) 118 | .pipe(replace(/("{0,1}|'{0,1})version\1\s*:\s*("|')([\d.]+)\2/, `$1version$1:$2${config.version}$2`)) 119 | .pipe(gulp.dest("./", {overwrite: true})); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /gulp/tasks/styles.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from '../../config'; 4 | import gulp from 'gulp'; 5 | import gulpif from 'gulp-if'; 6 | import sourcemaps from 'gulp-sourcemaps'; 7 | import sass from 'gulp-sass'; 8 | import sassUnicode from 'gulp-sass-unicode'; 9 | import handleErrors from '../util/handleErrors'; 10 | import browser from 'browser-sync'; 11 | import autoprefixer from 'gulp-autoprefixer'; 12 | import cssnano from 'gulp-cssnano'; 13 | import csscomb from 'gulp-csscomb'; 14 | import rename from 'gulp-rename'; 15 | import header from 'gulp-header'; 16 | import size from 'gulp-size'; 17 | import plumber from 'gulp-plumber'; 18 | import notify from 'gulp-notify'; 19 | import getSrcFiles from '../util/getSrcFiles'; 20 | 21 | export default function (src = config.styles.src, dest = config.styles.dest, files = config.styles.files, message = 'Styles task complete') { 22 | const createSourcemap = config.deploy || config.styles.prodSourcemap; 23 | 24 | return function() { 25 | let srcFiles = getSrcFiles(src, files); 26 | 27 | return gulp.src(srcFiles) 28 | .on('error', handleErrors) 29 | .pipe(plumber({errorHandler: handleErrors})) 30 | .pipe(sass({ 31 | outputStyle: 'nested', 32 | includePaths: config.styles.sassIncludePaths 33 | })) 34 | .pipe(sassUnicode()) 35 | .pipe(csscomb('.csscomb.json')) 36 | .pipe(autoprefixer(config.styles.autoprefixer)) 37 | .pipe(header(config.banner)) 38 | .pipe(gulp.dest(dest)) 39 | .pipe(size({ 40 | title: 'styles', 41 | showFiles: true 42 | })) 43 | .pipe(rename({ 44 | suffix: '.min' 45 | })) 46 | .pipe(gulpif(createSourcemap, sourcemaps.init())) 47 | .pipe(cssnano({ 48 | safe: true, 49 | autoprefixer: false 50 | })) 51 | .pipe(header(config.banner)) 52 | .pipe(gulpif( 53 | createSourcemap, 54 | sourcemaps.write(config.deploy ? './' : null)) 55 | ) 56 | .pipe(gulp.dest(dest)) 57 | .pipe(size({ 58 | title: 'minified styles', 59 | showFiles: true 60 | })) 61 | .pipe(browser.stream()) 62 | .pipe(notify({ 63 | title: config.notify.title, 64 | message: message, 65 | onLast: true 66 | })); 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /gulp/tasks/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Server as KarmaServer } from 'karma'; 4 | 5 | export default function (options = {}) { 6 | return function(done) { 7 | options = Object.assign({ 8 | configFile: `${__dirname}/../../karma.conf.js`, 9 | }, options); 10 | 11 | let karma = new KarmaServer(options, done); 12 | 13 | karma.start(); 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /gulp/util/getFolders.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import fs from 'graceful-fs'; 4 | import path from 'path'; 5 | 6 | export default function(dir) { 7 | return fs.readdirSync(dir).filter((file) => { 8 | return fs.statSync(path.join(dir, file)).isDirectory(); 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /gulp/util/getSrcFiles.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import {argv} from 'yargs'; 4 | import path from 'path'; 5 | import pathExists from 'path-exists'; 6 | 7 | export default function(src, files, argName = 'file') { 8 | let srcFiles = ''; 9 | 10 | if(argv[argName] && pathExists.sync(path.join(src, argv[argName]))) { 11 | let arg = argv[argName]; 12 | srcFiles = `${src}/${arg}`; 13 | } else if(Array.isArray(files)) { 14 | srcFiles = files.map((file) => { 15 | if(file.indexOf('!') === 0) { 16 | file = file.substr(1); 17 | return `!${src}/${file}`; 18 | } 19 | 20 | return `${src}/${file}`; 21 | }); 22 | } else { 23 | srcFiles = `${src}/${files}`; 24 | } 25 | 26 | return srcFiles; 27 | } 28 | -------------------------------------------------------------------------------- /gulp/util/handleErrors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import gutil from 'gulp-util'; 4 | import config from '../../config'; 5 | import notifier from 'node-notifier'; 6 | 7 | export default function(error) { 8 | if (!config.deploy) { 9 | // Send error to notification center with gulp-notify 10 | notifier.notify({ 11 | title: config.notify.title, 12 | subtitle: 'Failure!', 13 | message: error.message, 14 | }); 15 | gutil.log(gutil.colors.red(error)); 16 | // Keep gulp from hanging on this task 17 | this.emit('end'); 18 | } else { 19 | // Log the error and stop the process 20 | // to prevent broken code from building 21 | gutil.log(gutil.colors.red(error)); 22 | process.exit(1); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gulpfile.babel.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import config from './config'; 4 | import fs from 'graceful-fs'; 5 | import gulp from 'gulp'; 6 | import gutil from 'gulp-util'; 7 | 8 | // Tasks 9 | import clean from './gulp/tasks/clean'; 10 | import styles from './gulp/tasks/styles'; 11 | import {version,bundler,scripts} from './gulp/tasks/scripts'; 12 | import * as lintScripts from './gulp/tasks/lint-scripts'; 13 | import * as lintStyles from './gulp/tasks/lint-styles'; 14 | import test from './gulp/tasks/test'; 15 | import * as deploy from './gulp/tasks/deploy'; 16 | import * as browser from './gulp/tasks/browser'; 17 | import * as assets from './gulp/tasks/assets'; 18 | import images from './gulp/tasks/images'; 19 | import archive from './gulp/tasks/archive'; 20 | import release from './gulp/tasks/release'; 21 | 22 | if (config.production) { 23 | gutil.log(gutil.colors.bold.green('� Production Mode')); 24 | } else { 25 | gutil.log(gutil.colors.bold.green('� Development Mode')); 26 | } 27 | 28 | gulp.task('version', version()); 29 | gulp.task('bundler', bundler()); 30 | gulp.task('scripts', scripts()); 31 | gulp.task('clean', clean(config.scripts.dest)); 32 | 33 | // Styles 34 | gulp.task('styles', styles()); 35 | gulp.task('clean:styles', clean(config.styles.dest)); 36 | 37 | // Images 38 | gulp.task('images', images()); 39 | gulp.task('clean:images', clean(config.images.dest)); 40 | 41 | // Build the files 42 | gulp.task('build', gulp.series('clean', 'version', 'bundler', 'scripts', 'styles', 'images')); 43 | 44 | // Assets 45 | gulp.task('assets', assets.copy()); 46 | gulp.task('clean:assets', assets.clean()); 47 | 48 | // Lint Styles 49 | gulp.task('lint:style', lintStyles.style()); 50 | 51 | // Lint Scripts 52 | gulp.task('lint:script:src', lintScripts.es(config.scripts.src)); 53 | gulp.task('lint:script:dest', lintScripts.es(config.scripts.dest)); 54 | gulp.task('lint:script:test', lintScripts.es(config.scripts.test)); 55 | gulp.task('lint:script:gulp', lintScripts.es(config.scripts.gulp, {rules: {'no-console': 'off'}})); 56 | gulp.task('lint:script', gulp.series('lint:script:src', 'lint:script:dest', 'lint:script:test', 'lint:script:gulp')); 57 | 58 | // Run karma for development, will watch and reload 59 | gulp.task('tdd', test()); 60 | 61 | // Run tests and report for ci 62 | gulp.task('test', test({ 63 | singleRun: true, 64 | browsers: ['PhantomJS'], 65 | reporters: ['mocha'] 66 | })); 67 | 68 | gulp.task('coverage', test({ 69 | singleRun: true, 70 | browsers: ['PhantomJS'], 71 | reporters: ['coverage'], 72 | })); 73 | 74 | // Deploy 75 | gulp.task('deploy:prompt', deploy.prompt); 76 | gulp.task('deploy:version', deploy.version); 77 | gulp.task('deploy:message', deploy.message); 78 | gulp.task('deploy:init', deploy.init); 79 | gulp.task('deploy:commit', deploy.commit); 80 | 81 | // Generates compiled CSS and JS files and puts them in the dist/ folder 82 | gulp.task('deploy:dist', gulp.series('build')); 83 | gulp.task('deploy:prepare', gulp.series('deploy:prompt', 'deploy:version', 'deploy:init', 'deploy:dist')); 84 | gulp.task('deploy', gulp.series('deploy:prompt', 'deploy:version', 'deploy:message', 'deploy:dist', 'deploy:commit')); 85 | 86 | // Archive the distrubution files into package 87 | gulp.task('archive', archive()); 88 | 89 | // Starts a BrowerSync instance 90 | gulp.task('serve', browser.init()); 91 | 92 | // Reload browser 93 | gulp.task('reload', browser.reload()); 94 | 95 | // Watch files for changes 96 | gulp.task('watch', () => { 97 | gulp.watch(config.scripts.src, gulp.series('scripts', 'reload')); 98 | gulp.watch(config.styles.src, gulp.series('styles', 'reload')); 99 | }); 100 | 101 | // Release task 102 | gulp.task('release', release()); 103 | 104 | // Dev task 105 | gulp.task('dev', gulp.series('build', 'serve')); 106 | 107 | // Register default task 108 | gulp.task('default', gulp.series('lint:script:src', 'serve')); 109 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | import babel from 'rollup-plugin-babel'; 3 | import babelrc from 'babelrc-rollup'; 4 | import istanbul from 'rollup-plugin-istanbul'; 5 | import babel_istanbul from 'babel-istanbul'; 6 | 7 | module.exports = function(config) { 8 | config.set({ 9 | 10 | // base path that will be used to resolve all patterns (eg. files, exclude) 11 | basePath: '', 12 | 13 | // frameworks to use 14 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 15 | frameworks: ['mocha', 'sinon-chai'], 16 | 17 | // list of files / patterns to load in the browser 18 | files: [ 19 | 'test/spec/*.js' 20 | ], 21 | 22 | // preprocess matching files before serving them to the browser 23 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 24 | preprocessors: { 25 | // "dist/**/*.es.js": ["rollup"], 26 | "src/**/*.js": ["rollup", "coverage"], 27 | "test/spec/**/*.spec.js": ["rollup"] 28 | }, 29 | 30 | // optionally, configure the reporter 31 | // text displays it within the console (alternative: text-summary) 32 | // lcov creates a codecov compatible report 33 | coverageReporter: { 34 | reporters: [ 35 | {'type': 'text'}, 36 | {'type': 'html', dir: 'coverage'}, 37 | {'type': 'lcov'} 38 | ] 39 | }, 40 | 41 | // list of files to exclude 42 | exclude: [ 43 | ], 44 | 45 | 46 | // test results reporter to use 47 | // possible values: 'dots', 'progress' 48 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 49 | // coverage is from karma-coverage and provides Istanbul code coverage report 50 | reporters: ['mocha', 'coverage'], 51 | 52 | 53 | // web server port 54 | port: 9876, 55 | 56 | 57 | // enable / disable colors in the output (reporters and logs) 58 | colors: true, 59 | 60 | 61 | // level of logging 62 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 63 | logLevel: config.LOG_INFO, 64 | 65 | 66 | // enable / disable watching file and executing tests whenever any file changes 67 | autoWatch: true, 68 | 69 | 70 | // start these browsers 71 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 72 | // Currently available: 73 | // - Chrome 74 | // - ChromeCanary 75 | // - Firefox 76 | // - Opera 77 | // - Safari (only Mac) 78 | // - PhantomJS 79 | // - IE (only Windows) 80 | browsers: ['Firefox'], 81 | 82 | // Which plugins to enable 83 | plugins: [ 84 | 'karma-mocha', 85 | 'karma-sinon-chai', 86 | 'karma-chrome-launcher', 87 | 'karma-firefox-launcher', 88 | 'karma-phantomjs-launcher', 89 | 'karma-mocha-reporter', 90 | 'karma-coverage', 91 | 'karma-rollup-plugin' 92 | ], 93 | 94 | rollupPreprocessor: { 95 | plugins: [ 96 | babel(babelrc()), 97 | istanbul({ 98 | include: ['src/**/*.js'], 99 | exclude: ['test/spec/**/*.spec.js', 'node_modules/**'], 100 | // instrumenter: babel_istanbul 101 | }), 102 | ], 103 | sourceMap: 'inline' 104 | }, 105 | 106 | // Continuous Integration mode 107 | // if true, Karma captures browsers, runs the tests and exits 108 | singleRun: false, 109 | 110 | // Concurrency level 111 | // how many browser should be started simultaneous 112 | concurrency: Infinity 113 | }) 114 | } 115 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dest": "examples", 3 | "packages": { 4 | "npm:jquery": true, 5 | "npm:normalize.css": true 6 | } 7 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-scrollToTop", 3 | "title": "jQuery scrollToTop", 4 | "description": "A jquery plugin that automatically add a button to scroll to top.", 5 | "version": "0.4.3", 6 | "homepage": "https://github.com/amazingSurge/jquery-scrollToTop", 7 | "author": { 8 | "name": "amazingSurge", 9 | "email": "amazingSurge@gmail.com", 10 | "url": "amazingSurge.com" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git@github.com:amazingSurge/jquery-scrollToTop.git" 15 | }, 16 | "keywords": [ 17 | "jquery", 18 | "jquery-plugin", 19 | "ecosystem:jquery", 20 | "ui", 21 | "es6", 22 | "Scrollbar" 23 | ], 24 | "bugs": "https://github.com/amazingSurge/jquery-scrollToTop/issues", 25 | "licenses": [ 26 | { 27 | "type": "LGPL-3.0", 28 | "url": "https://github.com/amazingSurge/jquery-scrollToTop/blob/master/LICENSE" 29 | } 30 | ], 31 | "license": "LGPL-3.0", 32 | "main": "dist/jquery-scrollToTop.js", 33 | "module": "dist/jquery-scrollToTop.es.js", 34 | "files": [ 35 | "dist", 36 | "src" 37 | ], 38 | "scripts": { 39 | "prestart": "npm install", 40 | "start": "gulp serve", 41 | "build": "npm run prestart && gulp build", 42 | "deploy": "gulp deploy", 43 | "deploy:prepare": "gulp deploy:prepare", 44 | "release": "gulp release", 45 | "test": "gulp test" 46 | }, 47 | "devDependencies": { 48 | "yargs": "*", 49 | "assets-manager": "*", 50 | "babel-core": "*", 51 | "babel-eslint": "*", 52 | "babel-istanbul": "*", 53 | "babel-plugin-transform-es2015-modules-umd": "*", 54 | "babel-preset-es2015": "*", 55 | "babel-preset-es2015-rollup": "*", 56 | "babelrc-rollup": "*", 57 | "browser-sync": "*", 58 | "chai": "*", 59 | "del": "*", 60 | "prettier": "*", 61 | "gulp-nf-prettier": "*", 62 | "graceful-fs": "*", 63 | "gulp": "github:gulpjs/gulp#4.0", 64 | "gulp-autoprefixer": "*", 65 | "gulp-babel": "*", 66 | "gulp-changed": "*", 67 | "gulp-csscomb": "*", 68 | "gulp-cssnano": "*", 69 | "gulp-eslint": "*", 70 | "gulp-extname": "*", 71 | "gulp-filter": "*", 72 | "gulp-header": "*", 73 | "gulp-iconfont-css": "*", 74 | "gulp-if": "*", 75 | "gulp-notify": "*", 76 | "gulp-plumber": "*", 77 | "gulp-rename": "*", 78 | "gulp-replace": "*", 79 | "gulp-rollup": "*", 80 | "gulp-sass": "*", 81 | "gulp-sass-unicode": "*", 82 | "gulp-size": "*", 83 | "gulp-sourcemaps": "*", 84 | "gulp-stylelint": "*", 85 | "gulp-uglify": "*", 86 | "gulp-util": "*", 87 | "gulp-zip": "*", 88 | "inquirer": "*", 89 | "semver": "*", 90 | "karma": "*", 91 | "karma-babel-preprocessor": "*", 92 | "karma-chrome-launcher": "*", 93 | "karma-commonjs": "*", 94 | "karma-coverage": "*", 95 | "karma-firefox-launcher": "*", 96 | "karma-mocha": "*", 97 | "karma-mocha-reporter": "*", 98 | "karma-phantomjs-launcher": "*", 99 | "karma-rollup-plugin": "*", 100 | "karma-sinon-chai": "*", 101 | "merge-stream": "*", 102 | "mkdirp": "*", 103 | "mocha": "*", 104 | "node-notifier": "*", 105 | "normalize.css": "^7.0.0", 106 | "path-exists": "*", 107 | "phantomjs-prebuilt": "*", 108 | "release-it": "*", 109 | "rollup-plugin-babel": "*", 110 | "rollup-plugin-istanbul": "*", 111 | "sinon": "*", 112 | "sinon-chai": "*", 113 | "stylelint-config-bootstrap": "*", 114 | "stylelint-scss": "*", 115 | "through2": "*" 116 | }, 117 | "engines": { 118 | "node": ">= 6.2.2", 119 | "npm": ">= 3" 120 | }, 121 | "dependencies": { 122 | "jquery": ">=2.2.0" 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/defaults.js: -------------------------------------------------------------------------------- 1 | export default { 2 | distance: 200, 3 | speed: 1000, 4 | easing: 'linear', 5 | animation: 'fade', // fade, slide, none 6 | animationSpeed: 500, 7 | 8 | mobile: { 9 | width: 768, 10 | distance: 100, 11 | speed: 1000, 12 | easing: 'easeInOutElastic', 13 | animation: 'slide', 14 | animationSpeed: 200 15 | }, 16 | 17 | trigger: null, // Set a custom triggering element. Can be an HTML string or jQuery object 18 | target: null, // Set a custom target element for scrolling to. Can be element or number 19 | text: 'Scroll To Top', // Text for element, can contain HTML 20 | 21 | skin: null, 22 | throttle: 250, 23 | 24 | namespace: 'scrollToTop' 25 | }; 26 | -------------------------------------------------------------------------------- /src/images/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/.gitignore -------------------------------------------------------------------------------- /src/images/cycle-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/cycle-hover.png -------------------------------------------------------------------------------- /src/images/cycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/cycle.png -------------------------------------------------------------------------------- /src/images/square-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/square-hover.png -------------------------------------------------------------------------------- /src/images/square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/square.png -------------------------------------------------------------------------------- /src/images/text-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/text-hover.png -------------------------------------------------------------------------------- /src/images/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/text.png -------------------------------------------------------------------------------- /src/images/triangle-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/triangle-hover.png -------------------------------------------------------------------------------- /src/images/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecreation/jquery-scrollToTop/6e0d2a230c37c76ed2bf1e7e35831409796571e7/src/images/triangle.png -------------------------------------------------------------------------------- /src/info.js: -------------------------------------------------------------------------------- 1 | export default { 2 | version:'0.4.3' 3 | }; 4 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import $ from 'jquery'; 2 | import ScrollToTop from './scrollToTop'; 3 | import info from './info'; 4 | 5 | const NAMESPACE = 'scrollToTop'; 6 | const OtherScrollToTop = $.fn.scrollToTop; 7 | 8 | const jQueryScrollToTop = function(options, ...args) { 9 | if (typeof options === 'string') { 10 | const method = options; 11 | 12 | if (/^_/.test(method)) { 13 | return false; 14 | } else if ((/^(get)/.test(method))) { 15 | const instance = this.first().data(NAMESPACE); 16 | if (instance && typeof instance[method] === 'function') { 17 | return instance[method](...args); 18 | } 19 | } else { 20 | return this.each(function() { 21 | const instance = $.data(this, NAMESPACE); 22 | if (instance && typeof instance[method] === 'function') { 23 | instance[method](...args); 24 | } 25 | }); 26 | } 27 | } 28 | 29 | return this.each(function() { 30 | if (!$(this).data(NAMESPACE)) { 31 | $(this).data(NAMESPACE, new ScrollToTop(options)); 32 | } 33 | }); 34 | }; 35 | 36 | $.fn.scrollToTop = jQueryScrollToTop; 37 | 38 | $.scrollToTop = $.extend({ 39 | setDefaults: ScrollToTop.setDefaults, 40 | noConflict: function() { 41 | $.fn.scrollToTop = OtherScrollToTop; 42 | return jQueryScrollToTop; 43 | } 44 | }, info); 45 | -------------------------------------------------------------------------------- /src/scrollToTop.js: -------------------------------------------------------------------------------- 1 | import $ from 'jquery'; 2 | import DEFAULTS from './defaults'; 3 | import * as util from './util'; 4 | 5 | 6 | /** 7 | * Plugin constructor 8 | **/ 9 | class ScrollToTop { 10 | constructor(options = {}) { 11 | this.$doc = $('body'); 12 | this.options = $.extend(true, {}, DEFAULTS, options); 13 | 14 | const namespace = this.options.namespace; 15 | 16 | if (this.options.skin === null) { 17 | this.options.skin = 'default'; 18 | } 19 | 20 | this.classes = { 21 | skin: `${namespace}_${this.options.skin}`, 22 | trigger: namespace, 23 | animating: `${namespace}_animating`, 24 | show: `${namespace}_show` 25 | }; 26 | 27 | this.disabled = false; 28 | this.useMobile = false; 29 | this.isShow = false; 30 | 31 | this._init(); 32 | } 33 | 34 | _init() { 35 | this.transition = util.transition(); 36 | this._build(); 37 | 38 | if (this.options.target) { 39 | if (typeof this.options.target === 'number') { 40 | this.target = this.options.target; 41 | } else if (typeof this.options.target === 'string') { 42 | this.target = Math.floor($(this.options.target).offset().top); 43 | } 44 | } else { 45 | this.target = 0; 46 | } 47 | 48 | this._bindEvents(); 49 | 50 | this._toggle(); 51 | } 52 | 53 | _bindEvents() { 54 | this.$trigger.on('click.scrollToTop', () => { 55 | this.$doc.trigger('ScrollToTop::jump'); 56 | return false; 57 | }); 58 | 59 | // bind events 60 | this.$doc.on('ScrollToTop::jump', () => { 61 | if (this.disabled) { 62 | return; 63 | } 64 | 65 | this.checkMobile(); 66 | 67 | let speed; 68 | let easing; 69 | 70 | if (this.useMobile) { 71 | speed = this.options.mobile.speed; 72 | easing = this.options.mobile.easing; 73 | } else { 74 | speed = this.options.speed; 75 | easing = this.options.easing; 76 | } 77 | 78 | this.$doc.addClass(this.classes.animating); 79 | 80 | if (this.transition.supported) { 81 | const pos = $(window).scrollTop(); 82 | 83 | this.$doc.css({ 84 | 'margin-top': `${-pos + this.target}px` 85 | }); 86 | $(window).scrollTop(this.target); 87 | 88 | this._insertRule(`.duration_${speed}{${this.transition.prefix}transition-duration: ${speed}ms;}`); 89 | 90 | this.$doc.addClass(`easing_${easing} duration_${speed}`).css({ 91 | 'margin-top': '' 92 | }).one(this.transition.end, () => { 93 | this.$doc.removeClass(`${this.classes.animating} easing_${easing} duration_${speed}`); 94 | }); 95 | } else { 96 | $('html, body').stop(true, false).animate({ 97 | scrollTop: this.target 98 | }, speed, () => { 99 | this.$doc.removeClass(this.classes.animating); 100 | }); 101 | return; 102 | } 103 | }) 104 | .on('ScrollToTop::show', () => { 105 | if (this.isShow) { 106 | return; 107 | } 108 | this.isShow = true; 109 | 110 | this.$trigger.addClass(this.classes.show); 111 | }) 112 | .on('ScrollToTop::hide', () => { 113 | if (!this.isShow) { 114 | return; 115 | } 116 | this.isShow = false; 117 | this.$trigger.removeClass(this.classes.show); 118 | }) 119 | .on('ScrollToTop::disable', () => { 120 | this.disabled = true; 121 | this.$doc.trigger('ScrollToTop::hide'); 122 | }) 123 | .on('ScrollToTop::enable', () => { 124 | this.disabled = false; 125 | this._toggle(); 126 | }); 127 | 128 | $(window).on('scroll.ScrollToTop', util.throttle(() => { 129 | if (this.disabled) { 130 | return; 131 | } 132 | 133 | this._toggle(); 134 | }, this.options.throttle)); 135 | 136 | if (this.options.mobile) { 137 | $(window).on('resize.ScrollToTop orientationchange.ScrollToTop', util.throttle(() => { 138 | if (this.disabled) { 139 | return; 140 | } 141 | 142 | this.checkMobile(); 143 | }, this.options.throttle)); 144 | } 145 | } 146 | 147 | _build() { 148 | if (this.options.trigger) { 149 | this.$trigger = $(this.options.trigger); 150 | } else { 151 | this.$trigger = $(`${this.options.text}`).appendTo($('body')); 152 | } 153 | 154 | this._insertRule(`.${this.classes.show}{${this.transition.prefix}animation-duration: ${this.options.animationSpeed}ms;${this.transition.prefix}animation-name: ${this.options.namespace}_${this.options.animation};}`); 155 | 156 | if (this.options.mobile) { 157 | this._insertRule(`@media (max-width: ${this.options.mobile.width}px){.${this.classes.show}{${this.transition.prefix}animation-duration: ${this.options.mobile.animationSpeed}ms !important;${this.transition.prefix}animation-name: ${this.options.namespace}_${this.options.mobile.animation} !important;}}`); 158 | } 159 | } 160 | 161 | checkMobile() { 162 | const width = $(window).width(); 163 | 164 | if (width < this.options.mobile.width) { 165 | this.useMobile = true; 166 | } else { 167 | this.useMobile = false; 168 | } 169 | } 170 | 171 | can() { 172 | let distance; 173 | if (this.useMobile) { 174 | distance = this.options.mobile.distance; 175 | } else { 176 | distance = this.options.distance; 177 | } 178 | if ($(window).scrollTop() > distance) { 179 | return true; 180 | } 181 | return false; 182 | } 183 | 184 | _toggle() { 185 | if (this.can()) { 186 | this.$doc.trigger('ScrollToTop::show'); 187 | } else { 188 | this.$doc.trigger('ScrollToTop::hide'); 189 | } 190 | } 191 | 192 | _insertRule(rule) { 193 | if (this.rules && this.rules[rule]) { 194 | return; 195 | } else if (this.rules === undefined) { 196 | this.rules = {}; 197 | } else { 198 | this.rules[rule] = true; 199 | } 200 | 201 | if (document.styleSheets && document.styleSheets.length) { 202 | document.styleSheets[0].insertRule(rule, 0); 203 | } else { 204 | const style = document.createElement('style'); 205 | style.innerHTML = rule; 206 | document.head.appendChild(style); 207 | } 208 | } 209 | 210 | jump() { 211 | this.$doc.trigger('ScrollToTop::jump'); 212 | } 213 | 214 | disable() { 215 | this.$doc.trigger('ScrollToTop::disable'); 216 | } 217 | 218 | enable() { 219 | this.$doc.trigger('ScrollToTop::enable'); 220 | } 221 | 222 | destroy() { 223 | this.$trigger.remove(); 224 | this.$doc.data('ScrollToTop', null); 225 | this.$doc.off('ScrollToTop::enable') 226 | .off('ScrollToTop::disable') 227 | .off('ScrollToTop::jump') 228 | .off('ScrollToTop::show') 229 | .off('ScrollToTop::hide'); 230 | $(window).off('.ScrollToTop'); 231 | } 232 | 233 | static setDefaults(options) { 234 | $.extend(true, DEFAULTS, $.isPlainObject(options) && options); 235 | } 236 | } 237 | 238 | export default ScrollToTop; 239 | -------------------------------------------------------------------------------- /src/scss/easing.scss: -------------------------------------------------------------------------------- 1 | .easing_linear { 2 | transition-timing-function: cubic-bezier(0.25, 0.25, 0.75, 0.75); 3 | } 4 | .easing_ease { 5 | transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1); 6 | } 7 | 8 | .easing_easeIn { 9 | transition-timing-function: cubic-bezier(0.42, 0, 1, 1); 10 | } 11 | 12 | .easing_easeOut { 13 | transition-timing-function: cubic-bezier(0, 0, 0.58, 1); 14 | } 15 | 16 | .easing_easeInOut { 17 | transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1); 18 | } 19 | 20 | .easing_easeInQuad { 21 | transition-timing-function: cubic-bezier(0.55, 0.085, 0.68, 0.53); 22 | } 23 | 24 | .easing_easeInCubic { 25 | transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); 26 | } 27 | 28 | .easing_easeInQuart { 29 | transition-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22); 30 | } 31 | 32 | .easing_easeInQuint { 33 | transition-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); 34 | } 35 | 36 | .easing_easeInSine { 37 | transition-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715); 38 | } 39 | 40 | .easing_easeInExpo { 41 | transition-timing-function: cubic-bezier(0.95, 0.05, 0.795, 0.035); 42 | } 43 | 44 | .easing_easeInCirc { 45 | transition-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.335); 46 | } 47 | 48 | .easing_easeInBack { 49 | transition-timing-function: cubic-bezier(0.6, -0.28, 0.735, 0.045); 50 | } 51 | 52 | .easing_eastOutQuad { 53 | transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94); 54 | } 55 | 56 | .easing_easeOutCubic { 57 | transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); 58 | } 59 | 60 | .easing_easeOutQuart { 61 | transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1); 62 | } 63 | 64 | .easing_easeOutQuint { 65 | transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1); 66 | } 67 | 68 | .easing_easeOutSine { 69 | transition-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1); 70 | } 71 | 72 | .easing_easeOutExpo { 73 | transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1); 74 | } 75 | 76 | .easing_easeOutCirc { 77 | transition-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1); 78 | } 79 | 80 | .easing_easeOutBack { 81 | transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275); 82 | } 83 | 84 | .easing_easeInOutQuad { 85 | transition-timing-function: cubic-bezier(0.455, 0.03, 0.515, 0.955); 86 | } 87 | 88 | .easing_easeInOutCubic { 89 | transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1); 90 | } 91 | 92 | .easing_easeInOutQuart { 93 | transition-timing-function: cubic-bezier(0.77, 0, 0.175, 1); 94 | } 95 | 96 | .easing_easeInOutQuint { 97 | transition-timing-function: cubic-bezier(0.86, 0, 0.07, 1); 98 | } 99 | 100 | .easing_easeInOutSine { 101 | transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95); 102 | } 103 | 104 | .easing_easeInOutExpo { 105 | transition-timing-function: cubic-bezier(1, 0, 0, 1); 106 | } 107 | 108 | .easing_easeInOutCirc { 109 | transition-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86); 110 | } 111 | 112 | .easing_easeInOutBack { 113 | transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); 114 | } 115 | 116 | .easing_easeInOutElastic { 117 | transition-timing-function: cubic-bezier(1, -0.56, 0, 1.455); 118 | } 119 | 120 | .easing_custom { 121 | transition-timing-function: cubic-bezier(0.5, 0.25, 0.5, 0.75); 122 | } 123 | -------------------------------------------------------------------------------- /src/scss/scrollToTop.scss: -------------------------------------------------------------------------------- 1 | $namespce: scrollToTop !default; 2 | 3 | html { 4 | overflow-y: scroll; 5 | } 6 | 7 | /* core */ 8 | .#{$namespce} { 9 | position: fixed; 10 | right: 20px; 11 | bottom: -100px; 12 | opacity: 0; 13 | 14 | overflow: hidden; 15 | outline: none; 16 | 17 | &_show { 18 | opacity: 1; 19 | bottom: 20px; 20 | } 21 | 22 | &_animating, 23 | &_animating * { 24 | pointer-events: none !important; 25 | } 26 | } 27 | 28 | @keyframes scrollToTop_fade { 29 | 0% {opacity: 0;} 30 | 100% {opacity: 1;} 31 | } 32 | 33 | @keyframes scrollToTop_slide { 34 | 0% {bottom: -100px;} 35 | 100% {bottom: 20px;} 36 | } 37 | 38 | /* skins */ 39 | .#{$namespce} { 40 | width: 50px; 41 | height: 50px; 42 | color: #000; 43 | font-family: sans-serif; 44 | font-size: 12px; 45 | text-decoration: none; 46 | text-transform: uppercase; 47 | text-indent: 100%; 48 | white-space: nowrap; 49 | background: no-repeat center center transparent; 50 | outline: none; 51 | 52 | &_default { 53 | display: block; 54 | width: auto; 55 | height: auto; 56 | padding: 10px; 57 | text-indent: 0; 58 | background: #eee; 59 | -webkit-border-radius: 10px; 60 | border-radius: 10px; 61 | 62 | :hover { 63 | background-color: #ddd; 64 | } 65 | } 66 | 67 | // cycle skin 68 | &_cycle { 69 | background-image: url("../images/cycle.png"); 70 | 71 | &:hover { 72 | background-image: url("../images/cycle-hover.png"); 73 | } 74 | } 75 | 76 | // square skin 77 | &_square { 78 | background-image: url("../images/square.png"); 79 | 80 | &:hover { 81 | background-image: url("../images/square-hover.png"); 82 | } 83 | } 84 | 85 | // text skin 86 | &_text { 87 | background-image: url("../images/text.png"); 88 | 89 | &:hover { 90 | background-image: url("../images/text-hover.png"); 91 | } 92 | } 93 | 94 | // triangle skin 95 | &_triangle { 96 | background-image: url("../images/triangle.png"); 97 | 98 | &:hover { 99 | background-image: url("../images/triangle-hover.png"); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/support.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Css features detect 3 | **/ 4 | import $ from "jquery"; 5 | 6 | let support = {}; 7 | 8 | ((support) => { 9 | /** 10 | * Borrowed from Owl carousel 11 | **/ 12 | let events = { 13 | transition: { 14 | end: { 15 | WebkitTransition: 'webkitTransitionEnd', 16 | MozTransition: 'transitionend', 17 | OTransition: 'oTransitionEnd', 18 | transition: 'transitionend' 19 | } 20 | }, 21 | animation: { 22 | end: { 23 | WebkitAnimation: 'webkitAnimationEnd', 24 | MozAnimation: 'animationend', 25 | OAnimation: 'oAnimationEnd', 26 | animation: 'animationend' 27 | } 28 | } 29 | }, 30 | prefixes = ['webkit', 'Moz', 'O', 'ms'], 31 | style = $('').get(0).style, 32 | tests = { 33 | csstransforms() { 34 | return Boolean(test('transform')); 35 | }, 36 | csstransforms3d() { 37 | return Boolean(test('perspective')); 38 | }, 39 | csstransitions() { 40 | return Boolean(test('transition')); 41 | }, 42 | cssanimations() { 43 | return Boolean(test('animation')); 44 | } 45 | }; 46 | 47 | let test = (property, prefixed) => { 48 | let result = false, 49 | upper = property.charAt(0).toUpperCase() + property.slice(1); 50 | 51 | if (style[property] !== undefined) { 52 | result = property; 53 | } 54 | if (!result) { 55 | $.each(prefixes, (i, prefix) => { 56 | if (style[prefix + upper] !== undefined) { 57 | result = `-${prefix.toLowerCase()}-${upper}`; 58 | return false; 59 | } 60 | return true; 61 | }); 62 | } 63 | 64 | if (prefixed) { 65 | return result; 66 | } 67 | if (result) { 68 | return true; 69 | } 70 | return false; 71 | }; 72 | 73 | let prefixed = (property) => { 74 | return test(property, true); 75 | }; 76 | 77 | if (tests.csstransitions()) { 78 | /*eslint no-new-wrappers: "off"*/ 79 | support.transition = new String(prefixed('transition')); 80 | support.transition.end = events.transition.end[support.transition]; 81 | } 82 | 83 | if (tests.cssanimations()) { 84 | /*eslint no-new-wrappers: "off"*/ 85 | support.animation = new String(prefixed('animation')); 86 | support.animation.end = events.animation.end[support.animation]; 87 | } 88 | 89 | if (tests.csstransforms()) { 90 | /*eslint no-new-wrappers: "off"*/ 91 | support.transform = new String(prefixed('transform')); 92 | support.transform3d = tests.csstransforms3d(); 93 | } 94 | 95 | if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) { 96 | support.touch = true; 97 | } else { 98 | support.touch = false; 99 | } 100 | 101 | if (window.PointerEvent || window.MSPointerEvent) { 102 | support.pointer = true; 103 | } else { 104 | support.pointer = false; 105 | } 106 | 107 | support.prefixPointerEvent = (pointerEvent) => { 108 | let charStart = 9, 109 | subStart = 10; 110 | 111 | return window.MSPointerEvent ? 112 | `MSPointer${pointerEvent.charAt(charStart).toUpperCase()}${pointerEvent.substr(subStart)}` : 113 | pointerEvent; 114 | }; 115 | })(support); 116 | 117 | export default support; 118 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | export function transition() { 2 | let e; 3 | let end; 4 | let prefix = ''; 5 | let supported = false; 6 | const el = document.createElement("fakeelement"); 7 | 8 | const transitions = { 9 | "WebkitTransition": "webkitTransitionEnd", 10 | "MozTransition": "transitionend", 11 | "OTransition": "oTransitionend", 12 | "transition": "transitionend" 13 | }; 14 | 15 | for (e in transitions) { 16 | if (el.style[e] !== undefined) { 17 | end = transitions[e]; 18 | supported = true; 19 | break; 20 | } 21 | } 22 | if (/(WebKit)/i.test(window.navigator.userAgent)) { 23 | prefix = '-webkit-'; 24 | } 25 | return { 26 | prefix, 27 | end, 28 | supported 29 | }; 30 | } 31 | 32 | export function throttle(func, wait) { 33 | const _now = Date.now || function() { 34 | return new Date().getTime(); 35 | }; 36 | 37 | let timeout; 38 | let context; 39 | let args; 40 | let result; 41 | let previous = 0; 42 | let later = function() { 43 | previous = _now(); 44 | timeout = null; 45 | result = func.apply(context, args); 46 | if (!timeout) { 47 | context = args = null; 48 | } 49 | }; 50 | 51 | return (...params) => { 52 | /*eslint consistent-this: "off"*/ 53 | let now = _now(); 54 | let remaining = wait - (now - previous); 55 | context = this; 56 | args = params; 57 | if (remaining <= 0 || remaining > wait) { 58 | if (timeout) { 59 | clearTimeout(timeout); 60 | timeout = null; 61 | } 62 | previous = now; 63 | result = func.apply(context, args); 64 | if (!timeout) { 65 | context = args = null; 66 | } 67 | } else if (!timeout) { 68 | timeout = setTimeout(later, remaining); 69 | } 70 | return result; 71 | }; 72 | } 73 | --------------------------------------------------------------------------------