Huch! All diese Problemumgehungen haben mich zu dem Schluss geführt, dass das HTML-Kontrollkästchen nicht funktioniert, wenn Sie es stylen möchten.
Als Warnung ist dies keine CSS-Implementierung. Ich dachte nur, ich würde die Problemumgehung teilen, die ich mir ausgedacht habe, falls jemand anderes sie nützlich finden könnte.
Ich habe das HTML5- canvas
Element verwendet.
Der Vorteil dabei ist, dass Sie keine externen Bilder verwenden müssen und wahrscheinlich etwas Bandbreite sparen können.
Der Nachteil ist, dass es keinen Fallback gibt, wenn ein Browser es aus irgendeinem Grund nicht richtig rendern kann. Ob dies auch 2017 ein Thema bleibt, ist umstritten.
Aktualisieren
Ich fand den alten Code ziemlich hässlich und beschloss, ihn neu zu schreiben.
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;
}
});
Hier ist eine funktionierende Demo .
Die neue Version verwendet Prototypen und differenzielle Vererbung, um ein effizientes System zum Erstellen von Kontrollkästchen zu erstellen. So erstellen Sie ein Kontrollkästchen:
var my_checkbox = Checkbox.create();
Dadurch wird das Kontrollkästchen sofort zum DOM hinzugefügt und die Ereignisse werden verknüpft. So fragen Sie ab, ob ein Kontrollkästchen aktiviert ist:
my_checkbox.is_checked(); // True if checked, else false
Wichtig ist auch, dass ich die Schleife losgeworden bin.
Update 2
Etwas, das ich im letzten Update nicht erwähnt habe, ist, dass die Verwendung der Zeichenfläche mehr Vorteile bietet, als nur ein Kontrollkästchen zu erstellen, das so aussieht, wie Sie es möchten. Wenn Sie möchten, können Sie auch Kontrollkästchen mit mehreren Status erstellen .
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;
}
});
Ich habe das Checkbox
im letzten Snippet verwendete Element geringfügig geändert , damit es allgemeiner ist, sodass es mit einem Kontrollkästchen mit 3 Status "erweitert" werden kann. Hier ist eine Demo . Wie Sie sehen, verfügt es bereits über mehr Funktionen als das integrierte Kontrollkästchen.
Beachten Sie Folgendes, wenn Sie zwischen JavaScript und CSS wählen.
Alter, schlecht gestalteter Code
Arbeitsdemo
Richten Sie zunächst eine Leinwand ein
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'));
Entwickeln Sie als Nächstes eine Möglichkeit, die Zeichenfläche selbst zu aktualisieren.
(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
})();
Der letzte Teil ist, es interaktiv zu machen. Zum Glück ist es ziemlich einfach:
canvas.onclick = function(){
checked = !checked;
}
Hier können Probleme im IE auftreten, da das Modell für die Ereignisbehandlung in JavaScript seltsam ist.
Ich hoffe das hilft jemandem; es passte definitiv zu meinen Bedürfnissen.