Olmadı! Tüm bu geçici çözümler beni HTML onay kutusunun stilini değiştirmek isterseniz berbat olduğu sonucuna götürdü.
Önsöz olarak, bu bir CSS uygulaması değildir. Başka birinin yararlı bulabilmesi durumunda karşılaştığım geçici çözümü paylaşacağımı düşündüm.
HTML5 canvas
öğesini kullandım.
Bunun tersi, harici görüntüleri kullanmak zorunda olmamanız ve muhtemelen bazı bant genişliğinden tasarruf edebilmenizdir.
Dezavantajı, bir nedenden dolayı bir tarayıcı onu doğru bir şekilde oluşturamazsa, o zaman bir geri dönüş yoktur. Bununla birlikte, 2017'de bir sorun olarak kalmaya devam edeceği tartışmalıdır.
Güncelleme
Eski kodu oldukça çirkin buldum, bu yüzden tekrar yazmaya karar verdim.
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;
}
});
İşte çalışan bir demo .
Yeni sürüm, onay kutuları oluşturmak için verimli bir sistem oluşturmak için prototipler ve diferansiyel kalıtım kullanır. Bir onay kutusu oluşturmak için:
var my_checkbox = Checkbox.create();
Bu onay kutusunu hemen DOM'a ekler ve olayları bağlar. Bir onay kutusunun işaretli olup olmadığını sorgulamak için:
my_checkbox.is_checked(); // True if checked, else false
Ayrıca dikkat edilmesi gereken nokta, döngüden kurtuldum.
Güncelleme 2
Son güncellemede bahsetmeyi ihmal ettiğim bir şey, tuvali kullanmanın sadece görünmesini istediğiniz gibi görünen bir onay kutusu yapmaktan daha fazla avantajı olmasıdır. İsterseniz, çok durumlu onay kutuları da oluşturabilirsiniz .
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;
}
});
Checkbox
Son snippet'te kullanılanı biraz değiştirdim, böylece daha genel olacak ve 3 durumlu bir onay kutusuyla "genişletebilmeyi" mümkün kıldım. İşte bir demo . Gördüğünüz gibi, zaten yerleşik onay kutusundan daha fazla işlevselliğe sahip.
JavaScript ve CSS arasında seçim yaparken göz önünde bulundurulması gereken bir şey.
Eski, kötü tasarlanmış kod
Çalışma Demosu
İlk önce bir tuval oluşturun
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'));
Ardından, tuvalin kendisini güncellemesinin bir yolunu bulun.
(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
})();
Son bölüm etkileşimli hale getirmektir. Neyse ki, oldukça basit:
canvas.onclick = function(){
checked = !checked;
}
JavaScript'teki garip olay işleme modelleri nedeniyle IE'de sorun yaşayabileceğiniz yer burasıdır.
Umarım bu birine yardımcı olur; kesinlikle benim ihtiyaçlarına uygun.