Skip to content


Event Binding อย่างไรให้ใช้ได้จริง

ผมขออนญาตนำคำถามจากเมลของสมาชิก 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 ครับ

Share

Posted in Events, jQuery.

Tagged with , , , .


6 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. ๋j Joe says

    เป็นตัวอย่างที่ดีมากเลยคับ

    ขอบคุณนะคับ ท่านประธาน
    ผมจะพยายาม ต่อไป สู้ต่อไป ทาเคชิ

    อิอิ

  2. chonla says

    แรก ๆ ผมก็เคยพลาดแบบนี้เลยเหมือนกันครับ
    พอเจอวิธีแก้ปุ๊บก็ขึ้นใจเลยครับ

    สู้ ๆ ครับท่านโจ้

  3. ๋j Joe says

    คับผม แล้วแบบนี้ ถ้าหากผมคิดจะใช้ ajax ที่ append DOM ต่อไปใน html แล้ว ผมก็ต้องไป bind หลัง call ajax มาแล้ว ช่ายป่าวคับ

  4. chonla says

    การ Append DOM มันเป็นการสร้าง Element ใหม่ครับ ส่วนการ Bind มันจะเลือกเอา Element ตาม Selector จาก Element ที่มีอยู่ ณ ตอนนั้นครับ

    ดังนั้น ถ้ามีการสร้าง Element ใหม่ ก็ต้อง bind ใหม่ครับ

  5. noompkbn9 says

    งั้นเวลาเราเขียน Function เราก็เอาไปเขียนใน
    [code]
    $(document).ready(
    function foo(){
    //get dom from remote page
    }
    bind element
    );
    [/code]
    แบบนี้ได้ป่าวครับ

  6. chonla says

    ไม่ได้ครับ

    เพราะว่า parameter ที่คุณส่งเข้า .ready() มันเป็น function แล้วครับ ตัว bind element ที่อยู่นอก function (แต่อยู่ใน ชุด parameter) จะทำให้เกิด error ครับ

    ลองเอา bind element ไปไว้ใน foo ดูครับ

    ผมเข้าใจคุณถูกใช่มั๊ยครับ



Some HTML is OK

or, reply to this post via trackback.

*