ศึกษาจาวาสคริปต์จากกรณีศึกษา Free15

ประชาสัมพันธ์ให้ชาวเขต 3 ไปลงทะเบียนใช้สิทธิ์เรียนฟรี 15 ปี ไปตรวจสอบดูก็มีทยอยไปลงกันบ้างแล้ว โดยส่วนตัวผมก็ต้องไปกรอกข้อมูลให้โรงเรียนด้วยเช่นกัน หลังจากใช้ Mozilla Firefox กรอกข้อมูล แต่ติดปัญหาระบบมันไม่ให้ลงเพราะไม่รวมจำนวนนักเรียนให้ เลยเข้าไปดูกระดานถามตอบ พบว่ามีคนแจ้งปัญหานี้แล้ว ผู้พัฒนาโปรแกรม คือ คุณทรงฤทธิ์ สร้อยอาภรณ์ ก็ออกมาแจ้งปัญหานี้ด้วยตัวเอง จากการตอบคำถามบนกระดานถามตอบ ดูไปแล้วเป็นคนที่ใส่ใจกับรายละเอียดดีเอามาก ๆ แถมการพัฒนาโปรแกรมนี้เข้าใจว่าทำแบบลวกตูด แหง ๆ แต่ท่านก็ยังปั่นงานได้ฟีเจอร์ออกมาวันต่อวัน นับว่าเป็นสุดยอดอัจฉริยะของ สพฐ. คนหนึ่งเลยทีเดียว

กลับมาที่หัวเรื่องที่ผมเอามาเป็นกรณีศึกษาวันนี้กันดีกว่า เรื่องของเรื่องก็มาจากโปรแกรม free15 ที่บอกปัญหาข้างต้นไปแล้วว่า Mozilla Firefox ไม่สามารถใช้กรอกข้อมูลได้ ด้วยความซนบวกกับความอยากรู้อยากเห็นเลยคุ้ยแคะออกมาดู ว่ามันเป็นอย่างไร...

ก่อนอื่นมาดูก่อนว่าเครื่องมือที่ใช้ทดสอบ วันนี้มีอะไรบ้าง
1. ใช้ระบบปฎิบัติการ Windows XP SP3 ของคุณภรรยา เพราะ OpenSUSE บน netbook ของผมมีปัญหาอะแดปเตอร์พัง
2. editor ผมใช้ Aptana 1.2 เพิ่ม php + ajax ไลบรารี่อัปเดตล่าสุดแล้ว
3. Firefox 3.0.6 ภาษาไทย เพิ่ม ส่วนขยาย คือ Firebug 1.3 , Web developer toolbar

เอาหละมาเริ่มชำแหละกันเลย
หลังจากใช้ web developer tool bar gen โค้ด html ออกมาแล้วเอามาใช่ใน Aptana เพื่อจัดรูปแบบให้อ่านง่ายก็พบว่า โปรแกรม free15 พัฒนาบน Ajax technology ( html + javascript + php) การทำงานบนส่วนต่าง ๆ ไม่มีปัญหาคือสามารถเรียกเว็บเพจขึ้นมาโชว์ได้ ปัญหามันเกิดตอนกรอกข้อมูลครับ พอกรอกข้อมูลแล้ว หากกรอกข้อมูลเป็นตัวเลขระบบควรจะรวมค่าให้อัตโนมัติ แต่ Firebug แจ้งความผิดพลาดดังภาพ
สังเกตบริเวณคอนโซลด้านล่างครับ
ตัวหนังสือสีแดงบ่งว่า obj is undefined เมื่อกรอกข้อมูลช่องแรก

หากเข้าไปดูด้านในจะพบว่าปัญหาเกิดจากจาวาสคริปต์ ในส่วนของการกำหนดค่าตัวแปรดังภาพ
ซึ่งจะเห็นว่าตัวแปร obj ถูกกำหนดเป็น var obj = document.all;

