Search…

Tạo Menu Trượt Theo Khung Nhìn Trên Web

29/07/20204 min read
Tạo menu hoặc các phần tử có thể trượt theo thanh trượt của trình duyệt khi menu chạm đến đỉnh của trình duyệt web với thuần JavaScript.

Tạo menu hoặc các đối tượng có thể trôi dọc theo đỉnh của trình duyệt web (Affix) có thể dừng lại ở đỉnh đã cấu hình.

Outline bài viết trượt theo trình duyệt

Tính ứng dụng

  • Menu outline bài viết.
  • Quảng cáo trượt theo trình duyệt.
  • Các thành phần cần trượt khác.

Môi trường và các công cụ

Có thể sử dụng JavaScript hoặc JQuery, trong bài viết sử dụng JQuery.

Hướng dẫn

Tạo khung và nội dung (HTML + CSS)

Thiết kế layout bằng hình vẽ

Ta cần 3 thành phần chính để có thể tạo nên tính năng này (pipe, anchor, content).

tao-menu-truot-theo-khung-nhin-tren-web
  • anchor: phần tử để lấy tọa độ khởi đầu của phần tử NỘI DUNG.
  • content: phần tử chứa NỘI DUNG, trượt trên pipe.
  • pipe: "đường sống để NỘI DUNG trượt trên nó.

CSS code

Ta cần định nghĩa 3 class pipe, anchor và content và lưu ý là pipe sẽ chứa anchor và content.

.pipe{
	width:150px;
	height:1500px;
	padding:5px;
	float:left;
	background:#f0f0f0;
}

.pipe .anchor{
	width:150px;
	height:10px;
	float:left;
	background:#00aadd;
}

.pipe .content{
	width:150px;
	height:100px;
	float:left;
	top:0;
	background:#ffbb33;
}

HTML code và CSS code

<!DOCTYPE html>
<html> <head> <title>STDIO.VN</title> <style> .pipe{ width:150px; height:1500px; padding:5px; float:left; background:#f0f0f0; } .pipe .anchor{ width:150px; height:10px; float:left; background:#00aadd; } .pipe .content{ width:150px; height:100px; float:left; top:0; background:#ffbb33; } </style> </head> <body> <div class="pipe"> <div class="anchor"></div> <div class="content"> NỘI DUNG </div> </div> </body> </html>

Giải thích

  • pipe class: dùng để chứa đựng content, nó tạo ra một cái ống thẳng đứng, giúp cho content trượt dài trên nó.
  • content class: nội dung, có thể là outline, cũng có thể là hình hoặc quảng cáo.
  • anchor class:
    • Phần tử này không phải là phần tử chính, nhưng dùng nó để đánh dấu điểm đầu, nằm sát phía trên đỉnh của content, tồn tại để lưu trữ tọa độ khởi tạo của content vì trong quá trình trượt, content sẽ thay đổi tọa độ và mất đi tọa độ đầu.
    • Đây không phải là cách duy nhất, có thể dùng <input type="hidden" /> hoặc sessionStorage lưu trữ tọa độ này, tuy nhiên, code sẽ rối. Ngoài ra có thể dùng HTML5 với Local Storage cũng có thể làm được điều này. Nhưng tôi vẫn thích cách này hơn, đơn giản là vì tôi nghĩ ra nó. Thuộc tính height nên sử dụng là 1px thay vì 10px, và background color nên để là trong suốt, vì nó không phải là content chính nên không cần render (tôi để thông số lớn là để các bạn dễ theo dõi).

JQuery xử lý di chuyển

Ý tưởng

Ý tưởng để thực hiện việc di chuyển này là ta sẽ chuyển thuộc tính position của content trở thành fixed khi mà tọa độ đỉnh trình duyệt chạm anchor (hay hiểu là tọa độ đỉnh của content), lúc này content sẽ phụ thuộc vào tọa độ top của nó (trường hợp này ta cho giá trị là 0 để "chạm đỉnh" trình duyệt). Ngược lại, khi đỉnh trình duyệt cao hơn tọa độ đỉnh của content, thì ta sẽ chuyển thuộc tính position của content trở về relative, lúc này tọa độ của content sẽ được cố định lại tại vị trí khởi đầu của nó.

Nếu ngay từ đầu ta cho content class có thuộc tính này thì dù đỉnh trình duyệt chưa chạm vào anchor (hay tọa độ ban đầu của content) thì content đã chạm đỉnh trình duyệt.

Hiện thực

Ta cần truy cập vào 2 phần tử là anchor và content, do đó, ta sẽ gán id cho 2 phần tử này (id_anchor và id_content). Vậy ta có codes sau.

<!DOCTYPE html>
<html> <head> <title>STDIO.VN</title> <style> *{font-family:"Segoe UI",Arial,Helvetica,sans-serif;text-align:center;color:#fff} .pipe{ width:150px; height:1500px; padding:5px; float:left; background:#f0f0f0; } .pipe .anchor{ width:150px; height:10px; float:left; background:#00aadd; } .pipe .content{ width:150px; height:100px; float:left; top:0; background:#ffbb33; } </style> </head> <body> <div class="pipe"> <div class="anchor" id="id_anchor"></div> <div class="content" id="id_content"> NỘI DUNG </div> </div> </body> </html>

Hiện thực phần thay đổi thuộc tính position của content.

  • Thêm thư viện JQuery, đăng ký việc xử lý việc cuộn lên xuống trong sự kiện ready.
  • Khi tọa độ đạt ngưỡng cao hơn tọa độ ban đầu chuyển về position: relative và ngược lại là position: fixed.
<!DOCTYPE html>
<html> <head> <title>STDIO.VN</title> <style> .pipe{ width:150px; height:1500px; padding:5px; float:left; background:#f0f0f0; } .pipe .anchor{ width:150px; height:10px; float:left; background:#00aadd; } .pipe .content{ width:150px; height:100px; float:left; top:0; background:#ffbb33; } </style> <script type="text/javascript" src="jquery-2.1.1.min.js"></script> <script> $(document).ready(function(){ $(window).scroll(function(){ if($(window).scrollTop() - $("#id_anchor").position().top < 0){ $('#id_content').css({'position':'relative'}); }else{ $('#id_content').css({'position':'fixed'}); } }); }); </script> </head> <body> <div class="pipe"> <div class="anchor" id="id_anchor"></div> <div class="content" id="id_content"> NỘI DUNG </div> </div> </body> </html>

Download demo hoàn chỉnh

ProjectDemo.zip

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024