อ๊ะ! วิธีแก้ไขปัญหาทั้งหมดเหล่านี้ทำให้ฉันสรุปได้ว่าช่องทำเครื่องหมาย HTML นั้นแย่มากหากคุณต้องการจัดสไตล์
เป็นการเตือนล่วงหน้านี่ไม่ใช่การใช้ CSS ฉันแค่คิดว่าฉันจะแบ่งปันวิธีแก้ปัญหาที่ฉันคิดไว้ในกรณีที่คนอื่นอาจเห็นว่ามีประโยชน์
ฉันใช้canvas
องค์ประกอบHTML5
ข้อเสียคือคุณไม่จำเป็นต้องใช้รูปภาพภายนอกและอาจช่วยประหยัดแบนด์วิดท์ได้
ข้อเสียคือถ้าเบราว์เซอร์ด้วยเหตุผลบางอย่างไม่สามารถแสดงได้อย่างถูกต้องแล้วไม่มีทางเลือก แม้ว่าจะเป็นปัญหาในปี 2560 หรือไม่
ปรับปรุง
ฉันพบรหัสเก่าค่อนข้างน่าเกลียดดังนั้นฉันจึงตัดสินใจที่จะเขียนใหม่
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;
}
});
นี่คือการสาธิตการทำงาน
รุ่นใหม่ใช้ต้นแบบและการสืบทอดที่แตกต่างกันเพื่อสร้างระบบที่มีประสิทธิภาพสำหรับการสร้างช่องทำเครื่องหมาย ในการสร้างช่องทำเครื่องหมาย:
var my_checkbox = Checkbox.create();
การดำเนินการนี้จะเพิ่มช่องทำเครื่องหมายใน DOM และเชื่อมโยงเหตุการณ์ หากต้องการสอบถามว่ามีการทำเครื่องหมายในช่องทำเครื่องหมาย:
my_checkbox.is_checked(); // True if checked, else false
สิ่งสำคัญที่ควรทราบคือฉันกำจัดวงวน
อัปเดต 2
สิ่งที่ฉันละเลยที่จะพูดถึงในการอัปเดตครั้งล่าสุดคือการใช้ Canvas มีข้อดีมากกว่าแค่สร้างช่องทำเครื่องหมายที่มีลักษณะตามที่คุณต้องการ คุณสามารถสร้างช่องทำเครื่องหมายหลายสถานะได้ถ้าต้องการ
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
ใช้ในตัวอย่างสุดท้ายเพื่อให้เป็นเรื่องทั่วไปมากขึ้นทำให้สามารถ "ขยาย" ด้วยช่องทำเครื่องหมายที่มี 3 สถานะ นี่คือการสาธิต อย่างที่คุณเห็นมันมีฟังก์ชั่นมากกว่าช่องทำเครื่องหมายในตัวอยู่แล้ว
สิ่งที่ต้องพิจารณาเมื่อคุณเลือกระหว่าง JavaScript และ CSS
รหัสเก่าที่ออกแบบไม่ดี
การสาธิตการทำงาน
ก่อนอื่นให้ตั้งค่าผืนผ้าใบ
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'));
ถัดไปกำหนดวิธีที่จะปรับปรุงผ้าใบเอง
(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
})();
ส่วนสุดท้ายคือการทำให้มันโต้ตอบ โชคดีที่มันค่อนข้างง่าย:
canvas.onclick = function(){
checked = !checked;
}
นี่คือที่ที่คุณอาจมีปัญหาใน IE เนื่องจากรูปแบบการจัดการเหตุการณ์แปลก ๆ ใน JavaScript
ฉันหวังว่านี่จะช่วยให้ใครบางคน; มันเหมาะกับความต้องการของฉันอย่างแน่นอน