├── .gitignore ├── Gruntfile.js ├── Gulpfile.js ├── Makefile ├── README.md ├── bower.json ├── eslint.json ├── jquery.page.css ├── jquery.page.d.ts ├── jquery.page.js ├── jquery.page.min.js ├── jshint.json ├── package.json ├── page.jquery.json └── sample ├── app.css ├── app.js └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** jQuery Page -- jQuery Page Transitions for HTML5 Single-Page-Apps 3 | ** Copyright (c) 2016-2021 Dr. Ralf S. Engelschall 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining 6 | ** a copy of this software and associated documentation files (the 7 | ** "Software"), to deal in the Software without restriction, including 8 | ** without limitation the rights to use, copy, modify, merge, publish, 9 | ** distribute, sublicense, and/or sell copies of the Software, and to 10 | ** permit persons to whom the Software is furnished to do so, subject to 11 | ** the following conditions: 12 | ** 13 | ** The above copyright notice and this permission notice shall be included 14 | ** in all copies or substantial portions of the Software. 15 | ** 16 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /* global module: true */ 26 | module.exports = function (grunt) { 27 | grunt.initConfig({ 28 | pkg: grunt.file.readJSON("package.json"), 29 | jshint: { 30 | options: { 31 | jshintrc: "jshint.json" 32 | }, 33 | gruntfile: [ "Gruntfile.js" ], 34 | sourcefiles: [ "jquery.page.js" ] 35 | }, 36 | eslint: { 37 | options: { 38 | configFile: "eslint.json" 39 | }, 40 | target: [ "jquery.page.js" ], 41 | }, 42 | uglify: { 43 | options: { 44 | preserveComments: false, 45 | report: "min" 46 | }, 47 | dist: { 48 | src: "jquery.page.js", 49 | dest: "jquery.page.min.js" 50 | } 51 | }, 52 | clean: { 53 | clean: [ "jquery.page.min.js" ], 54 | distclean: [ "node_modules" ] 55 | } 56 | }); 57 | 58 | grunt.loadNpmTasks("grunt-contrib-jshint"); 59 | grunt.loadNpmTasks("grunt-contrib-uglify"); 60 | grunt.loadNpmTasks("grunt-contrib-clean"); 61 | grunt.loadNpmTasks("grunt-eslint"); 62 | 63 | grunt.registerTask("default", [ "jshint", "eslint", "uglify" ]); 64 | }; 65 | 66 | -------------------------------------------------------------------------------- /Gulpfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** jQuery Page -- jQuery Page Transitions for HTML5 Single-Page-Apps 3 | ** Copyright (c) 2016-2021 Dr. Ralf S. Engelschall 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining 6 | ** a copy of this software and associated documentation files (the 7 | ** "Software"), to deal in the Software without restriction, including 8 | ** without limitation the rights to use, copy, modify, merge, publish, 9 | ** distribute, sublicense, and/or sell copies of the Software, and to 10 | ** permit persons to whom the Software is furnished to do so, subject to 11 | ** the following conditions: 12 | ** 13 | ** The above copyright notice and this permission notice shall be included 14 | ** in all copies or substantial portions of the Software. 15 | ** 16 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | var gulp = require("gulp"); 26 | var rename = require("gulp-rename"); 27 | var jshint = require("gulp-jshint"); 28 | var eslint = require("gulp-eslint"); 29 | var uglify = require("gulp-uglify"); 30 | 31 | gulp.task("jshint", function() { 32 | gulp.src("jquery.page.js") 33 | .pipe(jshint("jshint.json")) 34 | .pipe(jshint.reporter("default")) 35 | }); 36 | 37 | gulp.task("eslint", function() { 38 | gulp.src("jquery.page.js") 39 | .pipe(eslint({ configFile: "eslint.json" })) 40 | }); 41 | 42 | gulp.task("uglify", function() { 43 | gulp.src("jquery.page.js") 44 | .pipe(uglify({ preserveComments: false })) 45 | .pipe(rename("jquery.page.min.js")) 46 | .pipe(gulp.dest(".")); 47 | }); 48 | 49 | gulp.task("default", [ "jshint", "eslint", "uglify" ]); 50 | 51 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## 2 | ## jQuery Page -- jQuery Page Transitions for HTML5 Single-Page-Apps 3 | ## Copyright (c) 2016-2021 Dr. Ralf S. Engelschall 4 | ## 5 | ## Permission is hereby granted, free of charge, to any person obtaining 6 | ## a copy of this software and associated documentation files (the 7 | ## "Software"), to deal in the Software without restriction, including 8 | ## without limitation the rights to use, copy, modify, merge, publish, 9 | ## distribute, sublicense, and/or sell copies of the Software, and to 10 | ## permit persons to whom the Software is furnished to do so, subject to 11 | ## the following conditions: 12 | ## 13 | ## The above copyright notice and this permission notice shall be included 14 | ## in all copies or substantial portions of the Software. 15 | ## 16 | ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | ## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | ## IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | ## CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | ## TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | ## SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | ## 24 | 25 | NPM = npm 26 | GRUNT = ./node_modules/grunt-cli/bin/grunt 27 | 28 | all: build 29 | 30 | bootstrap: 31 | @if [ ! -x $(GRUNT) ]; then $(NPM) install; fi 32 | 33 | build: bootstrap 34 | @$(GRUNT) 35 | 36 | clean: bootstrap 37 | @$(GRUNT) clean:clean 38 | 39 | distclean: bootstrap 40 | @$(GRUNT) clean:clean clean:distclean 41 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | jQuery Page 3 | =========== 4 | 5 | jQuery Page Transitions for HTML5 Single-Page-Apps 6 | 7 | Abstract 8 | -------- 9 | 10 | jQuery Page is a [jQuery](http://jquery.com/) plugin for 11 | mobile-style slide/flip-transitioning between page elements in HTML5 12 | Single-Page-Apps. 13 | 14 | Demo 15 | ---- 16 | 17 | See the included [sample/index.html](http://rawgit.com/rse/jquery-page/master/sample/index.html) 18 | for a small demonstration of jQuery Page. 19 | 20 | Motivation 21 | ---------- 22 | 23 | Mobile HTML5 Single-Page Applications (SPA) usually place their app 24 | content onto individual pages and switch between those pages with slide 25 | and flip transition effects. jQuery Page provides the required raw page 26 | transitions only. 27 | 28 | Solution 29 | -------- 30 | 31 | jQuery Page allows arbitrary page elements to be added to an invisible 32 | intermediate container element which is in turn placed into a visible 33 | constraining outmost screen container element. At each time only one 34 | page element is visible. On transitioning jQuery Page enables both the 35 | from/old and the to/new page element and uses the intermediate container 36 | element to provide a visually appealing transition effect. jQuery Page 37 | under the hood uses CSS transitions to perform the visual effect. 38 | 39 | API 40 | --- 41 | 42 | The Application Programming Interface (API) of jQuery Page is 43 | (in TypeScript definition syntax): 44 | 45 | /* the jQuery Page API */ 46 | interface JQueryPage { 47 | /* STRUCTURE: insert page element under unique id */ 48 | insert( 49 | pageId: string, 50 | pageEl: HTMLElement 51 | ): jQueryPage; 52 | 53 | /* STRUCTURE: remove page element by unique id */ 54 | remove( 55 | pageId: string 56 | ): jQueryPage; 57 | 58 | /* STRUCTURE: fetch page element by unique id */ 59 | fetch( 60 | pageId: string 61 | ): HTMLElement; 62 | 63 | /* STATUS: get unique ids of all page elements */ 64 | existing(): string[]; 65 | 66 | /* STATUS: get unique id of currently active page element */ 67 | active(): string; 68 | 69 | /* VISUAL EFFECT: shake the currently active page element */ 70 | shake( 71 | complete?: () => void 72 | ): jQueryPage; 73 | 74 | /* VISUAL EFFECT: transition to a particular page element. 75 | Known transition types are: 76 | - none 77 | - slide-in-from-left 78 | - slide-in-from-right 79 | - slide-in-from-top 80 | - slide-in-from-bottom 81 | - flip-towards-left 82 | - flip-towards-right 83 | */ 84 | transition( 85 | pageId: string, 86 | transitionType: string, 87 | complete?: (pageId: string) => void 88 | ): jQueryPage; 89 | } 90 | 91 | /* the (extended) jQuery API */ 92 | interface JQuery { 93 | /* create and attach or just retrieve jQuery Page API of queried element(s) */ 94 | page(): JQueryPage; 95 | } 96 | 97 | Getting jQuery-Page 98 | ------------------- 99 | 100 | You can conveniently get jQuery-Page in various ways: 101 | 102 | - Git: directly clone the official jQuery-Page repository 103 | 104 | `$ git clone https://github.com/rse/jquery-page.git` 105 | 106 | - NPM: install as client component via the NPM package manager: 107 | 108 | `$ npm install jquery-page` 109 | 110 | - Bower: install as client component via the Bower component manager: 111 | 112 | `$ bower install jquery-page` 113 | 114 | - cURL: downloading only the main file from the repository 115 | 116 | `$ curl -O https://raw.github.com/rse/jquery-page/master/jquery.page.js` 117 | 118 | Building jQuery Page 119 | --------------------- 120 | 121 | You can pick the jQuery plugin in file "jquery.page.js" as is for use, 122 | but for linting and minifying it yourself you need Node.js ("node") and 123 | its Node.js Package Manager ("npm") globally installed. 124 | 125 | # approach 1: use convenient Makefile (author preference) 126 | $ make 127 | 128 | # approach 2: use Grunt locally (contributor recommendation) 129 | $ npm install 130 | $ node_modules/grunt-cli/bin/grunt 131 | 132 | # approach 3: install and use Grunt globally (contributor alternative) 133 | $ npm install -g grunt-cli 134 | $ npm install 135 | $ grunt 136 | 137 | License 138 | ------- 139 | 140 | Copyright (c) 2016-2021 Dr. Ralf S. Engelschall (http://engelschall.com/) 141 | 142 | Permission is hereby granted, free of charge, to any person obtaining 143 | a copy of this software and associated documentation files (the 144 | "Software"), to deal in the Software without restriction, including 145 | without limitation the rights to use, copy, modify, merge, publish, 146 | distribute, sublicense, and/or sell copies of the Software, and to 147 | permit persons to whom the Software is furnished to do so, subject to 148 | the following conditions: 149 | 150 | The above copyright notice and this permission notice shall be included 151 | in all copies or substantial portions of the Software. 152 | 153 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 154 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 155 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 156 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 157 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 158 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 159 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 160 | 161 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-page", 3 | "version": "1.1.3", 4 | "description": "jQuery Page Transitions for HTML5 Single-Page-Apps", 5 | "main": "jquery.page.js", 6 | "homepage": "https://github.com/rse/jquery-page", 7 | "license": "MIT", 8 | "authors": [ 9 | "Dr. Ralf S. Engelschall " 10 | ], 11 | "keywords": [ 12 | "page", "transition", "slide", "flip" 13 | ], 14 | "dependencies": { 15 | "jquery": "latest" 16 | }, 17 | "ignore": [ 18 | "**/.*", 19 | "node_modules", 20 | "bower_components" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "espree", 3 | "rules": { 4 | "no-alert": 0, 5 | "no-array-constructor": 0, 6 | "no-arrow-condition": 0, 7 | "no-bitwise": 0, 8 | "no-caller": 0, 9 | "no-case-declarations": 0, 10 | "no-catch-shadow": 0, 11 | "no-class-assign": 0, 12 | "no-cond-assign": 2, 13 | "no-console": 0, 14 | "no-const-assign": 0, 15 | "no-constant-condition": 2, 16 | "no-continue": 0, 17 | "no-control-regex": 2, 18 | "no-debugger": 2, 19 | "no-delete-var": 2, 20 | "no-div-regex": 0, 21 | "no-dupe-class-members": 0, 22 | "no-dupe-keys": 2, 23 | "no-dupe-args": 2, 24 | "no-duplicate-case": 2, 25 | "no-else-return": 0, 26 | "no-empty": 2, 27 | "no-empty-character-class": 2, 28 | "no-empty-label": 0, 29 | "no-empty-pattern": 0, 30 | "no-eq-null": 0, 31 | "no-eval": 0, 32 | "no-ex-assign": 2, 33 | "no-extend-native": 0, 34 | "no-extra-bind": 0, 35 | "no-extra-boolean-cast": 2, 36 | "no-extra-parens": 0, 37 | "no-extra-semi": 2, 38 | "no-fallthrough": 2, 39 | "no-floating-decimal": 0, 40 | "no-func-assign": 2, 41 | "no-implicit-coercion": 0, 42 | "no-implied-eval": 0, 43 | "no-inline-comments": 0, 44 | "no-inner-declarations": [2, "functions"], 45 | "no-invalid-regexp": 2, 46 | "no-invalid-this": 0, 47 | "no-irregular-whitespace": 2, 48 | "no-iterator": 0, 49 | "no-label-var": 0, 50 | "no-labels": 0, 51 | "no-lone-blocks": 0, 52 | "no-lonely-if": 0, 53 | "no-loop-func": 0, 54 | "no-mixed-requires": [0, false], 55 | "no-mixed-spaces-and-tabs": [2, false], 56 | "linebreak-style": [0, "unix"], 57 | "no-multi-spaces": 0, 58 | "no-multi-str": 0, 59 | "no-multiple-empty-lines": [0, {"max": 2}], 60 | "no-native-reassign": 0, 61 | "no-negated-condition": 0, 62 | "no-negated-in-lhs": 2, 63 | "no-nested-ternary": 0, 64 | "no-new": 0, 65 | "no-new-func": 0, 66 | "no-new-object": 0, 67 | "no-new-require": 0, 68 | "no-new-wrappers": 0, 69 | "no-obj-calls": 2, 70 | "no-octal": 2, 71 | "no-octal-escape": 0, 72 | "no-param-reassign": 0, 73 | "no-path-concat": 0, 74 | "no-plusplus": 0, 75 | "no-process-env": 0, 76 | "no-process-exit": 0, 77 | "no-proto": 0, 78 | "no-redeclare": 2, 79 | "no-regex-spaces": 2, 80 | "no-restricted-modules": 0, 81 | "no-restricted-syntax": 0, 82 | "no-return-assign": 0, 83 | "no-script-url": 0, 84 | "no-self-compare": 0, 85 | "no-sequences": 0, 86 | "no-shadow": 0, 87 | "no-shadow-restricted-names": 0, 88 | "no-spaced-func": 0, 89 | "no-sparse-arrays": 2, 90 | "no-sync": 0, 91 | "no-ternary": 0, 92 | "no-trailing-spaces": 0, 93 | "no-this-before-super": 0, 94 | "no-throw-literal": 0, 95 | "no-undef": 2, 96 | "no-undef-init": 0, 97 | "no-undefined": 0, 98 | "no-unexpected-multiline": 0, 99 | "no-underscore-dangle": 0, 100 | "no-unneeded-ternary": 0, 101 | "no-unreachable": 2, 102 | "no-unused-expressions": 0, 103 | "no-unused-vars": [2, {"vars": "all", "args": "after-used"}], 104 | "no-use-before-define": 0, 105 | "no-useless-call": 0, 106 | "no-useless-concat": 0, 107 | "no-void": 0, 108 | "no-var": 0, 109 | "no-warning-comments": [0, { "terms": ["todo", "fixme", "xxx"], "location": "start" }], 110 | "no-with": 0, 111 | "no-magic-numbers": 0, 112 | 113 | "array-bracket-spacing": [0, "never"], 114 | "arrow-body-style": [0, "as-needed"], 115 | "arrow-parens": 0, 116 | "arrow-spacing": 0, 117 | "accessor-pairs": 0, 118 | "block-scoped-var": 0, 119 | "block-spacing": 0, 120 | "brace-style": [0, "1tbs"], 121 | "callback-return": 0, 122 | "camelcase": 0, 123 | "comma-dangle": [2, "never"], 124 | "comma-spacing": 0, 125 | "comma-style": 0, 126 | "complexity": [0, 11], 127 | "computed-property-spacing": [0, "never"], 128 | "consistent-return": 0, 129 | "consistent-this": [0, "that"], 130 | "constructor-super": 0, 131 | "curly": [0, "all"], 132 | "default-case": 0, 133 | "dot-location": 0, 134 | "dot-notation": [0, { "allowKeywords": true }], 135 | "eol-last": 0, 136 | "eqeqeq": 0, 137 | "func-names": 0, 138 | "func-style": [0, "declaration"], 139 | "generator-star-spacing": 0, 140 | "global-require": 0, 141 | "guard-for-in": 0, 142 | "handle-callback-err": 0, 143 | "id-length": 0, 144 | "indent": 0, 145 | "init-declarations": 0, 146 | "jsx-quotes": [0, "prefer-double"], 147 | "key-spacing": [0, { "beforeColon": false, "afterColon": true }], 148 | "lines-around-comment": 0, 149 | "max-depth": [0, 4], 150 | "max-len": [0, 80, 4], 151 | "max-nested-callbacks": [0, 2], 152 | "max-params": [0, 3], 153 | "max-statements": [0, 10], 154 | "new-cap": 0, 155 | "new-parens": 0, 156 | "newline-after-var": 0, 157 | "object-curly-spacing": [0, "never"], 158 | "object-shorthand": 0, 159 | "one-var": [0, "always"], 160 | "operator-assignment": [0, "always"], 161 | "operator-linebreak": 0, 162 | "padded-blocks": 0, 163 | "prefer-arrow-callback": 0, 164 | "prefer-const": 0, 165 | "prefer-spread": 0, 166 | "prefer-reflect": 0, 167 | "prefer-template": 0, 168 | "quote-props": 0, 169 | "quotes": [0, "double"], 170 | "radix": 0, 171 | "id-match": 0, 172 | "require-jsdoc": 0, 173 | "require-yield": 0, 174 | "semi": 0, 175 | "semi-spacing": [0, {"before": false, "after": true}], 176 | "sort-vars": 0, 177 | "space-after-keywords": [0, "always"], 178 | "space-before-keywords": [0, "always"], 179 | "space-before-blocks": [0, "always"], 180 | "space-before-function-paren": [0, "always"], 181 | "space-in-parens": [0, "never"], 182 | "space-infix-ops": 0, 183 | "space-return-throw-case": 0, 184 | "space-unary-ops": [0, { "words": true, "nonwords": false }], 185 | "spaced-comment": 0, 186 | "strict": 0, 187 | "use-isnan": 2, 188 | "valid-jsdoc": 0, 189 | "valid-typeof": 2, 190 | "vars-on-top": 0, 191 | "wrap-iife": 0, 192 | "wrap-regex": 0, 193 | "yoda": [0, "never"] 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /jquery.page.css: -------------------------------------------------------------------------------- 1 | /*! 2 | ** jQuery Page -- jQuery Page Transitions for HTML5 Single-Page-Apps 3 | ** Copyright (c) 2016-2021 Dr. Ralf S. Engelschall 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining 6 | ** a copy of this software and associated documentation files (the 7 | ** "Software"), to deal in the Software without restriction, including 8 | ** without limitation the rights to use, copy, modify, merge, publish, 9 | ** distribute, sublicense, and/or sell copies of the Software, and to 10 | ** permit persons to whom the Software is furnished to do so, subject to 11 | ** the following conditions: 12 | ** 13 | ** The above copyright notice and this permission notice shall be included 14 | ** in all copies or substantial portions of the Software. 15 | ** 16 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /* the window */ 26 | .jquery-page { 27 | height: 100%; 28 | width: 100%; 29 | display: block; 30 | position: relative; 31 | overflow: hidden; 32 | } 33 | 34 | /* the container */ 35 | .jquery-page .jquery-page-container { 36 | height: 100%; 37 | width: 100%; 38 | position: relative; 39 | } 40 | .jquery-page .jquery-page-container.jquery-page-stacked { 41 | display: block; 42 | -webkit-transform-style: preserve-3d; 43 | transform-style: preserve-3d; 44 | -webkit-perspective: 400px; 45 | perspective: 400px; 46 | } 47 | .jquery-page .jquery-page-container.jquery-page-horizontal { 48 | display: flex; 49 | flex-direction: row; 50 | flex-wrap: none; 51 | } 52 | .jquery-page .jquery-page-container.jquery-page-vertical { 53 | display: flex; 54 | flex-direction: column; 55 | flex-wrap: none; 56 | } 57 | .jquery-page .jquery-page-container.jquery-page-flip-left, 58 | .jquery-page .jquery-page-container.jquery-page-flip-right { 59 | transition: all 0.5s ease-in-out; 60 | box-shadow: 0 0 40px #333333; 61 | } 62 | .jquery-page .jquery-page-container.jquery-page-flip-left { 63 | transform: perspective(400px) rotateY(-180deg); 64 | } 65 | .jquery-page .jquery-page-container.jquery-page-flip-right { 66 | transform: perspective(400px) rotateY(180deg); 67 | } 68 | .jquery-page .jquery-page-container.jquery-page-slide { 69 | transition: all 0.5s ease-in-out; 70 | } 71 | .jquery-page .jquery-page-container.jquery-page-shake { 72 | animation: jquery-page-shake 0.50s cubic-bezier(.36, .07, .19, .97) both; 73 | } 74 | @keyframes jquery-page-shake { 75 | 10%, 90% { transform: translateX(-1px); } 76 | 20%, 80% { transform: translateX( 2px); } 77 | 30%, 50%, 70% { transform: translateX(-4px); } 78 | 40%, 60% { transform: translateX( 4px); } 79 | } 80 | 81 | /* the page(s) */ 82 | .jquery-page .jquery-page-front, 83 | .jquery-page .jquery-page-back { 84 | z-index: 0; 85 | position: absolute; 86 | top: 0; 87 | left: 0; 88 | -moz-backface-visibility: hidden; 89 | -webkit-backface-visibility: hidden; 90 | backface-visibility: hidden; 91 | } 92 | .jquery-page .jquery-page-back { 93 | transform: perspective(400px) rotateY(180deg); 94 | } 95 | .jquery-page .jquery-page-left, 96 | .jquery-page .jquery-page-top { 97 | order: 1; 98 | } 99 | .jquery-page .jquery-page-right, 100 | .jquery-page .jquery-page-bottom { 101 | order: 2; 102 | } 103 | .jquery-page .jquery-page-disabled { 104 | display: none !important; 105 | } 106 | 107 | -------------------------------------------------------------------------------- /jquery.page.d.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | ** jQuery Page -- jQuery Page Transitions for HTML5 Single-Page-Apps 3 | ** Copyright (c) 2016-2021 Dr. Ralf S. Engelschall 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining 6 | ** a copy of this software and associated documentation files (the 7 | ** "Software"), to deal in the Software without restriction, including 8 | ** without limitation the rights to use, copy, modify, merge, publish, 9 | ** distribute, sublicense, and/or sell copies of the Software, and to 10 | ** permit persons to whom the Software is furnished to do so, subject to 11 | ** the following conditions: 12 | ** 13 | ** The above copyright notice and this permission notice shall be included 14 | ** in all copies or substantial portions of the Software. 15 | ** 16 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /// 26 | 27 | /* the jQuery Page API */ 28 | interface JQueryPage { 29 | /* STRUCTURE: insert page element under unique id */ 30 | insert( 31 | pageId: string, 32 | pageEl: HTMLElement 33 | ): jQueryPage; 34 | 35 | /* STRUCTURE: remove page element by unique id */ 36 | remove( 37 | pageId: string 38 | ): jQueryPage; 39 | 40 | /* STRUCTURE: fetch page element by unique id */ 41 | fetch( 42 | pageId: string 43 | ): HTMLElement; 44 | 45 | /* STATUS: get unique ids of all page elements */ 46 | existing(): string[]; 47 | 48 | /* STATUS: get unique id of currently active page element */ 49 | active(): string; 50 | 51 | /* VISUAL EFFECT: shake the currently active page element */ 52 | shake( 53 | complete?: () => void 54 | ): jQueryPage; 55 | 56 | /* VISUAL EFFECT: transition to a particular page element. 57 | Known transition types are: 58 | - none 59 | - slide-in-from-left 60 | - slide-in-from-right 61 | - slide-in-from-top 62 | - slide-in-from-bottom 63 | - flip-towards-left 64 | - flip-towards-right 65 | */ 66 | transition( 67 | pageId: string, 68 | transitionType: string, 69 | complete?: (pageId: string) => void 70 | ): jQueryPage; 71 | } 72 | 73 | /* the (extended) jQuery API */ 74 | interface JQuery { 75 | /* create and attach or just retrieve jQuery Page API of queried element(s) */ 76 | page(): JQueryPage; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /jquery.page.js: -------------------------------------------------------------------------------- 1 | /*! 2 | ** jQuery Page -- jQuery Page Transitions for HTML5 Single-Page-Apps 3 | ** Copyright (c) 2016-2021 Dr. Ralf S. Engelschall 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining 6 | ** a copy of this software and associated documentation files (the 7 | ** "Software"), to deal in the Software without restriction, including 8 | ** without limitation the rights to use, copy, modify, merge, publish, 9 | ** distribute, sublicense, and/or sell copies of the Software, and to 10 | ** permit persons to whom the Software is furnished to do so, subject to 11 | ** the following conditions: 12 | ** 13 | ** The above copyright notice and this permission notice shall be included 14 | ** in all copies or substantial portions of the Software. 15 | ** 16 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | /* global jQuery: false */ 26 | (function ($) { 27 | /* internal API class */ 28 | var Page = function (root) { 29 | this.root = root; 30 | }; 31 | Page.prototype = { 32 | /* API method: insert new page element */ 33 | insert: function (pageId, el) { 34 | var self = this; 35 | 36 | /* sanity check arguments */ 37 | if (arguments.length !== 2) 38 | throw new Error("invalid number of arguments"); 39 | if (typeof pageId !== "string") 40 | throw new Error("invalid page id argument (string expected)"); 41 | 42 | /* append element */ 43 | $("> .jquery-page-container", self.root).append( 44 | $(el) 45 | .attr("data-jquery-page-name", pageId) 46 | .addClass("jquery-page-disabled") 47 | ); 48 | return this; 49 | }, 50 | 51 | /* API method: remove existing page element */ 52 | remove: function (pageId) { 53 | var self = this; 54 | 55 | /* sanity check arguments */ 56 | if (arguments.length !== 1) 57 | throw new Error("invalid number of arguments"); 58 | if (typeof pageId !== "string") 59 | throw new Error("invalid page id argument (string expected)"); 60 | 61 | /* remove element */ 62 | var page = $("> .jquery-page-container > *", self.root).filter(function (idx, el) { 63 | return $(el).attr("data-jquery-page-name") === pageId; 64 | }); 65 | if (page.length === 0) 66 | throw new Error("no such page \"" + pageId + "\" found"); 67 | if ($(page).hasClass("jquery-page-active")) { 68 | var others = self.existing().filter(function (id) { 69 | return id !== pageId; 70 | }); 71 | if (others.length > 0) 72 | self.transition(others[0], "none"); 73 | } 74 | $(page).remove(); 75 | 76 | return this; 77 | }, 78 | 79 | /* API method: fetch element of particular page */ 80 | fetch: function (pageId) { 81 | var self = this; 82 | 83 | /* sanity check arguments */ 84 | if (arguments.length === 0) 85 | throw new Error("missing page id"); 86 | else if (arguments.length === 1 && typeof pageId !== "string") 87 | throw new Error("invalid page id argument (string expected)"); 88 | 89 | /* get page element */ 90 | var pageTo = $("> .jquery-page-container > *", self.root).filter(function (idx, el) { 91 | return $(el).attr("data-jquery-page-name") === pageId; 92 | }); 93 | if (pageTo.length > 1) 94 | throw new Error("more than one page with id \"" + pageId + "\" found"); 95 | if (pageTo.length === 0) 96 | return null; 97 | return pageTo.get(0); 98 | }, 99 | 100 | /* API method: fetch ids of all existing page elements */ 101 | existing: function () { 102 | var self = this; 103 | 104 | /* sanity check arguments */ 105 | if (arguments.length !== 0) 106 | throw new Error("invalid number of arguments"); 107 | 108 | /* find all pages */ 109 | var pages = []; 110 | $("> .jquery-page-container > *", self.root).each(function () { 111 | pages.push($(this).attr("data-jquery-page-name")); 112 | }); 113 | return pages; 114 | }, 115 | 116 | /* API method: get id of currently active element */ 117 | active: function () { 118 | var self = this; 119 | 120 | /* sanity check arguments */ 121 | if (arguments.length !== 0) 122 | throw new Error("invalid number of arguments"); 123 | 124 | /* get id of currently active page element */ 125 | var pageActive = $("> .jquery-page-container > .jquery-page-active", self.root); 126 | if (pageActive.length === 0) 127 | throw new Error("internal error: no active page found"); 128 | if (pageActive.length > 1) 129 | throw new Error("internal error: more than one active page found"); 130 | return pageActive.attr("data-jquery-page-name"); 131 | }, 132 | 133 | /* API method: shake current page element */ 134 | shake: function (complete) { 135 | var self = this; 136 | 137 | /* sanity check arguments */ 138 | if (arguments.length < 0 || arguments.length > 1) 139 | throw new Error("invalid number of arguments (0 or 1 expected)"); 140 | else if (arguments.length === 1 && typeof complete !== "function") 141 | throw new Error("invalid complete argument (function expected)"); 142 | 143 | /* apply effect */ 144 | var pageCo = $("> .jquery-page-container", self.root); 145 | var pageWidth = $(self.root).width(); 146 | var handler = function (ev) { 147 | if (ev.target !== this) 148 | return; 149 | $(pageCo) 150 | .css("width", "") 151 | .removeClass("jquery-page-shake"); 152 | if (typeof complete === "function") 153 | complete.call(this); 154 | $(pageCo).off("animationend", handler); 155 | }; 156 | $(pageCo) 157 | .width(pageWidth) 158 | .addClass("jquery-page-shake") 159 | .on("animationend", handler); 160 | 161 | return this; 162 | }, 163 | 164 | /* API method: transition to a particular page element */ 165 | transition: function (pageId, transition, complete) { 166 | var self = this; 167 | 168 | /* sanity check arguments */ 169 | if (arguments.length < 2 || arguments.length > 3) 170 | throw new Error("invalid number of arguments (2 or 3 expected)"); 171 | else if (typeof pageId !== "string") 172 | throw new Error("invalid page id argument (string expected)"); 173 | else if (typeof transition !== "string") 174 | throw new Error("invalid transition type argument (string expected)"); 175 | else if (arguments.length === 3 && typeof complete !== "function") 176 | throw new Error("invalid complete argument (function expected)"); 177 | 178 | /* get page container */ 179 | var pageCo = $("> .jquery-page-container", self.root); 180 | 181 | /* get from/to pages */ 182 | var pageFr = $("> .jquery-page-container > .jquery-page-active", self.root); 183 | if (transition !== "none" && pageFr.length === 0) 184 | throw new Error("internal error: no active page found"); 185 | if (transition !== "none" && pageFr.length > 1) 186 | throw new Error("internal error: more than one active page found"); 187 | var pageTo = $("> .jquery-page-container > *", self.root).filter(function (idx, el) { 188 | return $(el).attr("data-jquery-page-name") === pageId; 189 | }); 190 | if (pageTo.length === 0) 191 | throw new Error("no such page \"" + pageId + "\" found"); 192 | if (pageTo.length > 1) 193 | throw new Error("more than one page with id \"" + pageId + "\" found"); 194 | 195 | /* determine page dimensions */ 196 | var pageWidth = $(self.root).width(); 197 | var pageHeight = $(self.root).height(); 198 | 199 | /* dispatch according to transition type */ 200 | var m, to, handler; 201 | if (transition === "none") { 202 | /* TRANSITION: none at all (just switch instantly) */ 203 | $(pageFr) 204 | .removeClass("jquery-page-active") 205 | .addClass("jquery-page-disabled"); 206 | $(pageTo) 207 | .removeClass("jquery-page-disabled") 208 | .addClass("jquery-page-active"); 209 | if (typeof complete === "function") 210 | complete.call(this, pageId); 211 | } 212 | else if ((m = transition.match(/^slide-in-from-(left|right)$/)) !== null) { 213 | /* TRANSITION: slide in from left/right */ 214 | to = m[1]; 215 | $(pageCo) 216 | .width(pageWidth * 2) 217 | .css("left", to === "left" ? -pageWidth : 0) 218 | .addClass("jquery-page-horizontal"); 219 | $(pageFr) 220 | .width(pageWidth) 221 | .addClass(to === "left" ? "jquery-page-right" : "jquery-page-left"); 222 | $(pageTo) 223 | .width(pageWidth) 224 | .addClass(to === "left" ? "jquery-page-left" : "jquery-page-right") 225 | .removeClass("jquery-page-disabled"); 226 | handler = function (ev) { 227 | if (ev.target !== this) 228 | return; 229 | $(pageFr) 230 | .addClass("jquery-page-disabled") 231 | .removeClass(to === "left" ? "jquery-page-right" : "jquery-page-left") 232 | .removeClass("jquery-page-active") 233 | .css("width", ""); 234 | $(pageTo) 235 | .removeClass(to === "left" ? "jquery-page-left" : "jquery-page-right") 236 | .addClass("jquery-page-active") 237 | .css("width", ""); 238 | $(pageCo) 239 | .css("width", "") 240 | .css("transform", "") 241 | .css("left", "") 242 | .removeClass("jquery-page-horizontal") 243 | .removeClass("jquery-page-slide"); 244 | if (typeof complete === "function") 245 | complete.call(this, pageId); 246 | $(pageCo).off("transitionend", handler); 247 | }; 248 | $(pageCo) 249 | .addClass("jquery-page-slide") 250 | .css("transform", "translate(" + (to === "left" ? "" : "-") + pageWidth + "px,0)") 251 | .on("transitionend", handler); 252 | } 253 | else if ((m = transition.match(/^slide-in-from-(top|bottom)$/)) !== null) { 254 | /* TRANSITION: slide in from top/bottom */ 255 | to = m[1]; 256 | $(pageCo) 257 | .height(pageHeight * 2) 258 | .css("top", to === "top" ? -pageHeight : 0) 259 | .addClass("jquery-page-vertical"); 260 | $(pageFr) 261 | .addClass(to === "top" ? "jquery-page-bottom" : "jquery-page-top") 262 | .height(pageHeight); 263 | $(pageTo) 264 | .addClass(to === "top" ? "jquery-page-top" : "jquery-page-bottom") 265 | .removeClass("jquery-page-disabled") 266 | .height(pageHeight); 267 | handler = function (ev) { 268 | if (ev.target !== this) 269 | return; 270 | $(pageFr) 271 | .addClass("jquery-page-disabled") 272 | .removeClass(to === "top" ? "jquery-page-bottom" : "jquery-page-top") 273 | .removeClass("jquery-page-active") 274 | .css("height", ""); 275 | $(pageTo) 276 | .removeClass(to === "top" ? "jquery-page-top" : "jquery-page-bottom") 277 | .addClass("jquery-page-active") 278 | .css("height", ""); 279 | $(pageCo) 280 | .css("height", "") 281 | .removeClass("jquery-page-vertical") 282 | .removeClass("jquery-page-slide") 283 | .css("transform", "") 284 | .css("top", 0); 285 | if (typeof complete === "function") 286 | complete.call(this, pageId); 287 | $(pageCo).off("transitionend", handler); 288 | }; 289 | $(pageCo) 290 | .addClass("jquery-page-slide") 291 | .css("transform", "translate(0," + (to === "top" ? "" : "-") + pageHeight + "px)") 292 | .on("transitionend", handler); 293 | } 294 | else if ((m = transition.match(/^flip-towards-(left|right)$/)) !== null) { 295 | /* TRANSITION: flip towards left/right */ 296 | to = m[1]; 297 | $(pageCo) 298 | .addClass("jquery-page-stacked") 299 | .width(pageWidth); 300 | $(pageFr) 301 | .addClass("jquery-page-front") 302 | .width(pageWidth); 303 | $(pageTo) 304 | .addClass("jquery-page-back") 305 | .removeClass("jquery-page-disabled") 306 | .width(pageWidth); 307 | handler = function (ev) { 308 | if (ev.target !== this) 309 | return; 310 | $(pageFr) 311 | .addClass("jquery-page-disabled") 312 | .removeClass("jquery-page-front") 313 | .removeClass("jquery-page-active") 314 | .css("width", ""); 315 | $(pageTo) 316 | .removeClass("jquery-page-back") 317 | .addClass("jquery-page-active") 318 | .css("width", ""); 319 | $(pageCo) 320 | .css("width", "") 321 | .removeClass("jquery-page-stacked") 322 | .removeClass("jquery-page-flip-" + to); 323 | if (typeof complete === "function") 324 | complete.call(this, pageId); 325 | $(pageCo).off("transitionend", handler); 326 | }; 327 | $(pageCo) 328 | .addClass("jquery-page-flip-" + to) 329 | .on("transitionend", handler); 330 | } 331 | else 332 | throw new Error("invalid transition type"); 333 | 334 | return this; 335 | } 336 | }; 337 | 338 | /* hook into jQuery (locally) */ 339 | $.fn.extend({ 340 | /* API method */ 341 | page: function () { 342 | var result = null; 343 | this.each(function () { 344 | /* determine attached API */ 345 | var api = $(this).data("jquery-page-api"); 346 | if (!api) { 347 | /* create new attached API and prepare root element */ 348 | api = new Page(this); 349 | $(this) 350 | .data("jquery-page-api", api) 351 | .addClass("jquery-page"); 352 | 353 | /* sanity check and prepare container element */ 354 | var container = $("> *", this); 355 | if (container.length === 0) { 356 | container = $("
"); 357 | $(this).append(container); 358 | } 359 | else if (container.length !== 1) 360 | throw new Error("require a single container element under jQuery Page root element"); 361 | $(container) 362 | .addClass("jquery-page-container"); 363 | 364 | /* prepare already existing page elements */ 365 | $("> *", container) 366 | .addClass("jquery-page-disabled"); 367 | $("> *:first", container) 368 | .removeClass("jquery-page-disabled") 369 | .addClass("jquery-page-active"); 370 | } 371 | result = api; 372 | }); 373 | return result; 374 | } 375 | }); 376 | })(jQuery); 377 | 378 | -------------------------------------------------------------------------------- /jquery.page.min.js: -------------------------------------------------------------------------------- 1 | !function(p){function a(e){this.root=e}a.prototype={insert:function(e,t){if(2!==arguments.length)throw new Error("invalid number of arguments");if("string"!=typeof e)throw new Error("invalid page id argument (string expected)");return p("> .jquery-page-container",this.root).append(p(t).attr("data-jquery-page-name",e).addClass("jquery-page-disabled")),this},remove:function(r){var e=this;if(1!==arguments.length)throw new Error("invalid number of arguments");if("string"!=typeof r)throw new Error("invalid page id argument (string expected)");var t=p("> .jquery-page-container > *",e.root).filter(function(e,t){return p(t).attr("data-jquery-page-name")===r});if(0===t.length)throw new Error('no such page "'+r+'" found');if(p(t).hasClass("jquery-page-active")){var a=e.existing().filter(function(e){return e!==r});0 .jquery-page-container > *",this.root).filter(function(e,t){return p(t).attr("data-jquery-page-name")===r});if(1 .jquery-page-container > *",this.root).each(function(){e.push(p(this).attr("data-jquery-page-name"))}),e},active:function(){if(0!==arguments.length)throw new Error("invalid number of arguments");var e=p("> .jquery-page-container > .jquery-page-active",this.root);if(0===e.length)throw new Error("internal error: no active page found");if(1 .jquery-page-container",this.root),e=p(this.root).width(),a=function(e){e.target===this&&(p(r).css("width","").removeClass("jquery-page-shake"),"function"==typeof t&&t.call(this),p(r).off("animationend",a))};return p(r).width(e).addClass("jquery-page-shake").on("animationend",a),this},transition:function(r,e,t){var a=this;if(arguments.length<2||3 .jquery-page-container",a.root),i=p("> .jquery-page-container > .jquery-page-active",a.root);if("none"!==e&&0===i.length)throw new Error("internal error: no active page found");if("none"!==e&&1 .jquery-page-container > *",a.root).filter(function(e,t){return p(t).attr("data-jquery-page-name")===r});if(0===o.length)throw new Error('no such page "'+r+'" found');if(1 *",this);if(0===t.length)t=p("
"),p(this).append(t);else if(1!==t.length)throw new Error("require a single container element under jQuery Page root element");p(t).addClass("jquery-page-container"),p("> *",t).addClass("jquery-page-disabled"),p("> *:first",t).removeClass("jquery-page-disabled").addClass("jquery-page-active")}r=e}),r}})}(jQuery); -------------------------------------------------------------------------------- /jshint.json: -------------------------------------------------------------------------------- 1 | { 2 | "maxerr": 200, 3 | "bitwise": true, 4 | "camelcase": false, 5 | "curly": false, 6 | "eqeqeq": true, 7 | "forin": false, 8 | "immed": true, 9 | "latedef": true, 10 | "newcap": false, 11 | "noarg": false, 12 | "noempty": false, 13 | "nonew": true, 14 | "plusplus": false, 15 | "quotmark": "double", 16 | "regexp": false, 17 | "undef": true, 18 | "unused": true, 19 | "strict": false, 20 | "trailing": true, 21 | "maxparams": 9, 22 | "maxdepth": 7, 23 | "maxstatements": 150, 24 | "maxlen": 200, 25 | "loopfunc": true 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-page", 3 | "version": "1.1.4", 4 | "description": "jQuery Page Transitions for HTML5 Single-Page-Apps", 5 | "main": "jquery.page.js", 6 | "keywords": [ 7 | "jquery-plugin", "ecosystem:jquery", 8 | "jquery", "page", 9 | "page", "transition", "slide", "flip" 10 | ], 11 | "scripts": { 12 | "test": "grunt" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/rse/jquery-page.git" 17 | }, 18 | "author": { 19 | "name": "Dr. Ralf S. Engelschall", 20 | "email": "rse@engelschall.com", 21 | "url": "http://engelschall.com" 22 | }, 23 | "license": "MIT", 24 | "homepage": "https://github.com/rse/jquery-page", 25 | "bugs": "https://github.com/rse/jquery-page/issues", 26 | "devDependencies": { 27 | "grunt": "1.3.0", 28 | "grunt-cli": "1.3.2", 29 | "grunt-contrib-jshint": "3.0.0", 30 | "grunt-contrib-uglify": "5.0.0", 31 | "grunt-contrib-clean": "2.0.0", 32 | "grunt-eslint": "23.0.0", 33 | "gulp": "4.0.2", 34 | "gulp-rename": "2.0.0", 35 | "gulp-jshint": "2.1.0", 36 | "gulp-eslint": "6.0.0", 37 | "gulp-uglify": "3.0.2" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /page.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "page", 3 | "title": "jQuery Page", 4 | "description": "jQuery Page Transitions for HTML5 Single-Page-Apps", 5 | "version": "1.1.3", 6 | "author": { 7 | "name": "Dr. Ralf S. Engelschall", 8 | "email": "rse@engelschall.com", 9 | "url": "http://engelschall.com" 10 | }, 11 | "licenses": [{ 12 | "type": "MIT", 13 | "url": "http://opensource.org/licenses/MIT" 14 | }], 15 | "dependencies": { 16 | "jquery": ">=1.3" 17 | }, 18 | "keywords": [ 19 | "page", "transition", "slide", "flip" 20 | ], 21 | "homepage": "https://github.com/rse/jquery-page", 22 | "docs": "https://github.com/rse/jquery-page", 23 | "download": "https://raw.github.com/rse/jquery-page/1.0.0/jquery.page.js", 24 | "bugs": "https://github.com/rse/jquery-page/issues" 25 | } 26 | -------------------------------------------------------------------------------- /sample/app.css: -------------------------------------------------------------------------------- 1 | 2 | html, body { 3 | background-color: #999999; 4 | margin: 10px; 5 | } 6 | 7 | .device { 8 | width: 250px; 9 | height: 450px; 10 | background-color: #333333; 11 | padding: 20px; 12 | border-radius: 12px 12px 12px 12px; 13 | background: linear-gradient(to bottom, #404040 0%, #333333 49%, #282828 51%, #222222 100%); 14 | } 15 | 16 | .device .screen { 17 | width: 100%; 18 | height: 100%; 19 | background-color: #666666; 20 | } 21 | 22 | .device .screen .page { 23 | width: 100%; 24 | height: 100%; 25 | color: white; 26 | font-family: sans-serif; 27 | } 28 | 29 | .device .screen .page[data-jquery-page-name='11'] { 30 | background-color: red; 31 | } 32 | .device .screen .page[data-jquery-page-name='12'] { 33 | background-color: purple; 34 | } 35 | .device .screen .page[data-jquery-page-name='21'] { 36 | background-color: green; 37 | } 38 | .device .screen .page[data-jquery-page-name='22'] { 39 | background-color: blue; 40 | } 41 | .device .screen .page[data-jquery-page-name='XX'] { 42 | background-color: orange; 43 | } 44 | 45 | .device .screen .page .title { 46 | width: 100%; 47 | font-weight: bold; 48 | font-size: 20pt; 49 | text-align: center; 50 | padding-top: 10px; 51 | padding-bottom: 10px; 52 | } 53 | 54 | .device .screen .page .navigate { 55 | border: 1px solid white; 56 | margin: 5px; 57 | padding: 5px; 58 | width: 90%; 59 | text-align: center; 60 | } 61 | 62 | .buttons { 63 | margin-top: 20px; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /sample/app.js: -------------------------------------------------------------------------------- 1 | 2 | (function ($) { 3 | $(document).ready(function () { 4 | $(".screen").page(); 5 | $(".screen .page .navigate").click(function (ev) { 6 | var page = $(ev.target).attr("data-page-name"); 7 | var trans = $(ev.target).attr("data-page-trans"); 8 | if ($(".screen").page().fetch(page) === null) 9 | $(".screen").page().shake(); 10 | else 11 | $(".screen").page().transition(page, trans); 12 | }); 13 | $(".screen").page().transition("11", "none"); 14 | $(".remove-button").click(function () { 15 | var id = $(".remove-input").val(); 16 | $(".screen").page().remove(id); 17 | }); 18 | $(".shake-button").click(function () { 19 | $(".screen").page().shake(); 20 | }); 21 | }); 22 | })(jQuery); 23 | 24 | -------------------------------------------------------------------------------- /sample/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Trivial jQuery Page Sample 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 |
22 |
Page 11
23 | 24 | 25 | 26 |
27 |
28 |
Page 12
29 | 30 | 31 |
32 |
33 |
Page 21
34 | 35 | 36 |
37 |
38 |
Page 22
39 | 40 | 41 |
42 |
43 |
Page XX
44 | 45 |
46 |
47 |
48 |
49 |
50 | 51 | 52 | 53 |
54 | 55 | 56 | --------------------------------------------------------------------------------