ปัญหามันไม่ได้เกิดจากหลักไวยกรณ์ครับ แต่เกิดจากมาตรฐานของ Internet Explorer แต่เดิมไม่มีการกำหนดมาตรฐานอย่างชัดเจน ดังนั้นไมโครซอฟท์เลยทำคำสั่ง document.all ขึ้นมาใช้เอง (ข้อมูลจากที่นี่)ซึ่งหากเป็นเมื่อก่อนก็คงไม่มีปัญหาอะไรเพราะ Internet Explorer ครองตลาดและแทบจะเป็นผู้กำหนดมาตรฐานกลางขึ้นมาเสียเองอยู่แล้ว...

คุณอาจจะมีคำถามว่าแล้วทำไม บราวเซอร์ตัวอื่นไม่เอาคำสั่งนี้มาใช้ด้วยเลยหล่ะ จะได้ตัดปัญหาที่มี...
คำตอบคือ ไม่ใช่ไม่อยากเอามาใช้ครับ ปัญหานี้มันอยู่ที่สิทธิบัตรที่เกี่ยวเนื่องกับ Internet Explorer เอง ซึ่งไม่แน่ว่าพี่แกจะเอามาเล่นวันไหน บราวเซอร์เจ้าอื่น ๆ เลยเลี่ยงปัญหาโดยหันไปใช้มาตรฐานกลางดีกว่า สบายใจกว่ากันแยะ ผลกรรมเลยตกมาอยู่ที่คนใช้งานอย่างช่วยไม่ได้

เอาหล่ะเรารับรู้ปัญหาแล้วนะครับว่า ไม่ควรใช้ document.all ถ้าจะพัฒนาโปรแกรมให้เป็นมาตรฐาน

คำถามที่จะมีตามมาแน่นอน ก็คือ แล้วจะใช้อะไรมาแทนคำสั่งข้างต้นหละ?
คำตอบ คือ ใช้วิธีการคิวรี่ผ่าน DOM โดยใช้ document.getElementById() แทน
แน่นอนครับ หากเทียบกันแล้ว document.all สั้นกว่ากันแยะ แต่ getElementById ก็ทำให้การใช้งานยืดหยุ่นกว่า จากโค้ดด้านบน เราแก้เสียใหม่ จะได้ดังภาพด้านล่าง


หลังจากแก้ไขแล้ว ทดสอบผลการทำงานอีกทีก็เรียบร้อยครับ


ใช้ได้ดี สามารถแสดงผลรวมได้ถูกต้องไม่มีปัญหา... 55555
หวังว่ากรณีศึกษานี้จะเป็นประโยชน์บ้างนะครับ...

ปล. ชาว blognone มักจะแขวะเว็บไซต์ของหน่วยงานราชการไทยเสมอ ๆ ว่าการดูว่า ประเทศจะมีความเจริญขนาดไหนให้วัดกันด้วยเว็บไซต์ของหน่วยงานราชการ ว่าใส่ใจกับรายละเอียด ตรงตามมาตรฐานกลาง สามารถใช้ได้กับทุกบราวเซอร์หรือไม่ อยากจะเถียงเขาเหมือนกัน แต่ดู ๆ ไปแล้วก็จริงอย่างเขาว่า ก็เลยได้แต่ บลา บลา ...

ความคิดเห็น

