01/10/2018, 16:45

Làm menu ẩn hiện khi scroll bằng JQuery - Headroom

Có thể nói rằng menu là một thành phần không thể thiếu được trong một Website, nó điều hướng người dùng, giúp người dùng di chuyển giữa các mục khác nhau. Hiện nay có rất nhiều cách thể hiện phong cách cũng như vị trí đặt menu, nhưng thông dụng nhất là dạng menu nằm ngang. Khi người dùng scroll, ...

Có thể nói rằng menu là một thành phần không thể thiếu được trong một Website, nó điều hướng người dùng, giúp người dùng di chuyển giữa các mục khác nhau. Hiện nay có rất nhiều cách thể hiện phong cách cũng như vị trí đặt menu, nhưng thông dụng nhất là dạng menu nằm ngang. Khi người dùng scroll, thì menu có thể scroll theo ( fixed ) hoặc sẽ trôi lên phía trên.

Theo xu hướng hiện này fixed menu khá là được ưa chuộng vì lúc nào nó cũng hiển thị lên viewport của người dùng. Trong một vài trường hợp nó không được hợp lý cho lắm. Khi người dùng không quan tâm tới các mục hiện có trên menu, các liên kết trên menu hướng về những trang nội dung quá khác nhau, hoặc khi menu có quá nhiều liên kết, phức tạp. Đối với những menu như vậy, nếu fixed thì sẽ gây khó chịu cho người dùng.

Có một cách khắc phục được yếu điểm hay những bất tiện phía trên đó là khi người dùng scroll chuột xuống(down) thì menu của bạn sẽ bị ẩn đi đồng thời nếu người dụng scroll chuột nên(up) thì menu của bạn sẽ được hiện ra.

Thì hiện nay có một thư viện đã được xây dựng sẵn nó khá gọn nhẹ giúp bạn xây dựng sự kiện này đó là Headroom.JS. Bạn có thể download và nhúng thư viện vào ứng dụng của bạn tại trang GibHub của tác giả. https://github.com/WickyNilliams/headroom.js

Thư viện này được viết độc lập, không đòi hỏi thêm thư viện nào khác như jQuery, vì vậy bạn có thể sử dụng riêng một mình nó, nhưng bạn cũng có thể dùng chung với jQuery, Zepto và Angular.

Viên đầu tiên bạn cần nhúng thư viện của HeadroomJS vào ứng dụng của bạn.

Thư viện Javascript.

<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/headroom/0.7.0/jQuery.headroom.min.js"></script>
Mã HTML.

<nav id="header" class="headroom menu">
    ....
</nav>

Mã CSS.

Đầu tiên bạn nên làm cho .headroom fixed và một vài thuộc tính về transition :

.headroom {
    position: fixed;
    z-index: 9998;
    top: 0;
    left: 0;
    right: 0;
 
    -webkit-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-timing-function: ease-in-out;
    animation-timing-function: ease-in-out;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
}

Ta cần định nghĩa hiệu ứng khi scroll up/down. HeadroomJs sẽ thêm class headroom--pinned khi menu hiện ra, và headroom--unpinned khi menu ẩn, nên ta sẽ làm hiệu ứng cho nó như sau :

.headroom--unpinned {
    top: -80px;
    -webkit-transition: .25s;
    -o-transition: .25s;
    -moz-transition: .25s;
    -ms-transition: .25s;
    transition: .25s;
    -webkit-transform: translateY(-80px);
    -o-transform: translateY(-80px);
    -moz-transform: translateY(-80px);
    -ms-transform: translateY(-80px);
    transform: translateY(-80px);
}
.headroom--pinned {
    top: 0;
    transition-timing-function: cubic-bezier(0.64, 0.57, 0.67, 1.53);
 
    -webkit-transition: .5s;
    -o-transition: .5s;
    -moz-transition: .5s;
    -ms-transition: .5s;
    transition: .5s;
}

Mã Javascript:

(function ($) {
   $(function () {
       $("#header").headroom({
           // vertical offset in px before element is first unpinned
           offset : 100,
           // or you can specify tolerance individually for up/down scroll
           tolerance : {
               up : 20,
               down : 20
           },           classes : {               // when element is initialised
               initial : "headroom",
               // when scrolling up
               pinned : "headroom--pinned",
               // when scrolling down
               unpinned : "headroom--unpinned",
           }
       });
   }); // end of document ready
})(jQuery); // end of jQuery name space

Trong đó:

  • offset : nếu số pixel scroll từ top của trang nhỏ hơn offset, thì sẽ không ẩn navbar.
  • tolerance : Số số pixel trong một lần scroll lớn hơn tolerance thì sẽ ẩn/hiện.
  • classes : các class mà bạn muốn thêm vào khi show/hide
    • initial : khi khởi tạo
    • pinned : khi được hiện ra
    • unpinned : khi bị ẩn đi
    • top : khi nằm trong vùng offset
    • notTop : khi ngoài vùng offset

