Igor Simic
3 years ago

Angular autohide navigation directive (show hide toolbar on scroll)


Auto hide/show navigation or toolbar on scroll is a popular feature especially when it comes to small screens. In angularJS 1.x this can be done with directive. So in order to show - hide toolbar on page scroll down or up we can do this:

In this case we are using material design built in toolbar and directive named hideShowToolbar is assigned to id:

<md-content layout="column" layout-fill id="main-content"> 
     <md-toolbar hide-show-toolbar layout="row" layout-wrap toolbar="main" class="md-theme-indigo">
          <!--... some toolbar elements-->
     </md-toolbar> 
</md-content>

The directive for auto hide toolbar on element scroll will look like this:
	app.directive('hideShowToolbar',['$rootScope','$window',function($rootScope,$window){

		return {

			restrict:'AE',
			link:function(scope, element, attr){ 

				// get element which will be scrolled
 				var scrollParent = angular.element(document.querySelector('md-content[md-scroll-y]'));

 				// set var for last scroll and ofset
				var lastScroll = 0;
				var offset = 15;

				// get toolbar height
				var toolbarHeight = element[0].clientHeight;
 

				// move content from top for toolbar height
				scrollParent[0].style.paddingTop = toolbarHeight+'px';


 				// add class with css styles to tollbar
					element.addClass("hideShowToolbar");

				// on parent scroll call fn to show/hide toolbar
				scrollParent.on('scroll', function(){

					setTimeout(function() {

						showHideToolbar();

					}, 250);

				});


				function showHideToolbar(){

					// get scroll pos
					var scrollNum = Math.round(scrollParent[0].scrollTop); 

					//exit if it is less than ofset (delay)
					if(Math.abs(lastScroll - scrollNum) <= offset){
         				return;
					}

					// add remove class for scrolling
						if (scrollNum > lastScroll && scrollNum > toolbarHeight){
	  
							if(!element.hasClass("hideToolbar")){

								element.removeClass("showToolbar");
								element.addClass("hideToolbar");
	  
							}

						}else{

							if(!element.hasClass("showToolbar")){

								element.removeClass("hideToolbar");
								element.addClass("showToolbar");

							}

						}
					// set lastScroll to last scroll number
					lastScroll = scrollNum;
				}

			}

		}


	}]);


In case you are using window scroll try this directive:
app.directive('hideShowToolbar',['$rootScope','$window','$timeout',function($rootScope,$window,$timeout){

		return {

			restrict:'AE',
			link:function(scope, element, attr){ 

				$timeout(function(){

					// get element which will be scrolled 
	 				var contentEl = angular.element(document.querySelector('.wrapper-element'));
 
	 				// set var for last scroll and ofset
					var lastScroll = 0;
					var offset = 15;

					// get toolbar height
					var toolbarHeight = element[0].clientHeight; 
	 
					// move content from top for toolbar height
					//contentEl[0].style.paddingTop = toolbarHeight+'px';
					document.getElementById("main-content").style.paddingTop  = toolbarHeight+'px';

	 				// add class with css styles to tollbar
						element.addClass("hideShowToolbar");

					// on windows scroll

 					window.onscroll = function() { 
 	 					showHideToolbar();
 	 				};
 

					function showHideToolbar(){
	 
						// get scroll pos
 						var scrollNum = window.scrollY;

						//exit if it is less than ofset (delay)
						if(Math.abs(lastScroll - scrollNum) <= offset){
	         				return;
						}

						// add remove class for scrolling
							if (scrollNum > lastScroll && scrollNum > toolbarHeight){
		  
								if(!element.hasClass("hideToolbar")){

									element.removeClass("showToolbar");
									element.addClass("hideToolbar");
		  
								}

							}else{

								if(!element.hasClass("showToolbar")){

									element.removeClass("hideToolbar");
									element.addClass("showToolbar");

								}

							}
						// set lastScroll to last scroll number
						lastScroll = scrollNum;
					}
				});


			}

		}


	}]);


And css will be used only to use animation for moving down/up navigation bar:
	.hideShowToolbar{
		-webkit-transition: all .5s ease-in-out !important;
		-moz-transition: all .5s ease-in-out !important;
		-o-transition: all .5s ease-in-out !important;
		transition: all .5s ease-in-out !important;
		position: fixed;
		top:0px;
	} 

	.hideToolbar {
 		-webkit-transform: translateY(-100%);
		-ms-transform: translateY(-100%);
		-o-transform: translateY(-100%);
		transform: translateY(-100%);
	}

	.showToolbar{
		-webkit-transform: translateY(0%);
		-ms-transform: translateY(0%);
		-o-transform: translateY(0%);
		transform: translateY(0%);
	}