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