Nhưng có một lý do là đôi khi bạn nhúng cái thư viện đó vào website của bạn nó không có chạy mặc dù bạn đã tải và nhúng file  Debouncer.js vào. 

Mình sẽ hướng dẫn các bạn xây dựng sự kiện này sử dụng JQuery.

Trong bài viết này mình sử dụng JQuery và boostrap nên bạn cần nhúng hai thư viện này vào website của bạn.

<link rel="stylesheet" type="text/css" href="/isocms/skin/css/bootstrap.min.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

1. Mã HTML

Bạn xây dựng một mã HTML đơn giản như sau.

<div class="navbar navbar-inverse headroom" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <a href="/" title="Học lập trình Online | Chia sẻ lập trình PHP">
                <img src="/isocms/skin/images/chiasephp_logo_tryit.png" alt="{$PAGE_NAME}" />
            </a>
        </div>
        <ul class="nav navbar-nav navbar-right">
            <li><a href="http://ouo.io/7ZnRkb">Download</a> </li>
            <li><a href="/c129d129-lam-menu-an-hien-khi-scroll-bang-jquery.html">Tutorial</a> </li>
        </ul>
    </div>
</div>

2. Mã Javascript

Mã 

$(function () {
	$('.headroom').each(function () {
		var $doc = $(document)
		, $win = $(window)
		, $self = $(this)
		
		, $sHeight = $self.outerHeight(false)
		, isHidden = false
		, lastScrollTop = 0
		/* Sự kiện lúc người dùng scroll chuột */
		$win.on('scroll', function () {
			var scrollTop = $doc.scrollTop()
			var offset = scrollTop - lastScrollTop
			lastScrollTop = scrollTop
			
			// min-offset, min-scroll-top
			if (offset > 10 && scrollTop > $sHeight ) {
				if (!isHidden) {
					/* Thêm class làm ẩn menu */
					$self.addClass('headroom-pinned')
					isHidden = true
				}
			} else if (offset < -10 || scrollTop < $sHeight) {
				if (isHidden) {
					/* Gõ bỏ class làm ẩn menu */
					$self.removeClass('headroom-pinned')
					isHidden = false
				}
			}
		});
	});
});

Trên đây là những đoạn mã cũng khá là đơn giản nên mình không giải thích thì thêm.

Lưu ý: Đối tượng để trigger sự kiện này là những phần tử HTML có class là headroom và trong css bạn cần khai báo css cho class .headroom và như sau .headroom-pinned

.headroom {
	position: fixed;
	top: 0;
	transition: top 0.15s;
	-webkit-transition: top 0.15s;
	-moz-transition: top 0.15s;
	-o-transition: top 0.15s;
	-ms-transition: top 0.15s;
}
.headroom-pinned {
	top: -61px;
}

3. CSS

body {
	font-family:Arial, Helvetica, sans-serif;
	font-size:14px;
	padding-top:81px;
}
.navbar-inverse {
	background:#fafafa;
	awidth:100%;
	border-bottom:1px solid #e9e9e9;
	margin-bottom:20px;
	padding:0;
	z-index:99;
}
.navbar-inverse:after,  .navbar-inverse:before {
	display:table;
	clear:both;
	content:"";
}
.navbar-header {
	display:inline-block;
	float:left;
	padding:10px 20px 10px 0px;
}
.navbar-right {
	float:right;
}
.navbar-nav > li {
	float:left;
}
.navbar-inverse .navbar-nav li:first-child a {
	border-left: 1px solid #e9e9e9;
}
.navbar-inverse .navbar-nav > li > a {
	border-right: 1px solid #e9e9e9;
	color: #555;
	font-weight: 700;
}
.navbar-collapse ul li a {
	text-transform: uppercase;
}
.navbar-nav > li > a {
	padding-top: 15px;
	padding-bottom: 15px;
}
.navbar-nav > li > a {
	padding-top: 10px;
	padding-bottom: 10px;
	line-height: 20px;
}
.nav > li > a {
	position: relative;
	display: block;
	padding: 20px 15px;
	text-transform:uppercase;
}
.list-group {
	margin-bottom:15px;
}
.headroom {
	position: fixed;
	top: 0;
	transition: top 0.15s;
	-webkit-transition: top 0.15s;
	-moz-transition: top 0.15s;
	-o-transition: top 0.15s;
	-ms-transition: top 0.15s;
}
.headroom-pinned {
	top: -61px;
}

4. Tổng kết

Trong xu hướng phá triển website ngày nay ngày càng tiến tới sự đơn giả. Chính vì điều đó người ta gần như lược bỏ đi sự phức tạp mang tính chất đánh đố người dùng. Làm menu ẩn hiện khi scroll - Headroom làm tăng diện tích màn hình và sự tiện ích cho người dùng duyệt web.

0