jQuery - onclick: เหตุใดจึงดำเนินการคลิกทันทีเมื่อเพิ่มตัวจัดการ

คำถาม:

ฉันประสบปัญหาเล็กน้อยกับ jQuery: ลองพิจารณา HTML นี้ โดยที่ฉันต้องการคลิกซ้ายที่ "https" เปลี่ยนค่าแล้วคลิกตกลง เมื่อตกลง ควรลบกล่องข้อความออก และแนบตัวจัดการ onclick อีกครั้ง สิ่งนี้เป็นเช่นนั้น แต่ onclick ได้รับการออกแล้วโดยการคลิกปัจจุบัน...

ทำไม ? และจะทำอย่างไรให้ถูกต้อง?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Tabelle editieren</title>
    <!--
    <script src="jquery-1.4.4.min.js" type="text/javascript"></script>
    -->
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.js"></script>  

    <style type="text/css" media="all">
        html {margin: 0px; padding: 0px; height: 100%;}
        body {margin: 0px; padding: 0px; height: 100%;}
        input{margin: 0px; padding: 0px; }

        tr:nth-child(2n+1) {background-color: #F0F0F0;}
        tr:nth-child(2n)   {background-color: #FEFEFE;}

        td
        {
            margin: 0px; padding: 0.5cm; padding: 0px; text-align: left; 
        }


    </style>

    <script type="text/javascript" language="javascript">

        function hello(me) {
            //alert("hello");
            var str = $(me).text();
            //alert(str);
            $(me).html("<input id=\"my1\" type=\"text\" style=\"width: 198px; height: 100%;\" value=\"" + str + "\" /><input id=\"my1confirm\" type=\"button\" onclick=\"bye(this);\"style=\"width: 35px;\" value=\"" + "OK" + "\" />");
            $(me).attr('onclick', '').unbind('click');

            return false;
        }


        function bye(me) {
            var objTR = $(me).parent();

            //var tb = $(me).closest('table');
            var tb = objTR.find('input');
            var str = tb.val();
            tb.remove();

            objTR.text(str);
            alert("TODO: sending change event with { id : \"" + objTR.attr('id') + "\", str : \"" + str + "\" } to server");


            /*
            objTR.click(function () {
                alert("hi");
                return false;
            });
            */


            objTR.attr('onclick', '').bind("click", function (e) {
                e.preventDefault();
                alert("it shouldn't  execute this in this click, but it does... ");
                //hello(this);
                //event.stopImmediatePropagation();
            });

            return false;
        }


        $(document).ready(function () {
            //$('#myDataTable').dataTable().makeEditable();

        });
    </script>

</head>
<body style="margin: 0.5cm;">
    <h1>Application configuration</h1>
    <!--

    -->
    <table border="1" style="border-collapse: collapse;" >
      <thead>
        <tr style="background-color: Black; color:White; font-weight: bold; text-transform: capitalize;">
          <th style="width: 235px; text-align: left;">key</th>
          <th style="width: 235px; text-align: left;">value</th>
        </tr>
      </thead>
      <tfoot>
        <tr style="background-color: Black; color:White; font-weight: bold; text-transform: capitalize;">
          <th style="text-align: left;">key</th>
          <th style="text-align: left;">value</th>
        </tr>
      </tfoot>
      <tbody>
        <tr>
          <td>Environment</td>
          <td id="server">testing</td>
        </tr>

        <tr>
          <td>Protocol</td>
          <td id="Protocol" onclick="hello(this);">https</td>
        </tr>

        <tr>
          <td>UserHashMode</td>
          <td id="UserHashMode">true</td>
        </tr>

        <tr>
          <td>Logo</td>
          <td id="Logo">LogoFileCustomerN.png</td>
        </tr>

      </tbody>
    </table>
</body>
</html>

person Stefan Steiger    schedule 27.06.2012    source แหล่งที่มา
comment
คุณได้ลองใช้วิธีการ .on() หรือ .delegated() แล้วหรือยัง? ฉันไม่สามารถลองได้ เพราะฉันไม่ได้นั่งอยู่บนคอมพิวเตอร์   -  person Reporter    schedule 28.06.2012
comment
เนื่องจากคุณใช้ jQuery 1.7.1 ให้ลองใช้ .prop() หรือ .removeProp() แทนที่จะเป็น .attr() การลบหรือการรีเซ็ตแอตทริบิวต์ไม่ได้หมายความว่าค่าคุณสมบัติที่เกี่ยวข้องจะมีการเปลี่ยนแปลงเสมอไป   -  person Jonathan Lonowski    schedule 28.06.2012
comment
@reporter: ใช้งานได้จนถึงตอนนี้ แต่ตอนนี้ฉันไม่สามารถเอามันออกไปได้อีกต่อไป ฮ่าๆ ;)   -  person Stefan Steiger    schedule 28.06.2012


คำตอบ (3)


ดูเหมือนว่าตัวจัดการเหตุการณ์อินไลน์ไม่สามารถยกเลิกการผูกมัดโดย jQuery: การเลิกผูกอินไลน์ onClick ไม่ทำงาน เจคิวรี?

ดังนั้นฉันไม่แน่ใจว่ามันจะได้ผลหรือไม่ แต่แทนที่จะใช้:

.attr("onclick", "")

พยายาม:

.removeAttr("onclick")

แจ้งให้เราทราบหากมีการเปลี่ยนแปลงสิ่งใด

อัปเดต:

ฉันสร้าง jsFiddle เพื่อแสดงให้คุณเห็นว่ามันจะทำงาน "ง่ายขึ้น" ได้อย่างไร: http://jsfiddle.net/S2ARR/3/

ส่วนใหญ่ขึ้นอยู่กับบางสิ่ง เช่น การใช้โครงสร้างของฉัน - ใส่ช่วงภายในคอลัมน์แทนที่จะใช้คอลัมน์สำหรับทุกสิ่ง ฉันไม่ได้ใช้รหัสขององค์ประกอบสำหรับการเลือก jQuery เพราะฉันไม่แน่ใจว่าทำไมคุณถึงไม่เป็นเช่นนั้น หากคุณตั้งค่ารหัสขององค์ประกอบและจำเป็นต้องเข้าถึงองค์ประกอบเหล่านั้น คุณอาจใช้ตัวเลือกรหัสใน jQuery ได้เช่นกัน ดังนั้นคุณไม่จำเป็นต้องใช้ .parent() หรือ .find() ในตัวอย่างของฉันหากคุณเพิ่งใช้ id หวังว่านี่คือสิ่งที่คุณกำลังมองหา ฉันคิดว่าสิ่งสำคัญคือการเรียก .stopPropagation() ไม่เช่นนั้นดูเหมือนว่าจะไม่ทำงาน

person Ian    schedule 27.06.2012
comment
เพิ่งอัปเดตและให้ตัวอย่างเล็กๆ น้อยๆ ของสิ่งที่คุณกำลังมองหา แก้ไขโค้ดของคุณเล็กน้อย ดูเหมือนว่าจะได้ผลสำหรับฉัน! - person Ian; 28.06.2012
comment
ใช่แล้ว .stopPropagation() คือความมหัศจรรย์ที่แท้จริง PS: ดูเหมือนว่าจะทำงานได้ดีกับ td แทนที่จะเป็น span ของคุณเป็น HTML ที่ไม่ถูกต้อง - person Stefan Steiger; 28.06.2012
comment
ขึ้นอยู่กับคุณว่าคุณต้องการผูกเข้ากับทั้งหมด ‹td› หรือ ‹span› HTML ของฉันไม่ถูกต้องอย่างไร - person Ian; 28.06.2012

ฉันเปลี่ยนกิจกรรมของคุณเป็นการมอบหมาย ลบ onclick ออกจากตาราง และเรียกมันโดยใช้ jquery อย่างไรก็ตาม ฉันไม่แน่ใจว่าสิ่งที่ฉันได้รับคือพฤติกรรมความปรารถนาของคุณหรือไม่

jsfiddle

อัปเดต

สวัสดี ฉันอัปเดตด้วยพฤติกรรมที่ต้องการแล้ว

โซลูชัน

person KoU_warch    schedule 27.06.2012
comment
@Quandary ups ขออภัยฉันทำให้มันใช้งานได้แล้ว! หวังว่าจะสามารถช่วยได้นิดหน่อย - person KoU_warch; 28.06.2012

แทนที่จะผูกเหตุการณ์ผ่านแอตทริบิวต์ onclick คุณสามารถผูกเข้ากับเซลล์ตารางด้วย jquery ได้

$(function(){
    $("#Protocol").click(function(){ 
       // your content
    });
});

จากนั้นคุณสามารถรับประกันได้ว่าคุณจะสามารถเลิกผูกกิจกรรมด้วยการเลิกผูกในภายหลังได้

person Thinking Sites    schedule 27.06.2012
comment
ฉันได้ลองแล้ว มันไม่ได้สร้างความแตกต่าง... การเลิกผูกก็ใช้ได้ แต่ปัญหาคือเมื่อฉันพยายามจะผูกใหม่ - person Stefan Steiger; 28.06.2012
comment
ปัญหาพื้นฐานของคุณคือมันไม่คลายตัวใช่ไหม? ฉันมีเวลาที่ยากลำบากในการอ่านคำอธิบายของคุณ - person Thinking Sites; 28.06.2012
comment
ไม่ มันคลายออกอย่างถูกต้อง การรีไฟแนนซ์คือปัญหา ทันทีที่ฉัน rebind ฉันจะได้รับการดำเนินการคลิกโดยไม่ต้องคลิก... - person Stefan Steiger; 28.06.2012
comment
อ้อเข้าใจแล้ว. ให้ฉันดูเรื่องนี้แล้วกลับไปหาคุณ - person Thinking Sites; 28.06.2012