jQuery Knob là một plugin UI dựa trên canvas cho phép bạn biến input số thành núm xoay (dial) tương tác. Nó hỗ trợ chuột, bàn phím, cảm ứng, hiển thị giá trị trực tiếp, tùy biến màu sắc/độ dày, và hoạt động tốt trên màn hình Retina/HiDPI. Bài viết này hướng dẫn cài đặt, cấu hình, xử lý sự kiện, tối ưu hiệu năng và các mẫu điển hình để bạn triển khai nhanh trên dashboard, điều khiển âm lượng, form nhập số, điều khiển IoT, v.v.
1) Cài đặt và yêu cầu
- Yêu cầu: jQuery 1.7+.
- Tải plugin: dùng file jQuery Knob (phiên bản phổ biến: 1.2.x).
- Chèn theo thứ tự: jQuery trước, rồi đến plugin.
Ví dụ dùng CDN (minh họa):
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<!-- jQuery Knob -->
<script src="path/to/jquery.knob.min.js"></script>
Lưu ý về khả năng tương thích:
- Canvas là bắt buộc. IE8 cần excanvas (không khuyến nghị cho dự án mới).
- Plugin tự động nhân tỷ lệ theo devicePixelRatio để sắc nét trên HiDPI.
2) Khởi tạo cơ bản
HTML:
<input type="text" class="dial" value="35">
JS:
$(function() {
$('.dial').knob();
});
Khi khởi tạo, input số được vẽ lại thành một núm xoay (dial) với giá trị ban đầu là value của input.
3) Các tùy chọn (options) quan trọng
Bạn có thể đặt options qua:
- Thuộc tính data-* trên phần tử
- Hoặc truyền đối tượng cấu hình khi gọi .knob()
Một số options thường dùng:
- min, max: khoảng giá trị. Mặc định 0–100
- step: bước tăng/giảm mỗi lần thay đổi
- width, height: kích thước canvas. Có thể dùng % để responsive
- thickness: độ dày đường vẽ (0.01–1.0)
- fgColor: màu vòng tiến trình (ví dụ: “#87CEEB”)
- bgColor: màu nền vòng (nếu bản plugin bạn dùng hỗ trợ)
- lineCap: kiểu đầu nét “butt”, “round”, “square”
- cursor: tạo hiệu ứng con trỏ (đơn vị px ảo, thường 0–30)
- displayInput: hiển thị input số ở giữa hay không (true/false)
- displayPrevious: hiển thị giá trị trước đó mờ hơn để so sánh
- readOnly: chỉ hiển thị, không cho phép kéo/thay đổi
- inputColor, font, fontWeight: kiểu chữ của giá trị hiển thị
- angleOffset: góc bắt đầu (độ), mặc định 0, có thể -90 để xoay
- angleArc: tổng góc hiển thị (độ), mặc định 360
Ví dụ cấu hình bằng JS:
$('.dial').knob({
min: 0,
max: 200,
step: 5,
width: 220,
height: 220,
thickness: 0.25,
fgColor: '#00b894',
// bgColor: '#ecf0f1', // nếu bản plugin hỗ trợ
lineCap: 'round',
cursor: 20,
displayInput: true,
inputColor: '#2d3436',
font: 'Arial',
fontWeight: 'bold',
angleOffset: -90,
angleArc: 270
});
Đặt qua data-*:
<input
class="dial"
data-min="0"
data-max="200"
data-step="5"
data-width="220"
data-height="220"
data-thickness="0.25"
data-fgcolor="#00b894"
data-linecap="round"
data-cursor="20"
data-displayinput="true"
data-inputcolor="#2d3436"
data-font="Arial"
data-font-weight="bold"
data-angleoffset="-90"
data-anglearc="270"
value="80"
/>
4) Hook và sự kiện: change, release, cancel, draw
Plugin cho phép đăng ký hàm callback để xử lý tương tác thời gian thực:
$('.dial').knob({
change: function(val) {
// Gọi liên tục khi người dùng kéo/nhập (chưa "commit")
// Dùng để cập nhật UI khác theo thời gian thực
},
release: function(val) {
// Gọi khi người dùng "nhả" chuột/ngừng chạm/enter xong (đã "commit")
// Dùng để lưu dữ liệu, gọi API, v.v.
console.log('Giá trị cuối:', val);
},
cancel: function() {
// Gọi khi hủy thay đổi (nhấn ESC trong lúc kéo)
},
draw: function() {
// Tùy biến vẽ nếu cần (nâng cao)
// return false để chặn vẽ mặc định
}
});
Hành vi bàn phím:
- Phím mũi tên lên/xuống: tăng/giảm theo step
- Shift/Alt/Ctrl kết hợp có thể thay đổi tốc độ tùy phiên bản
- ESC: hủy thay đổi giữa chừng (gọi cancel)
5) Responsive: đặt width/height theo phần trăm
Plugin hỗ trợ width, height dạng phần trăm. Đặt dựa trên container cha.
HTML:
<div class="knob-wrap">
<input class="dial" data-width="100%" data-height="100%" value="45">
</div>
CSS:
.knob-wrap {
width: 240px; /* hoặc %/vw */
height: 240px; /* giữ tỉ lệ vuông */
position: relative;
}
JS:
$('.dial').knob();
Khi thay đổi kích thước container (resize), núm xoay sẽ vẽ lại theo kích thước mới.
6) Nhiều núm xoay trên cùng trang
Chỉ cần gán cùng class và khởi tạo một lần:
<input class="dial" value="20">
<input class="dial" value="50">
<input class="dial" value="90">
$(function() {
$('.dial').knob({
thickness: 0.3,
fgColor: '#0984e3'
});
});
Bạn cũng có thể nhóm theo fieldset (plugin hỗ trợ biến nhiều input trong fieldset thành một nhóm logic), nhưng thực tế phổ biến hơn là khởi tạo theo class như trên.
7) Mẫu điển hình
- Đồng hồ âm lượng:
$('.volume').knob({
min: 0,
max: 100,
step: 1,
fgColor: '#d63031',
angleArc: 240,
angleOffset: -120,
release: function(v) {
setVolume(v / 100); // ví dụ cập nhật audio
}
});
- Điều khiển độ sáng:
$('.brightness').knob({
min: 0,
max: 1000,
step: 50,
fgColor: '#fdcb6e',
thickness: 0.2,
displayPrevious: true
});
- Chỉ hiển thị số liệu (readOnly) trong dashboard:
$('.kpi').knob({
readOnly: true,
fgColor: '#00b894',
thickness: 0.15
});
8) Tối ưu hiệu năng và UX
- Tránh xử lý nặng trong change: change được gọi liên tục; debounce/throttle nếu cập nhật DOM phức tạp.
- Dùng release để lưu dữ liệu/ gọi API nhằm giảm tải.
- Giới hạn angleArc để hiển thị bán nguyệt hoặc 3/4 vòng giúp thao tác chính xác hơn.
- Sử dụng step phù hợp để tránh “nhảy” quá mượt khiến người dùng khó dừng đúng giá trị.
- Nếu chỉ để hiển thị, dùng readOnly để loại bỏ sự kiện thừa.
- Tối ưu màu tương phản fgColor, bgColor, inputColor để đọc tốt trên nền sáng/tối.
9) Khả năng truy cập (Accessibility)
Mặc dù plugin hỗ trợ bàn phím, bạn nên:
- Thêm label mô tả rõ ràng:
<label for="speed">Tốc độ quạt</label>
<input id="speed" class="dial" value="30">
- Cân nhắc thêm thuộc tính aria (ví dụ role=”slider”, aria-valuemin, aria-valuemax, aria-valuenow) đồng bộ với giá trị hiện tại.
- Đảm bảo tỷ lệ tương phản văn bản ở giữa núm xoay đáp ứng tiêu chuẩn WCAG.
10) Gỡ lỗi và lỗi thường gặp
- Không hiển thị gì: kiểm tra thứ tự script (jQuery trước), đường dẫn plugin chính xác, trình duyệt hỗ trợ canvas.
- Màu không đổi: đảm bảo sử dụng đúng tên option (fgColor, inputColor). Một số fork/phiên bản khác nhau có thể thay đổi tên.
- Không responsive: cần đặt width/height dạng % và đảm bảo container cha có kích thước xác định.
- Lag khi kéo: tối ưu callback change, tránh thao tác DOM tốn kém theo từng khung vẽ.
- Giá trị nhảy vượt giới hạn: thiết lập min, max và step hợp lý, đồng thời kiểm tra tính toán khi cập nhật bằng phím.
11) So sánh nhanh với giải pháp khác
- CSS/JS thuần: linh hoạt hơn nhưng tốn thời gian dựng lại canvas/logic xoay.
- Range input HTML5: đơn giản, hỗ trợ sẵn A11y tốt hơn, nhưng không có giao diện núm tròn.
- Thư viện chart/gauge: phù hợp hiển thị số liệu một chiều; không phải để nhập liệu tương tác.
Nếu bạn cần một UI nhập liệu tròn, nhẹ, dễ tùy biến và tương tác đa phương thức, jQuery Knob vẫn là lựa chọn hiệu quả.
12) Kết luận
jQuery Knob giúp bạn tạo núm xoay (dial) mượt, thân thiện, dễ dùng cho nhiều tình huống giao diện web. Chỉ với vài dòng cấu hình, bạn đã có thể:
- Tùy biến giao diện (màu, độ dày, góc)
- Hỗ trợ bàn phím, chuột, cảm ứng
- Tối ưu cho HiDPI và responsive
Hãy bắt đầu với cấu hình cơ bản, thêm các hook cần thiết, rồi tối ưu hiệu năng và khả năng truy cập để có trải nghiệm người dùng tốt nhất.
