ผมขออนญาตนำคำถามจากเมลของสมาชิก jQuery [THAI] ท่านหนึ่งมาเล่าให้ฟังเป็นกรณีศึกษานะครับ เนื้อหาของจดหมายพอสรุปได้คร่าว ๆ คือ ใน code มีการ bind event ไว้ และมีการสร้าง element ตอน runtime ในลักษณะนี้ (ผมไม่ได้ใช้ code ที่สมาชิกส่งมาให้ แต่เขียน code ขึ้นใหม่ เพื่อให้ดูง่ายขึ้นนะครับ)
ในส่วนของการ binding คือ
$("input[type=button]").click(function(){ alert("Hello world"); }); // (1)
และในส่วนของการสร้าง element ตอน runtime คือ
$("#container").html("<input type='button' value='Click me'>"); // (2)
ปัญหาของกรณีนี้คือ การวางลำดับคำสั่งผิดครับ ลองนึกดูว่า ถ้าเรามีการเรียก code ส่วนที่ (1) ก่อน แล้วค่อยสร้าง element ในส่วน (2) สิ่งที่เกิดจาก (1) คือ มีการ bind event click ให้กับ $(“input[type=button]“) ไปแล้วครับ ในขณะที่ element นั้นยังไม่มีอยู่จริงในเว็บ ทำให้ปุ่มที่สร้างขึ้นมาใหม่ไม่ถูก bind ไปด้วยครับ
ปัญหานี้ทำให้ผมนึกถึงอีกกรณีศึกษาหนึ่งครับ ลองดู code ตามนี้ครับ
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<title> sample </title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$("input[type=button]").click(function(){alert("Hello world");})
</script>
</head>
<body>
<input type="button" value="click me">
</body>
</html>
ดูเผิน ๆ อาจจะไม่เห็นอะไรผิดปกติ แต่พิจารณาดูดี ๆ แล้ว คำสั่ง $(“input[type=button]“).click(function(){alert(“Hello world”);}) มันถูกสั่งให้ทำตั้งแต่โหลดหน้า page ยังไม่เสร็จ แน่นอน มันก็จะยังไม่รู้จักกับ <input type=”button” value=”click me”> เลยครับ ทำให้การ bind event ในลักษณะนี้ไม่เป็นผลเช่นกัน
การ bind event จะต้องเกิดหลังจากที่ element นั้นมีอยู่แล้ว ถึงจะใช้งานได้ครับ ในกรณีศึกษาแรก ผมได้แนะนำให้ไปเรียก binding หลังจากที่สร้าง element แืทน ส่วนกรณีหลัง ผมแนะนำให้ไปไว้ใน $.ready() ครับ
ลองไปดูตัวอย่างได้ใน LIVE DEMO ครับ
เป็นตัวอย่างที่ดีมากเลยคับ
ขอบคุณนะคับ ท่านประธาน
ผมจะพยายาม ต่อไป สู้ต่อไป ทาเคชิ
อิอิ
แรก ๆ ผมก็เคยพลาดแบบนี้เลยเหมือนกันครับ
พอเจอวิธีแก้ปุ๊บก็ขึ้นใจเลยครับ
สู้ ๆ ครับท่านโจ้
คับผม แล้วแบบนี้ ถ้าหากผมคิดจะใช้ ajax ที่ append DOM ต่อไปใน html แล้ว ผมก็ต้องไป bind หลัง call ajax มาแล้ว ช่ายป่าวคับ
การ Append DOM มันเป็นการสร้าง Element ใหม่ครับ ส่วนการ Bind มันจะเลือกเอา Element ตาม Selector จาก Element ที่มีอยู่ ณ ตอนนั้นครับ
ดังนั้น ถ้ามีการสร้าง Element ใหม่ ก็ต้อง bind ใหม่ครับ
งั้นเวลาเราเขียน Function เราก็เอาไปเขียนใน
[code]
$(document).ready(
function foo(){
//get dom from remote page
}
bind element
);
[/code]
แบบนี้ได้ป่าวครับ
ไม่ได้ครับ
เพราะว่า parameter ที่คุณส่งเข้า .ready() มันเป็น function แล้วครับ ตัว bind element ที่อยู่นอก function (แต่อยู่ใน ชุด parameter) จะทำให้เกิด error ครับ
ลองเอา bind element ไปไว้ใน foo ดูครับ
ผมเข้าใจคุณถูกใช่มั๊ยครับ