Rất tiếc! Tất cả các cách giải quyết này đã đưa tôi đến kết luận rằng loại hộp kiểm HTML rất tệ nếu bạn muốn tạo kiểu cho nó.
Như một lời cảnh báo trước, đây không phải là một triển khai CSS. Tôi chỉ nghĩ rằng tôi sẽ chia sẻ cách giải quyết mà tôi đã nghĩ ra trong trường hợp bất kỳ ai khác có thể thấy nó hữu ích.
Tôi đã sử dụng canvas
phần tử HTML5 .
Mặt trái của điều này là bạn không phải sử dụng hình ảnh bên ngoài và có thể tiết kiệm một số băng thông.
Nhược điểm là nếu một trình duyệt vì một lý do nào đó không thể hiển thị chính xác, thì sẽ không có dự phòng. Mặc dù điều này vẫn còn là một vấn đề trong năm 2017 đang gây tranh cãi.
Cập nhật
Tôi thấy mã cũ khá xấu, vì vậy tôi quyết định viết lại.
Object.prototype.create = function(args){
var retobj = Object.create(this);
retobj.constructor(args || null);
return retobj;
}
var Checkbox = Object.seal({
width: 0,
height: 0,
state: 0,
document: null,
parent: null,
canvas: null,
ctx: null,
/*
* args:
* name default desc.
*
* width 15 width
* height 15 height
* document window.document explicit document reference
* target this.document.body target element to insert checkbox into
*/
constructor: function(args){
if(args === null)
args = {};
this.width = args.width || 15;
this.height = args.height || 15;
this.document = args.document || window.document;
this.parent = args.target || this.document.body;
this.canvas = this.document.createElement("canvas");
this.ctx = this.canvas.getContext('2d');
this.canvas.width = this.width;
this.canvas.height = this.height;
this.canvas.addEventListener("click", this.ev_click(this), false);
this.parent.appendChild(this.canvas);
this.draw();
},
ev_click: function(self){
return function(unused){
self.state = !self.state;
self.draw();
}
},
draw_rect: function(color, offset){
this.ctx.fillStyle = color;
this.ctx.fillRect(offset, offset,
this.width - offset * 2, this.height - offset * 2);
},
draw: function(){
this.draw_rect("#CCCCCC", 0);
this.draw_rect("#FFFFFF", 1);
if(this.is_checked())
this.draw_rect("#000000", 2);
},
is_checked: function(){
return !!this.state;
}
});
Đây là một bản demo hoạt động .
Phiên bản mới sử dụng nguyên mẫu và kế thừa vi sai để tạo ra một hệ thống hiệu quả để tạo các hộp kiểm. Để tạo một hộp kiểm:
var my_checkbox = Checkbox.create();
Điều này sẽ ngay lập tức thêm hộp kiểm vào DOM và kết nối các sự kiện. Để truy vấn xem hộp kiểm có được chọn hay không:
my_checkbox.is_checked(); // True if checked, else false
Cũng cần lưu ý là tôi đã thoát khỏi vòng lặp.
Cập nhật 2
Một cái gì đó tôi đã bỏ qua để đề cập đến trong bản cập nhật mới nhất là việc sử dụng canvas có nhiều lợi thế hơn là chỉ tạo một hộp kiểm trông giống như bạn muốn nó nhìn. Bạn cũng có thể tạo các hộp kiểm đa trạng thái , nếu bạn muốn.
Object.prototype.create = function(args){
var retobj = Object.create(this);
retobj.constructor(args || null);
return retobj;
}
Object.prototype.extend = function(newobj){
var oldobj = Object.create(this);
for(prop in newobj)
oldobj[prop] = newobj[prop];
return Object.seal(oldobj);
}
var Checkbox = Object.seal({
width: 0,
height: 0,
state: 0,
document: null,
parent: null,
canvas: null,
ctx: null,
/*
* args:
* name default desc.
*
* width 15 width
* height 15 height
* document window.document explicit document reference
* target this.document.body target element to insert checkbox into
*/
constructor: function(args){
if(args === null)
args = {};
this.width = args.width || 15;
this.height = args.height || 15;
this.document = args.document || window.document;
this.parent = args.target || this.document.body;
this.canvas = this.document.createElement("canvas");
this.ctx = this.canvas.getContext('2d');
this.canvas.width = this.width;
this.canvas.height = this.height;
this.canvas.addEventListener("click", this.ev_click(this), false);
this.parent.appendChild(this.canvas);
this.draw();
},
ev_click: function(self){
return function(unused){
self.state = !self.state;
self.draw();
}
},
draw_rect: function(color, offsetx, offsety){
this.ctx.fillStyle = color;
this.ctx.fillRect(offsetx, offsety,
this.width - offsetx * 2, this.height - offsety * 2);
},
draw: function(){
this.draw_rect("#CCCCCC", 0, 0);
this.draw_rect("#FFFFFF", 1, 1);
this.draw_state();
},
draw_state: function(){
if(this.is_checked())
this.draw_rect("#000000", 2, 2);
},
is_checked: function(){
return this.state == 1;
}
});
var Checkbox3 = Checkbox.extend({
ev_click: function(self){
return function(unused){
self.state = (self.state + 1) % 3;
self.draw();
}
},
draw_state: function(){
if(this.is_checked())
this.draw_rect("#000000", 2, 2);
if(this.is_partial())
this.draw_rect("#000000", 2, (this.height - 2) / 2);
},
is_partial: function(){
return this.state == 2;
}
});
Tôi đã sửa đổi một chút cái Checkbox
được sử dụng trong đoạn trích cuối để nó chung chung hơn, giúp nó có thể "mở rộng" nó bằng một hộp kiểm có 3 trạng thái. Đây là bản demo . Như bạn có thể thấy, nó đã có nhiều chức năng hơn hộp kiểm tích hợp.
Một cái gì đó để xem xét khi bạn chọn giữa JavaScript và CSS.
Mã cũ, thiết kế kém
Trình diễn làm việc
Đầu tiên, thiết lập một khung vẽ
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
checked = 0; // The state of the checkbox
canvas.width = canvas.height = 15; // Set the width and height of the canvas
document.body.appendChild(canvas);
document.body.appendChild(document.createTextNode(' Togglable Option'));
Tiếp theo, nghĩ ra một cách để có bản cập nhật canvas.
(function loop(){
// Draws a border
ctx.fillStyle = '#ccc';
ctx.fillRect(0,0,15,15);
ctx.fillStyle = '#fff';
ctx.fillRect(1, 1, 13, 13);
// Fills in canvas if checked
if(checked){
ctx.fillStyle = '#000';
ctx.fillRect(2, 2, 11, 11);
}
setTimeout(loop, 1000/10); // Refresh 10 times per second
})();
Phần cuối cùng là làm cho nó tương tác. May mắn thay, nó khá đơn giản:
canvas.onclick = function(){
checked = !checked;
}
Đây là nơi bạn có thể gặp sự cố trong IE, do mô hình xử lý sự kiện kỳ lạ của họ trong JavaScript.
Tôi hi vọng điêu nay se giup được ai đo; nó chắc chắn phù hợp với nhu cầu của tôi