ไม่ระบุชื่อ กล่าวว่า
ผมก็ บลา บลา มาหลายสิบปีแล้วครับ คริคริ คือว่ามันต้องทำใจนะครับ free 15 นี่ ผมมีเวลาทำจริงๆ วันครึ่ง ย้ำครับ ตอนกลางวันที่ทำงานกลับไปโซโล่ต่อที่บ้านยันตีหนึ่ง แล้วก็เอาขึ้นรันเลย แมลงสาบ(bug)วิ่งกันพล่าน เก็บเล็กเก็บน้อย ไปทีละตัวสองตัว ลืมทกสอบบนเจ้าหมาย่างไปเสียสนิท มารู้สึกตัวก็ได้แต่เซ็งตัวเอง พลาดอีกแล้วกู จะแก้ไขก็หลายหน เปิดหน้า data_in.php ขึ้นมา ยังไม่ทันทำอะไรเลย ก็เป็นอันว่ามีงานอื่นที่เร่งด่วนจี๋เข้ามาแทรก พูดไปก็เท่ากับแก้ตัว เฮ้อ บลา บลา ....
ยุทธนา แม่นผล กล่าวว่า
ไหน ๆ ก็มาถึงนี่แล้ว ต่อกันให้จบดีกว่า
อันนี้เป็นฟังก์ชัน sum() ที่ไม่ error บน IE 6 + FF 3.0.6

function sum(){

document.getElementById('txtspre').value = parseInt(document.getElementById('txtpre_m').value) + parseInt(document.getElementById('txtpre_w').value);
document.getElementById('txtspri').value = parseInt(document.getElementById('txtpri_m').value) + parseInt(document.getElementById('txtpri_w').value);
document.getElementById('txtssec').value = parseInt(document.getElementById('txtsec_m').value) + parseInt(document.getElementById('txtsec_w').value);
document.getElementById('txtssecc').value = parseInt(document.getElementById('txtsecc_m').value) + parseInt(document.getElementById('txtsecc_w').value);
document.getElementById('txtsm').value = parseInt(document.getElementById('txtpre_m').value) + parseInt(document.getElementById('txtpri_m').value) + parseInt(document.getElementById('txtsec_m').value) + parseInt(document.getElementById('txtsecc_m').value);
document.getElementById('txtsw').value = parseInt(document.getElementById('txtpre_w').value) + parseInt(document.getElementById('txtpri_w').value) + parseInt(document.getElementById('txtsec_w').value) + parseInt(document.getElementById('txtsecc_w').value);
document.getElementById('txtsclass').value = parseInt(document.getElementById('txtspre').value) + parseInt(document.getElementById('txtspri').value) + parseInt(document.getElementById('txtssec').value) + parseInt(document.getElementById('txtssecc').value);

document.getElementById('txtacc_m').value = parseInt(document.getElementById('txtsm').value) - parseInt(document.getElementById('txtnacc_m').value);
document.getElementById('txtacc_w').value = parseInt(document.getElementById('txtsw').value) - parseInt(document.getElementById('txtnacc_w').value);
document.getElementById('txtsnacc').value = parseInt(document.getElementById('txtnacc_m').value) + parseInt(document.getElementById('txtnacc_w').value);
document.getElementById('txtsacc').value = parseInt(document.getElementById('txtsclass').value) - parseInt(document.getElementById('txtsnacc').value);

document.getElementById('txtmat_m').value = parseInt(document.getElementById('txtsm').value) - parseInt(document.getElementById('txtnmat_m').value);
document.getElementById('txtmat_w').value = parseInt(document.getElementById('txtsw').value) - parseInt(document.getElementById('txtnmat_w').value);
document.getElementById('txtsnmat').value = parseInt(document.getElementById('txtnmat_m').value) + parseInt(document.getElementById('txtnmat_w').value);
document.getElementById('txtsmat').value = parseInt(document.getElementById('txtsclass').value) - parseInt(document.getElementById('txtsnmat').value);

}
ยุทธนา แม่นผล กล่าวว่า
เสริมอีกนิด คือ ระวังเรื่อง id ของ text box บนฟอร์ม ต้องเช็คเพิ่มเติมอีกหน่อย แต่รวม ๆ แล้วประมาณนี้
ไม่ระบุชื่อ กล่าวว่า
ไม่มีปัญหาครับ เข้าทุกตัว แต่ที่จับอาการดู พอได้ครับ ช้านิดนึง แต่ใช้ได้ทั้งสองตัว ขอบคุณนะครับ