diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..70c00f5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..42cfe09 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.idea +.hg +.hgignore +nbproject +node_modules +bower_components diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..e9a8f63 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,19 @@ +{ + "boss": true, + "curly": true, + "eqeqeq": true, + "eqnull": true, + "expr": true, + "immed": true, + "noarg": true, + "onevar": false, + "quotmark": "single", + "smarttabs": true, + "trailing": true, + "unused": true, + "node": true, + "globals": { + "$": true, + "jQuery": true + } +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..20fd86b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.10 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..40053ac --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# Contributing + +Before sending a pull request remember to follow [jQuery Core Style Guide](http://contribute.jquery.org/style-guide/js/). + +1. Fork it! +2. Create your feature branch: `git checkout -b my-new-feature` +3. Make your changes on the `src` folder, never on the `dist` folder. +4. Commit your changes: `git commit -m 'Add some feature'` +5. Push to the branch: `git push origin my-new-feature` +6. Submit a pull request :D diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..fe3b412 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,59 @@ +module.exports = function (grunt) { + + grunt.initConfig({ + + // Import package manifest + pkg: grunt.file.readJSON("bootstrap-autohidingnavbar.jquery.json"), + + // Banner definitions + meta: { + banner: "/*\n" + + " * <%= pkg.title || pkg.name %> - v<%= pkg.version %>\n" + + " * <%= pkg.description %>\n" + + " * <%= pkg.homepage %>\n" + + " *\n" + + " * Made by <%= pkg.author.name %>\n" + + " * Under <%= pkg.licenses[0].type %> License\n" + + " */\n" + }, + + // Concat definitions + concat: { + js: { + src: ["src/jquery.bootstrap-autohidingnavbar.js"], + dest: "dist/jquery.bootstrap-autohidingnavbar.js" + }, + options: { + banner: "<%= meta.banner %>" + } + }, + + // Lint definitions + jshint: { + files: ["src/jquery.bootstrap-autohidingnavbar.js"], + options: { + jshintrc: ".jshintrc" + } + }, + + // Minify definitions + uglify: { + js: { + src: ["dist/jquery.bootstrap-autohidingnavbar.js"], + dest: "dist/jquery.bootstrap-autohidingnavbar.min.js" + }, + options: { + banner: "<%= meta.banner %>" + } + }, + + }); + + grunt.loadNpmTasks("grunt-contrib-concat"); + grunt.loadNpmTasks("grunt-contrib-jshint"); + grunt.loadNpmTasks("grunt-contrib-uglify"); + + grunt.registerTask("default", ["jshint", "concat", "uglify"]); + grunt.registerTask("travis", ["jshint"]); + +}; diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..e9cb086 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,20 @@ +Bootstrap Auto-Hiding Navbar + +An extension for Bootstrap's fixed navbar which hides the navbar while the page is scrolling downwards and shows it the other way. The plugin is able to show/hide the navbar programmatically as well. + +- https://github.com/istvan-meszaros/bootstrap-autohidingnavbar +- http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/ + +Copyright 2014 István Ujj-Mészáros + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3c9d19a --- /dev/null +++ b/README.md @@ -0,0 +1,199 @@ +# Bootstrap Auto-Hiding Navbar [![Build Status](https://secure.travis-ci.org/istvan-ujjmeszaros/bootstrap-autohidingnavbar.png?branch=master)](https://travis-ci.org/istvan-ujjmeszaros/bootstrap-autohidingnavbar) +Bootstrap Auto-Hiding Navbar is an extension for Bootstrap's fixed navbar which hides the navbar while the page is scrolling downwards and shows it the other way. The plugin is able to show/hide the navbar programmatically as well. + +Check the [official website](http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/) for a demo. + +## Usage + +1. Download the latest tag from the [releases page](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/releases) or get it via **bower**: + + ```shell + $ bower install bootstrap-autohidingnavbar + ``` + +2. Include **jQuery** and **Bootstrap**: + + ```html + + + + ``` + +3. Include plugin's code: + + ```html + + ``` + +4. Call the plugin: + + ```javascript + $(".navbar-fixed-top").autoHidingNavbar({ + // see next for specifications + }); + ``` + +## Specifications + +### Initialization parameters object + +When calling `$(".navbar-fixed-top").autoHidingNavbar()` you can pass a parameters object with zero or more of the following: + +- `disableAutohide`, defaults to `false`, set this to `true` if you want to show/hide the navbar programmatically. +- `showOnUpscroll`, defaults to `'true'`, the navbar shows up when scrolling the page upwards (otherwise it shows only when scroll is on page's top). +- `showOnBottom`, defaults to `'true'`, the navbar shows up when scroll reaches the page's end. +- `hideOffset`, defaults to `'auto'`, hides the navbar after scrolling that much pixel. Auto means the navbar's height. +- `animationDuration`, defaults to `'200'`, is the duration of the show and hide animations in milliseconds. + +### Methods + +You can modify the behavior and aspect of the plugin by calling its methods, most of them accepts a `value`. + +To call methods on the auto hiding instance, use the following syntax: + + ```javascript + $(selector).autoHidingNavbar(methodName, parameter); + ``` + +Here are the available methods: + +- `setDisableAutohide(value)` to change the `disableAutohide` parameter. +- `setShowOnUpscroll(value)` to change the `showOnUpscroll` parameter. +- `setShowOnBottom(value)` to change the `showOnBottom` parameter. +- `setHideOffset(value)` to change the `hideOffset` parameter. +- `setAnimationDuration(value)` to change the `animationDuration` parameter. +- `show()` to show the navbar programmatically. +- `hide()` to hide the navbar programmatically. +- `destroy()` destroys the plugin instance. + + +## Structure + +The basic structure of the project is given in the following way: + +``` +├── demo/ +│ └── index.html +├── dist/ +│ ├── jquery.bootstrap-autohidingnavbar.js +│ └── jquery.bootstrap-autohidingnavbar.min.js +├── src/ +│ └── jquery.bootstrap-autohidingnavbar.js +├── .editorconfig +├── .gitignore +├── .jshintrc +├── .travis.yml +├── bootstrap-autohidingnavbar.jquery.json +├── bower.json +├── Gruntfile.js +└── package.json +``` + +#### [demo/](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/demo) + +Contains a simple HTML file to demonstrate the plugin. + +#### [dist/](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/dist) + +This is where the generated files are stored once Grunt runs. + +#### [src/](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/src) + +Contains the source files. + +#### [.editorconfig](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/.editorconfig) + +This file is for unifying the coding style for different editors and IDEs. + +> Check [editorconfig.org](http://editorconfig.org) if you haven't heard about this project yet. + +#### [.gitignore](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/.gitignore) + +List of files that we don't want Git to track. + +> Check this [Git Ignoring Files Guide](https://help.github.com/articles/ignoring-files) for more details. + +#### [.jshintrc](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/.jshintrc) + +List of rules used by JSHint to detect errors and potential problems in JavaScript. + +> Check [jshint.com](http://jshint.com/about/) if you haven't heard about this project yet. + +#### [.travis.yml](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/.travis.yml) + +Definitions for continous integration using Travis. + +> Check [travis-ci.org](http://about.travis-ci.org/) if you haven't heard about this project yet. + +#### [bootstrap-autohidingnavbar.jquery.json](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/bootstrap-autohidingnavbar.jquery.json) + +Package manifest file used to publish plugins in jQuery Plugin Registry. + +> Check this [Package Manifest Guide](http://plugins.jquery.com/docs/package-manifest/) for more details. + +#### [Gruntfile.js](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/Gruntfile.js) + +Contains all automated tasks using Grunt. + +> Check [gruntjs.com](http://gruntjs.com) if you haven't heard about this project yet. + +#### [package.json](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/tree/master/package.json) + +Specify all dependencies loaded via Node.JS. + +> Check [NPM](https://npmjs.org/doc/json.html) for more details. + +## Building + +To build and test the plugin, you need: + +- [**NodeJS**](www.nodejs.org) with **npm** +- **bower** (install it with `npm install bower --g`) +- **grunt-cli** (install it with `npm install grunt-cli --g`) + +Then, `cd` to the project directory and install the required dependencies: + + ```shell + $ npm install + $ bower install + ``` + +To run jshint on the plugin code, call: + + ```shell + $ grunt jshint + ``` + +To build the output js and css files, with the related minified ones, run: + + ```shell + $ grunt + ``` + +## Issues and Contributions + +You can report any issue you may encounter on the [GitHub Issue Tracker](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/issues). + +To contribute, please follow the [contribution guidelines](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/blob/master/CONTRIBUTING.md). + +## History + +Check [Release](https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/releases) list. + +## License + +``` + Copyright 2014 István Ujj-Mészáros + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +``` \ No newline at end of file diff --git a/bootstrap-autohidingnavbar.jquery.json b/bootstrap-autohidingnavbar.jquery.json new file mode 100644 index 0000000..6c76669 --- /dev/null +++ b/bootstrap-autohidingnavbar.jquery.json @@ -0,0 +1,29 @@ +{ + "name": "bootstrap-autohidingnavbar", + "title": "Bootstrap Auto-Hiding Navbar", + "description": "An extension for Bootstrap's fixed navbar which hides the navbar while the page is scrolling downwards and shows it the other way. The plugin is able to show/hide the navbar programmatically as well.", + "keywords": [ + "bootstrap", + "ui", + "navigation" + ], + "version": "1.0.0", + "author": { + "name": "István Ujj-Mészáros", + "url": "https://github.com/istvan-autohidingnavbar" + }, + "licenses": [ + { + "type": "Apache License v2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0" + } + ], + "homepage": "http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/", + "demo": "http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/", + "docs": "http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/", + "download": "https://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar/archive/master.zip", + "dependencies": { + "jquery": ">=1.7", + "bootstrap": ">=3.0.0" + } +} diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..17fa015 --- /dev/null +++ b/bower.json @@ -0,0 +1,25 @@ +{ + "name": "bootstrap-autohidingnavbar", + "version": "1.0.0", + "homepage": "http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/", + "authors": [ + { + "name": "István Ujj-Mészáros", + "url": "https://github.com/istvan-ujjmeszaros" + } + ], + "description": "An extension for Bootstrap's fixed navbar which hides the navbar while the page is scrolling downwards and shows it the other way. The plugin is able to show/hide the navbar programmatically as well.", + "main": "src/jquery.bootstrap-autohidingnavbar.js", + "dependencies": { + "jquery": ">=1.9.0", + "bootstrap": ">=3.0.0" + }, + "keywords": [ + "jquery", + "plugin", + "bootstrap", + "ui", + "navigation" + ], + "license": "Apache License v2.0" +} diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..d30e041 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,88 @@ + + + + + + + + Auto-hiding fixed navbar for Bootstrap + + + + + + + + + + +
+ +

+ Long content... +

+

+ Long content... +

+

+ Long content... +

+

+ Long content... +

+

+ Long content... +

+

+ Long content... +

+ +
+ + + + + + + \ No newline at end of file diff --git a/dist/jquery.bootstrap-autohidingnavbar.js b/dist/jquery.bootstrap-autohidingnavbar.js new file mode 100644 index 0000000..f59d3dc --- /dev/null +++ b/dist/jquery.bootstrap-autohidingnavbar.js @@ -0,0 +1,213 @@ +/* + * Bootstrap Auto-Hiding Navbar - v1.0.0 + * An extension for Bootstrap's fixed navbar which hides the navbar while the page is scrolling downwards and shows it the other way. The plugin is able to show/hide the navbar programmatically as well. + * http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/ + * + * Made by István Ujj-Mészáros + * Under Apache License v2.0 License + */ +;(function($, window, document, undefined) { + var pluginName = 'autoHidingNavbar', + $window = $(window), + $document = $(document), + _scrollThrottleTimer = null, + _resizeThrottleTimer = null, + _throttleDelay = 70, + _lastScrollHandlerRun = 0, + _previousScrollTop = null, + _windowHeight = $window.height(), + _visible = true, + _hideOffset, + defaults = { + disableAutohide: false, + showOnUpscroll: true, + showOnBottom: true, + hideOffset: 'auto', // "auto" means the navbar height + animationDuration: 200 + }; + + function AutoHidingNavbar(element, options) { + this.element = $(element); + this.settings = $.extend({}, defaults, options); + this._defaults = defaults; + this._name = pluginName; + this.init(); + } + + function hide(autoHidingNavbar) { + if (!_visible) { + return; + } + + autoHidingNavbar.element.addClass('navbar-hidden').animate({ + top: -autoHidingNavbar.element.height() + }, { + queue: false, + duration: autoHidingNavbar.settings.animationDuration + }); + + $('.dropdown.open .dropdown-toggle', autoHidingNavbar.element).dropdown('toggle'); + + _visible = false; + } + + function show(autoHidingNavbar) { + if (_visible) { + return; + } + + autoHidingNavbar.element.removeClass('navbar-hidden').animate({ + top: 0 + }, { + queue: false, + duration: autoHidingNavbar.settings.animationDuration + }); + _visible = true; + } + + function detectState(autoHidingNavbar) { + var scrollTop = $window.scrollTop(), + scrollDelta = scrollTop - _previousScrollTop; + + _previousScrollTop = scrollTop; + + if (scrollDelta < 0) { + if (_visible) { + return; + } + + if (autoHidingNavbar.settings.showOnUpscroll || scrollTop <= _hideOffset) { + show(autoHidingNavbar); + } + } + else if (scrollDelta > 0) { + if (!_visible) { + if (autoHidingNavbar.settings.showOnBottom && scrollTop + _windowHeight === $document.height()) { + show(autoHidingNavbar); + } + return; + } + + if (scrollTop >= _hideOffset) { + hide(autoHidingNavbar); + } + } + + } + + function scrollHandler(autoHidingNavbar) { + if (autoHidingNavbar.settings.disableAutohide) { + return; + } + + _lastScrollHandlerRun = new Date().getTime(); + + detectState(autoHidingNavbar); + } + + function bindEvents(autoHidingNavbar) { + $document.on('scroll.' + pluginName, function() { + if (new Date().getTime() - _lastScrollHandlerRun > _throttleDelay) { + scrollHandler(autoHidingNavbar); + } + else { + clearTimeout(_scrollThrottleTimer); + _scrollThrottleTimer = setTimeout(function() { + scrollHandler(autoHidingNavbar); + }, _throttleDelay); + } + }); + + $window.on('resize.' + pluginName, function() { + clearTimeout(_resizeThrottleTimer); + _resizeThrottleTimer = setTimeout(function() { + _windowHeight = $window.height(); + }, _throttleDelay); + }); + } + + function unbindEvents() { + $document.off('.' + pluginName); + + $window.off('.' + pluginName); + } + + AutoHidingNavbar.prototype = { + init: function() { + this.elements = { + navbar: this.element + }; + + this.setDisableAutohide(this.settings.disableAutohide); + this.setShowOnUpscroll(this.settings.showOnUpscroll); + this.setShowOnBottom(this.settings.showOnBottom); + this.setHideOffset(this.settings.hideOffset); + this.setAnimationDuration(this.settings.animationDuration); + + _hideOffset = this.settings.hideOffset === 'auto' ? this.element.height() : this.settings.hideOffset; + bindEvents(this); + + return this.element; + }, + setDisableAutohide: function(value) { + this.settings.disableAutohide = value; + return this.element; + }, + setShowOnUpscroll: function(value) { + this.settings.showOnUpscroll = value; + return this.element; + }, + setShowOnBottom: function(value) { + this.settings.showOnBottom = value; + return this.element; + }, + setHideOffset: function(value) { + this.settings.hideOffset = value; + return this.element; + }, + setAnimationDuration: function(value) { + this.settings.animationDuration = value; + return this.element; + }, + show: function() { + show(this); + return this.element; + }, + hide: function() { + hide(this); + return this.element; + }, + destroy: function() { + unbindEvents(this); + show(this); + $.data(this, 'plugin_' + pluginName, null); + return this.element; + } + }; + + $.fn[pluginName] = function(options) { + var args = arguments; + + if (options === undefined || typeof options === 'object') { + return this.each(function() { + if (!$.data(this, 'plugin_' + pluginName)) { + $.data(this, 'plugin_' + pluginName, new AutoHidingNavbar(this, options)); + } + }); + } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { + var returns; + + this.each(function() { + var instance = $.data(this, 'plugin_' + pluginName); + + if (instance instanceof AutoHidingNavbar && typeof instance[options] === 'function') { + returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1)); + } + }); + + return returns !== undefined ? returns : this; + } + + }; + +})(jQuery, window, document); diff --git a/dist/jquery.bootstrap-autohidingnavbar.min.js b/dist/jquery.bootstrap-autohidingnavbar.min.js new file mode 100644 index 0000000..dba7a79 --- /dev/null +++ b/dist/jquery.bootstrap-autohidingnavbar.min.js @@ -0,0 +1,9 @@ +/* + * Bootstrap Auto-Hiding Navbar - v1.0.0 + * An extension for Bootstrap's fixed navbar which hides the navbar while the page is scrolling downwards and shows it the other way. The plugin is able to show/hide the navbar programmatically as well. + * http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/ + * + * Made by István Ujj-Mészáros + * Under Apache License v2.0 License + */ +!function(a,b,c,d){function e(b,c){this.element=a(b),this.settings=a.extend({},w,c),this._defaults=w,this._name=m,this.init()}function f(b){v&&(b.element.addClass("navbar-hidden").animate({top:-b.element.height()},{queue:!1,duration:b.settings.animationDuration}),a(".dropdown.open .dropdown-toggle",b.element).dropdown("toggle"),v=!1)}function g(a){v||(a.element.removeClass("navbar-hidden").animate({top:0},{queue:!1,duration:a.settings.animationDuration}),v=!0)}function h(a){var b=n.scrollTop(),c=b-t;if(t=b,0>c){if(v)return;(a.settings.showOnUpscroll||l>=b)&&g(a)}else if(c>0){if(!v)return void(a.settings.showOnBottom&&b+u===o.height()&&g(a));b>=l&&f(a)}}function i(a){a.settings.disableAutohide||(s=(new Date).getTime(),h(a))}function j(a){o.on("scroll."+m,function(){(new Date).getTime()-s>r?i(a):(clearTimeout(p),p=setTimeout(function(){i(a)},r))}),n.on("resize."+m,function(){clearTimeout(q),q=setTimeout(function(){u=n.height()},r)})}function k(){o.off("."+m),n.off("."+m)}var l,m="autoHidingNavbar",n=a(b),o=a(c),p=null,q=null,r=70,s=0,t=null,u=n.height(),v=!0,w={disableAutohide:!1,showOnUpscroll:!0,showOnBottom:!0,hideOffset:"auto",animationDuration:200};e.prototype={init:function(){return this.elements={navbar:this.element},this.setDisableAutohide(this.settings.disableAutohide),this.setShowOnUpscroll(this.settings.showOnUpscroll),this.setShowOnBottom(this.settings.showOnBottom),this.setHideOffset(this.settings.hideOffset),this.setAnimationDuration(this.settings.animationDuration),l="auto"===this.settings.hideOffset?this.element.height():this.settings.hideOffset,j(this),this.element},setDisableAutohide:function(a){return this.settings.disableAutohide=a,this.element},setShowOnUpscroll:function(a){return this.settings.showOnUpscroll=a,this.element},setShowOnBottom:function(a){return this.settings.showOnBottom=a,this.element},setHideOffset:function(a){return this.settings.hideOffset=a,this.element},setAnimationDuration:function(a){return this.settings.animationDuration=a,this.element},show:function(){return g(this),this.element},hide:function(){return f(this),this.element},destroy:function(){return k(this),g(this),a.data(this,"plugin_"+m,null),this.element}},a.fn[m]=function(b){var c=arguments;if(b===d||"object"==typeof b)return this.each(function(){a.data(this,"plugin_"+m)||a.data(this,"plugin_"+m,new e(this,b))});if("string"==typeof b&&"_"!==b[0]&&"init"!==b){var f;return this.each(function(){var d=a.data(this,"plugin_"+m);d instanceof e&&"function"==typeof d[b]&&(f=d[b].apply(d,Array.prototype.slice.call(c,1)))}),f!==d?f:this}}}(jQuery,window,document); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..5a6beab --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "bootstrap-autohidingnavbar", + "title": "Bootstrap Auto-Hiding Navbar", + "description": "An extension for Bootstrap's fixed navbar which hides the navbar while the page is scrolling downwards and shows it the other way. The plugin is able to show/hide the navbar programmatically as well.", + "author": { + "name": "István Ujj-Mészáros", + "url": "https://github.com/istvan-ujjmeszaros" + }, + "contributors": [ + ], + "repository": { + "type": "git", + "url": "http://github.com/istvan-ujjmeszaros/bootstrap-autohidingnavbar.git" + }, + "homepage": "http://www.virtuosoft.eu/code/bootstrap-autohidingnavbar/", + "version": "1.0.0", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-cli": "~0.1.13", + "grunt-contrib-jshint": "~0.8.0", + "grunt-contrib-concat": "~0.3.0", + "grunt-contrib-uglify": "~0.3.2", + "grunt-contrib-cssmin": "~0.9.0" + }, + "scripts": { + "test": "grunt travis --verbose" + } +} diff --git a/src/jquery.bootstrap-autohidingnavbar.js b/src/jquery.bootstrap-autohidingnavbar.js new file mode 100644 index 0000000..cef93b8 --- /dev/null +++ b/src/jquery.bootstrap-autohidingnavbar.js @@ -0,0 +1,205 @@ +;(function($, window, document, undefined) { + var pluginName = 'autoHidingNavbar', + $window = $(window), + $document = $(document), + _scrollThrottleTimer = null, + _resizeThrottleTimer = null, + _throttleDelay = 70, + _lastScrollHandlerRun = 0, + _previousScrollTop = null, + _windowHeight = $window.height(), + _visible = true, + _hideOffset, + defaults = { + disableAutohide: false, + showOnUpscroll: true, + showOnBottom: true, + hideOffset: 'auto', // "auto" means the navbar height + animationDuration: 200 + }; + + function AutoHidingNavbar(element, options) { + this.element = $(element); + this.settings = $.extend({}, defaults, options); + this._defaults = defaults; + this._name = pluginName; + this.init(); + } + + function hide(autoHidingNavbar) { + if (!_visible) { + return; + } + + autoHidingNavbar.element.addClass('navbar-hidden').animate({ + top: -autoHidingNavbar.element.height() + }, { + queue: false, + duration: autoHidingNavbar.settings.animationDuration + }); + + $('.dropdown.open .dropdown-toggle', autoHidingNavbar.element).dropdown('toggle'); + + _visible = false; + } + + function show(autoHidingNavbar) { + if (_visible) { + return; + } + + autoHidingNavbar.element.removeClass('navbar-hidden').animate({ + top: 0 + }, { + queue: false, + duration: autoHidingNavbar.settings.animationDuration + }); + _visible = true; + } + + function detectState(autoHidingNavbar) { + var scrollTop = $window.scrollTop(), + scrollDelta = scrollTop - _previousScrollTop; + + _previousScrollTop = scrollTop; + + if (scrollDelta < 0) { + if (_visible) { + return; + } + + if (autoHidingNavbar.settings.showOnUpscroll || scrollTop <= _hideOffset) { + show(autoHidingNavbar); + } + } + else if (scrollDelta > 0) { + if (!_visible) { + if (autoHidingNavbar.settings.showOnBottom && scrollTop + _windowHeight === $document.height()) { + show(autoHidingNavbar); + } + return; + } + + if (scrollTop >= _hideOffset) { + hide(autoHidingNavbar); + } + } + + } + + function scrollHandler(autoHidingNavbar) { + if (autoHidingNavbar.settings.disableAutohide) { + return; + } + + _lastScrollHandlerRun = new Date().getTime(); + + detectState(autoHidingNavbar); + } + + function bindEvents(autoHidingNavbar) { + $document.on('scroll.' + pluginName, function() { + if (new Date().getTime() - _lastScrollHandlerRun > _throttleDelay) { + scrollHandler(autoHidingNavbar); + } + else { + clearTimeout(_scrollThrottleTimer); + _scrollThrottleTimer = setTimeout(function() { + scrollHandler(autoHidingNavbar); + }, _throttleDelay); + } + }); + + $window.on('resize.' + pluginName, function() { + clearTimeout(_resizeThrottleTimer); + _resizeThrottleTimer = setTimeout(function() { + _windowHeight = $window.height(); + }, _throttleDelay); + }); + } + + function unbindEvents() { + $document.off('.' + pluginName); + + $window.off('.' + pluginName); + } + + AutoHidingNavbar.prototype = { + init: function() { + this.elements = { + navbar: this.element + }; + + this.setDisableAutohide(this.settings.disableAutohide); + this.setShowOnUpscroll(this.settings.showOnUpscroll); + this.setShowOnBottom(this.settings.showOnBottom); + this.setHideOffset(this.settings.hideOffset); + this.setAnimationDuration(this.settings.animationDuration); + + _hideOffset = this.settings.hideOffset === 'auto' ? this.element.height() : this.settings.hideOffset; + bindEvents(this); + + return this.element; + }, + setDisableAutohide: function(value) { + this.settings.disableAutohide = value; + return this.element; + }, + setShowOnUpscroll: function(value) { + this.settings.showOnUpscroll = value; + return this.element; + }, + setShowOnBottom: function(value) { + this.settings.showOnBottom = value; + return this.element; + }, + setHideOffset: function(value) { + this.settings.hideOffset = value; + return this.element; + }, + setAnimationDuration: function(value) { + this.settings.animationDuration = value; + return this.element; + }, + show: function() { + show(this); + return this.element; + }, + hide: function() { + hide(this); + return this.element; + }, + destroy: function() { + unbindEvents(this); + show(this); + $.data(this, 'plugin_' + pluginName, null); + return this.element; + } + }; + + $.fn[pluginName] = function(options) { + var args = arguments; + + if (options === undefined || typeof options === 'object') { + return this.each(function() { + if (!$.data(this, 'plugin_' + pluginName)) { + $.data(this, 'plugin_' + pluginName, new AutoHidingNavbar(this, options)); + } + }); + } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') { + var returns; + + this.each(function() { + var instance = $.data(this, 'plugin_' + pluginName); + + if (instance instanceof AutoHidingNavbar && typeof instance[options] === 'function') { + returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1)); + } + }); + + return returns !== undefined ? returns : this; + } + + }; + +})(jQuery, window, document);