noUiSlider là gì và vì sao nên dùng
noUiSlider là thư viện thanh trượt nhẹ, không phụ thuộc framework lớn, tương thích jQuery hoặc Zepto, hỗ trợ cả chuột, chạm và con trỏ. Điểm mạnh:
- Hiệu suất cao, kích thước nhỏ, không nặng CSS
- Hỗ trợ 1 hoặc 2 tay nắm, slider dải giá trị, step linh hoạt
- Dạng ngang hoặc dọc, LTR và RTL
- Kết nối thanh nền thể hiện khoảng đã chọn
- Pips, ticks, nhãn mức trên thang đo
- Định dạng số tùy biến (tiền tệ, phần trăm)
- API đơn giản: get, set, update, events
- Thân thiện màn hình cảm ứng, dễ tùy biến UI
Khi nào nên áp dụng
- Bộ lọc giá trong thương mại điện tử
- Chọn khoảng thời gian, khung giờ
- Điều chỉnh âm lượng, độ sáng, tốc độ phát
- Cấu hình thông số dạng khoảng trong biểu mẫu
- Visualize khoảng dữ liệu với bước nhảy cụ thể
Cài đặt nhanh
Bạn có thể dùng CDN hoặc cài qua npm. Thư viện tương thích jQuery/Zepto; nếu không dùng, vẫn có thể thao tác bằng JavaScript thuần vì API gắn vào phần tử.
Các bước triển khai cơ bản:
- Thêm CSS của noUiSlider để có giao diện mặc định
- Thêm script noUiSlider
- Tạo phần tử chứa slider, ví dụ một div
- Khởi tạo slider bằng phương thức noUiSlider với options
Cấu hình cốt lõi bạn cần nắm
- start: giá trị khởi tạo, mảng 1 hoặc 2 phần tử
- range: min và max, có thể thêm mốc trung gian
- step: bước nhảy đơn vị
- connect: hiển thị phần kết nối nền đã chọn
- false, true, lower, upper tùy số tay nắm
- direction: ltr hoặc rtl
- orientation: horizontal hoặc vertical
- snap: tay nắm hút về các mốc
- animate: bật tắt hiệu ứng khi set
- margin: khoảng cách tối thiểu giữa 2 tay nắm
- limit: khoảng cách tối đa giữa 2 tay nắm
- behaviour: kết hợp tap, drag, fixed, snap để tùy thao tác
- format: quy định cách hiển thị và phân tích giá trị với to và from
Mẹo:
- Dùng margin khi cần cấm chồng lấn hai tay nắm
- Dùng limit để giới hạn độ rộng khoảng chọn
- snap phù hợp khi bạn có thang giá trị rời rạc
Khởi tạo slider hai tay nắm
Quy trình điển hình:
- Tạo phần tử chứa
- Gọi noUiSlider với start là mảng hai giá trị và connect bật để thấy khoảng chọn
- Thiết lập range min, max và step
Trường hợp dọc:
- Thêm orientation là vertical
- Cân nhắc chiều cao phần tử và style top thay vì left
Lấy và đặt giá trị
- Lấy giá trị hiện tại: gọi phương thức get tương đương
.val()
trên phần tử slider - Đặt giá trị mới: gọi set tương đương
.val([v1, v2])
với slider 2 tay nắm - Có thể cập nhật từng tay nắm bằng cách truyền mảng giữ nguyên giá trị tay còn lại
Lưu ý:
- Nếu đã bật animate, set sẽ có hiệu ứng
- Nếu dùng format, get trả chuỗi đã định dạng trừ khi bạn gọi from để chuyển ngược
Sự kiện quan trọng
- update: khi slider thay đổi trong quá trình kéo
- slide: trong lúc kéo tay nắm
- set: sau khi người dùng thả tay nắm
- change: khi giá trị cuối được xác nhận
Bạn có thể lắng nghe các sự kiện để đồng bộ với input, gọi API lọc, hoặc cập nhật giao diện.
Đồng bộ slider với input
- Ràng buộc giá trị slider với input text, number, hidden
- Khi input thay đổi, parse bằng format.from và set ngược lên slider
- Khi slider thay đổi, format.to để hiển thị đẹp trong input
- Kiểm tra giá trị người dùng nhập, nếu không hợp lệ, khôi phục giá trị trước đó
Mẹo:
- Chặn ký tự không hợp lệ, chuẩn hóa dấu thập phân
- Làm tròn theo step để đảm bảo tính nhất quán
Định dạng số cho UI thực tế
Bạn có thể thiết lập format:
- to: nhận number, trả chuỗi hiển thị, ví dụ thêm đơn vị tiền, nhóm nghìn, làm tròn
- from: nhận chuỗi người dùng nhập, trả number, xử lý dấu tách thập phân, nghìn
Các trường hợp phổ biến: - Tiền tệ: 1 234 567 đ
- Phần trăm: 25%
- Số thập phân cố định: 2 chữ số sau dấu phẩy
Lưu ý:
- Hãy quy ước thống nhất giữa to và from
- Khi b = 0, đảm bảo hiển thị 0 thay vì chuỗi rỗng
Pips, ticks và nhãn thang đo
- Pips giúp người dùng ước lượng vị trí và mốc giá trị
- Có thể đặt density để mật độ mốc
- Có filter để tùy loại pips lớn, nhỏ, phụ
- Có thể hiển thị nhãn giá trị bằng format.to
Trường hợp range dài: - Chỉ hiển thị mốc chính để tránh rối mắt
- Kết hợp snap nếu cần bắt dính về các mốc
Tinh chỉnh trải nghiệm người dùng
- behaviour
- tap: nhảy tay nắm đến vị trí click
- drag: kéo vùng connect để di chuyển cả hai tay
- fixed: duy trì khoảng cách cố định giữa hai tay
- snap: bắt dính mốc khi kéo
- animate: bật khi cần hiệu ứng mượt, tắt nếu ưu tiên hiệu suất
- RTL: dùng direction rtl cho giao diện tiếng Ả Rập, Hebrew
- Vertical: hữu ích với slider tham số kỹ thuật, thước đo dạng cột
Tối ưu hiệu suất
- Trì hoãn xử lý nặng ở sự kiện change hoặc set thay vì update
- Debounce hoặc throttle khi gọi API tìm kiếm/lọc
- Tránh reflow layout không cần thiết khi slider đang slide
- Gộp cập nhật DOM khi đồng bộ nhiều phần tử
Khả năng truy cập
- Kích thước tay nắm đủ lớn cho chạm
- Tương phản màu sắc đạt chuẩn
- Hỗ trợ bàn phím: bước nhảy bằng phím mũi tên
- Thêm nhãn mô tả vai trò slider, thông báo giá trị hiện tại
- ARIA attributes phù hợp cho tay nắm và vùng slider
Kiểm thử trên thiết bị thực
- Chuột, touch, bút stylus
- iOS, Android, Windows, macOS
- Trình duyệt mobile với thanh địa chỉ tự ẩn hiện
- RTL và vertical để phát hiện lỗi style theo chiều
Xử lý lỗi thường gặp
- Tay nắm không di chuyển
- Kiểm tra range, step, margin, limit có gây khóa giá trị
- Giá trị hiển thị sai
- Rà soát format.to và format.from không đồng nhất
- Pips tràn layout
- Giảm density, ẩn label nhỏ, rút ngắn format
- Sự kiện bắn quá nhiều
- Chuyển logic sang change hoặc set, dùng debounce
Mẫu áp dụng nhanh
- Bộ lọc giá sản phẩm
- 2 tay nắm, connect true, step 1000, format tiền
- Chọn khoảng giờ
- range 0 đến 24, step 0.5, format giờ phút
- Điều chỉnh âm lượng
- 1 tay nắm, step 1, pips 0, 25, 50, 75, 100
So sánh nhanh với lựa chọn khác
- Ion.RangeSlider: nhiều theme, phụ thuộc jQuery
- noUiSlider: nhẹ hơn, linh hoạt formatter, pips rõ ràng, phù hợp dự án hiện đại
Checklist triển khai sản phẩm
- Xác định range, step, hành vi cần có
- Quy ước format to và from ngay từ đầu
- Liên kết input và slider hai chiều
- Bật pips khi cần hướng dẫn thị giác
- Kiểm thử chạm và bàn phím
- Theo dõi hiệu suất trong sự kiện update
Kết luận
noUiSlider 7.x là lựa chọn vững chắc để tạo thanh trượt UI mượt, chính xác và thân thiện di động. Với cấu hình linh hoạt, định dạng số mạnh và API rõ ràng, bạn có thể triển khai từ bộ lọc giá thương mại điện tử đến các trình điều khiển thông số kỹ thuật, đồng thời đảm bảo trải nghiệm người dùng, hiệu suất và khả năng truy cập.