jQuery cơ bản – Hướng dẫn xây dựng module Header accordion

Điểm bài viết
[Tổng cộng: 0 Trung bình: 0]

Share vì hữu ích

Sử dụng Header với menu nhiều lớp cần xử lý tinh tế trong UX và là câu hỏi được nhiều lập trình viên quan tâm. Trong bài viết này, tôi xin hướng dẫn các bạn cách thức thực hiện gọn gàng và dễ nhìn nhất.

Header Accordion là gì?

“Accordion” là tính năng cho phép đóng mở nội dung ẩn của một khu vực. Khi nhấp vào một item trong danh sách, nó sẽ mở ra phần nội dung bên dưới.

Module Accordion

Accordion có ứng dụng rộng rãi trong nhiều phần của website, nhưng phổ biến nhất là sử dụng làm module FAQ (Câu hỏi thường gặp).

Trong bài viết này, ta sẽ thử ứng dụng module Accordion này vào làm một việc khác: sử dụng trong Header ở trạng thái trên mobile.

Bài toán Header chứa Accordion

Ta có những dữ liệu cụ thể như sau:

Khách hàng sử dụng website WordPress, trong đó chức năng menu là sử dụng hoàn toàn tính năng built-in của WordPress.

Trên khung màn hình máy tính, khách hàng muốn hover chuột là hiện ra sub-menu phụ.

Trạng thái sub-menu khi hover

Trên màn hình mobile, thay vì hover, người dùng phải nhấp chuột vào item cha để hiện ra các sub-menu con.

Mô hình Header Accordion trên mobile

Vì đây là một bài toán cơ bản, nhưng do tính chất cần tiếp cận với số đông lập trình viên có thói quen sử dụng jQuery, ta sẽ mô phỏng lại bằng cách giữ jQuery của WordPress và cập nhật cho nó hoạt động.

Tạo markup PHP kết hợp BEM Class

Cấu trúc markup của tôi thực ra rất đơn giản, kết hợp đặt tên class theo BEM:

Tiếp đến, tôi cần tạo một lớp menu trong backend chứa sub-menu như trong hình:

Thêm menu có chứa sub-menu trong WordPress

Lưu ý, để thêm vào đúng menu, bạn còn cần bước đăng ký menu trong functions.php như register_nav_menus của theme Twenty Seventeen nhé.

Markup khi tạo ra có thể sẽ như thế này:

<header class="header" data-module-init="header">
  <div class="header__wrapper">
    <nav class="header__nav">
      <ul class="header__menu">
        <li class="menu-item"><a href="a/demo/1">First Item</a></li>
        <li class="menu-item menu-item-has-children">
          <a href="a/demo/2">Second Item</a>
          <ul class="sub-menu">
            <li class="menu-item">
              <a href="a/demo/3">First Sub Item</a>
            </li>
          </ul>
        </li>
      </ul>
    </nav>
  </div>
</header>

Khởi tạo module Javascript

Giờ, sau khi ta đã có markup, ta cần define những gì sẽ xảy ra trong Javascript. Hãy bắt đầu bằng cấp dấu để load trong jQuery quen thuộc:

$(function() {
 // Module sẽ làm việc trong này
});

Ta thực thi các phần gọi tới jQuery object ta cần:

var t = this;
t.$header = $('[data-module-init="header"]');
t.$parentMenuItems = t.$header.find('.menu-item-has-children'); // class này do WordPress tạo ra
t.$headerBreakpoint = 1024;

Tiếp đến, ta thực hiện loop để với mỗi item chứa sub-menu thì sẽ click vào link a đầu tiên.

for(var i = 0; i < t.$parentMenuItems.length; i++) {
 // Đây là link <a> đầu tiên chứ không phải link a trong các sub-menu
 var $trigger = $(t.$parentMenuItems[i]).children().first(); // <a> element
 // Bình tĩnh kiểm tra xem có tồn tại không đã
 if($trigger.length > 0) {
  $trigger.on('click', function (e) {
   // Mỗi khi click, kiểm tra breakpoint xem có nhỏ hơn trên khung tablet/mobule không
   if( $(window).width() <= t.$headerBreakpoint ) {
    // OK, giờ bạn cần tắt không cho click vào link parent
    e.preventDefault();
    // Bạn tìm ngược ra thằng <li> và cho toggle class của mình
    $(this).parent().toggleClass('menu-item--opened');
    // Sau đó vào thằng sub-menu nằm bên cạnh để đẩy cho hiện ra
    $(this).next('.sub-menu').slideToggle();
   }
  });
 }
}

Bạn có hiểu đoạn code ở trên không? Tôi nghĩ nó lý giải khá rõ ràng những gì bạn sẽ làm. Nhưng hãy lưu ý, bạn cần test với những gì bạn viết ra, chứ đừng copy-paste nhé.

Thêm style cho module Header Accordion

Phần style của menu ta sẽ không bàn chi tiết ở đây, gợi ý về cách viết như sau cho các class bạn sẽ sử dụng:

.header__menu {}
.header__menu > .menu-item-has-children {}
.header__menu > .menu-item-has-children > a {}
.header__menu > .menu-item-has-children:hover {}
/** Trạng thái khi menu được hiển thị ra **/
.header__menu > .menu-item-has-children.menu-item--opened {}

Nếu bạn cần thêm hướng dẫn, đừng ngại đặt câu hỏi nhé.

Share vì hữu ích

Điện thoại Apple mua tại FptShop

About Khôi 'Pro' Nguyễn

Technical Lead tại Solis Lab. Quản lý ngôn ngữ tại vi.wordpress.org.

View all posts by Khôi 'Pro' Nguyễn →

Trả lời