Ajax: บันทึก trick เรื่องจาวาสคริปต์
ต้องการทำป้าย Loading ...
แบบที่กูเกิลใช้
ทดลองแกะดู เขาใช้ css เป็นทำนองนี้ (แก้ไขและเปลี่ยนแปลงจากต้นฉบับแล้ว)
... .hidden { display: none; } #loading { position: absolute; top: 14em; height: 2em; left: 49%; z-index: 10000; } #loading p { padding: .5em 40px .5em 40px; text-align: center; line-height: 2em; color: #c66; background: #fee; border: solid 1px #c99; } ...
เวลาใส่ในข้อความ html ก็ใช้ทำนองว่า...
... <div id="loading" class="hidden"><p>Loading ... </p></div> ...
เวลาถูกเรียกใช้งานด้วยจาวาสคริปต์ โดยเมธอด POST
ก็ให้มาเปลี่ยนแปลง class
จาก hidden เป็นคลาสอื่นตามต้องการ ด้วยคำสั่ง ...
document.getElementById("loading").className = "";
ก็จะแสดงผล Loading ...
ออกมา
เวลางานเสร็จ ข้อมูลถูกส่งกลับมายัง client ก็ให้ตั้งคลาสกลับเป็น hidden ตามเดิม ด้วยคำสั่ง
document.getElementById("loading").className = "hidden";
ปัญหาคือจาวาสคริปต์รันโดยใช้แคช จึงข้ามลำดับขั้นตอนสลับไปหมด (ไม่แน่ใจนะครับ เดาเอาเฉย ๆ)
เลยต้องใช้การหน่วงเวลา โดยแบ่งการ Request ออกเป็นสองจังหวะ
ให้จังหวะแรกมาเรียกให้เลิก hidden ก่อน แล้วจึงเรียกให้ทำการ hidden ซ้ำอีกครั้ง
ได้ปรับให้โปรแกรมทำงานตามลำดับโดยเรียกใช้ฟังก์ชั่น setTimeout
ในจังหวะแรก ดังนี้
<script> function getXmlHttpRequestObject() { if (window.XMLHttpRequest) { return new XMLHttpRequest(); //Not IE } else { if(window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); //IE } else { alert("Your browser doesn't support the XmlHttpRequest object. Better upgrade to Firefox."); } } } var req = getXmlHttpRequestObject(); function d_post(cmd,argv) { arg1 = "cmd="+cmd+"/"+argv; req.open("POST", "?", false); req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); req.send(arg1); if (cmd=="info" || cmd=="source") { document.getElementById("loading").className = ""; setTimeout("d_post('do_"+cmd+"','"+argv+"');", 1); } else if (cmd=="c2e" || cmd=="e2c") { document.getElementById("loading").className = ""; setTimeout("d_post('do_"+cmd+"','"+char2url(argv)+"');", 1); } else if (cmd=="do_info" || cmd=="do_source" || cmd=="do_c2e" || cmd=="do_e2c") { document.getElementById("d_main").innerHTML = req.responseText; document.getElementById("loading").className = "hidden"; document.getElementById("search_form").focus(); } } </script>
หลังจากใส่ฟังก์ชั่น setTimeout
เข้าไป ปรากฎว่าโปรแกรมทำงานตามลำดับได้เรียบร้อย
มารู้ทีหลังว่า ภาษานี้เขาเขียนแบบไล่ฟังก์ชั่นเป็นทอด ๆ เพื่อให้การทำงานเป็นไปตามลำดับ
เขียนใหม่ได้เป็น
<script> function getXmlHttpRequestObject() { if (window.XMLHttpRequest) { return new XMLHttpRequest(); //Not IE } else { if(window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); //IE } else { alert("Your browser doesn't support the XmlHttpRequest object. Better upgrade to Firefox."); } } } var req = getXmlHttpRequestObject(); function d_post(cmd,argv) { document.getElementById("loading").className = ""; setTimeout("xd_post('" + cmd + "','" + argv + "');", 1); } function xd_post(cmd,argv) { arg1 = "cmd="+cmd+"/"+argv; req.open("POST", "?", false); req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); req.send(arg1); if (cmd=="info" || cmd=="source" || cmd=="c2e" || cmd=="e2c") { document.getElementById("d_main").innerHTML = req.responseText; document.getElementById("loading").className = "hidden"; } } </script>
Recent comments