Bài 8. Thành phần JavaScript: modal, collapse, offcanvas, toast, carousel

Bootstrap có sẵn các thành phần tương tác chỉ cần thuộc tính data-bs-*: hộp thoại (modal), accordion, menu trượt (offcanvas), thông báo nổi (toast), tooltip, popover, tab và carousel. Bài này học cách dùng bằng HTML và điều khiển bằng JavaScript khi cần.

60 phútTrung cấp
Bạn sẽ học được
  • Dùng modal và offcanvas
  • Tạo accordion và collapse
  • Kích hoạt tooltip, popover, toast
  • Điều khiển thành phần bằng API JavaScript và sự kiện
Thuật ngữ cần biết
data-bs-toggle
Thuộc tính khai báo loại thành phần cần mở.
data-bs-target
Bộ chọn (thường là #id) của phần tử bị điều khiển.
Instance
Đối tượng JS của thành phần: bootstrap.Modal.getOrCreateInstance(el).

Một số khái niệm

Mọi thành phần JS cần tệp bootstrap.bundle.min.js. Cách 1 (khai báo): thêm data-bs-toggle và data-bs-target vào nút. Cách 2 (lập trình): new bootstrap.Modal('#hop').show(). Tooltip, popover, toast cần khởi tạo bằng JavaScript vì lý do hiệu năng.

Modal và offcanvas

<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#hop">Mở hộp thoại</button>
<button class="btn btn-outline-dark" data-bs-toggle="offcanvas" data-bs-target="#ben">Mở menu trượt</button>
<div class="modal fade" id="hop" tabindex="-1"><div class="modal-dialog modal-dialog-centered"><div class="modal-content">
  <div class="modal-header"><h5 class="modal-title">Xác nhận nộp bài</h5><button class="btn-close" data-bs-dismiss="modal"></button></div>
  <div class="modal-body">Bạn chắc chắn muốn nộp bài? Sau khi nộp không sửa được.</div>
  <div class="modal-footer"><button class="btn btn-secondary" data-bs-dismiss="modal">Hủy</button><button class="btn btn-success">Nộp bài</button></div>
</div></div></div>
<div class="offcanvas offcanvas-start" id="ben" style="width:240px"><div class="offcanvas-header"><h5>Nội dung loạt bài</h5><button class="btn-close" data-bs-dismiss="offcanvas"></button></div>
<div class="offcanvas-body"><div class="list-group list-group-flush"><a class="list-group-item" href="#">Bài 1</a><a class="list-group-item active" href="#">Bài 2</a><a class="list-group-item" href="#">Bài 3</a></div></div></div>
Kết quả hiển thị

Offcanvas là cách Tự Học Tin đưa danh sách bài vào menu trượt trên điện thoại.

Accordion (câu hỏi thường gặp)

<div class="accordion" id="faq">
  <div class="accordion-item"><h2 class="accordion-header"><button class="accordion-button" data-bs-toggle="collapse" data-bs-target="#c1">Bootstrap có miễn phí không?</button></h2>
    <div id="c1" class="accordion-collapse collapse show" data-bs-parent="#faq"><div class="accordion-body">Có, mã nguồn mở theo giấy phép MIT.</div></div></div>
  <div class="accordion-item"><h2 class="accordion-header"><button class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#c2">Có cần biết CSS không?</button></h2>
    <div id="c2" class="accordion-collapse collapse" data-bs-parent="#faq"><div class="accordion-body">Nên biết CSS cơ bản để tùy biến khi cần.</div></div></div>
</div>
Kết quả hiển thị

Tooltip, popover, toast (cần khởi tạo)

<button class="btn btn-outline-success" data-bs-toggle="tooltip" data-bs-title="Lưu bản nháp">Lưu</button>
<button class="btn btn-outline-primary" data-bs-toggle="popover" data-bs-title="Gợi ý" data-bs-content="Dùng col-md-6 để chia đôi.">Gợi ý</button>
<button class="btn btn-success" id="nutToast">Hiện thông báo</button>
<div class="toast-container position-fixed bottom-0 end-0 p-2"><div id="tb" class="toast text-bg-success"><div class="d-flex"><div class="toast-body">Đã lưu thành công!</div><button class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button></div></div></div>
<script>
document.addEventListener('DOMContentLoaded', () => {
  document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => new bootstrap.Tooltip(el));
  document.querySelectorAll('[data-bs-toggle="popover"]').forEach(el => new bootstrap.Popover(el));
  document.getElementById('nutToast').onclick = () => bootstrap.Toast.getOrCreateInstance('#tb').show();
});
</script>
Kết quả hiển thị
// Lắng nghe sự kiện thành phần
document.getElementById('hop').addEventListener('hidden.bs.modal', () => console.log('Đã đóng'));
Mẹo hay

Carousel (trình chiếu ảnh) dùng tương tự: .carousel > .carousel-inner > .carousel-item và nút data-bs-slide="prev/next"; xem mục Components → Carousel trong tài liệu.

Lưu ý

Modal đặt bên trong phần tử có position: fixed hoặc transform có thể hiển thị sai; đặt modal ở cuối thẻ body.

Thực hành
  1. Tạo modal xác nhận xóa sinh viên.
  2. Làm trang FAQ 5 câu hỏi bằng accordion.
  3. Đưa menu chính vào offcanvas trên điện thoại.
  4. Hiện toast “Đã lưu” sau khi gửi form bằng fetch.
Tóm tắt bài học
  • Cần bootstrap.bundle.min.js.
  • data-bs-toggle/target cho modal, collapse, offcanvas, tab, dropdown.
  • Tooltip, popover, toast khởi tạo bằng JS.
  • API: getOrCreateInstance, show(), hide(), sự kiện *.bs.*.