jQuery的click事件只触发一次

6

从查看其他帖子的经验中,我尝试在我的代码中添加live()和on(),但点击功能只能运行一次,然后就无法再次运行。请问有人能指出我哪里做错了吗?这是我的最新代码:

<script language="javascript">
//Used to delete a step from the database after confirming with user
$(document).ready(function(){
    $("#success_message2").hide();
    $(".delete_it").on('click',function() {
    var answer = confirm('Are you sure you want to delete this step?');
    if (answer){
          var data = {
              'hospid': '<? echo $hospid; ?>',
              "step_id" : $(this).parent().attr("name")
              }; 
        $.post("../php/progress_steps_delete.php",
                data,
                function (data) {
                    if (data.success) {
                        $("#success_message2").show('slow');
                        setTimeout(function () {
                            $("#success_message2").hide('slow');
                        }, 5000);
                        $('#step_list').html(data.success);
                    } else {
                        alert('not done');
                        $("#non-grid").prepend(data.error);
                    }
                }, "json");
    }
});
});
</script>

抱歉,这是HTML格式的文字。
抱歉,这是HTML格式的文字。
<body>
<div id="body-wrapper">
  <?php include_once(getBasePath()."site_hospital_files/elements/navbar.php"); ?>
  <div id="main-content">
    <div class="content-box">
      <div class="content-box-header">
        <h3>Progress Steps</h3>
      </div>
      <div class="content-box-content">
        <div class="msg-status div_message" id="success_message">New step added successfully!</div>
        <div class="msg-status div_message" id="success_message1">New List Order Updated!</div>
        <div class="msg-status div_message" id="success_message2">Step Deleted!</div>
        <div id="non-grid">
          <form method="post" name="upload_form" id="upload_form">
            <fieldset style="height:100px;  margin-left:25px; margin-top:15px; background-color:#FFF;">
              <legend style="padding:2px;">Add a Step</legend>
              <div class="column-left" style="width:50%;">
                <label class="space">Step Name</label>
                <input class="text-input tall-input required alnum" type="text" id="step_add" name="step_add" style="width:90%;"/>
              </div>
              <div class="column-left" style="width:20%; padding-top:25px;">
                <input type="hidden" name="hosp" id="hosp" value="<? echo $hospid; ?>"/>
                <input type="submit" id="snd_upload" name="snd_upload" value="Submit Step" class='button'  />
              </div>
            </fieldset>
          </form>
          <form name="delete_form" method="post" id="delete_form">
            <fieldset style="height:100%;  margin-left:25px; margin-top:15px; background-color:#FFF;">
              <legend style="padding:2px;">List of Steps</legend>
              <h3>Drag and Drop to Change Step Order</h3>
              <input type="hidden" name="hosp" id="hosp" value="<? echo $hospid; ?>"/>
              <div id="step_list">
              <? echo $step_list ?>
              </div>
            </fieldset>
          </form>
        </div>
      </div>
    </div>
    <div class="clear"></div>
    <div id="footer">&#169; Copyright 2012  Inc. | <a href="#">Top</a></div>
  </div>
</div>
</body>

好的,第二次编辑,我认为我开始理解问题了。以下是生成列表的 PHP 代码。而我要点击的元素被嵌套在容器中。我不想点击整个容器,只想点击图片内部。这是否可能?感谢迄今为止所有的建议。我正在学习...

function getSteps($dbh, $hospid)
{
    $sql1 = $dbh->prepare('
    SELECT COUNT(*) 
    FROM progress_steps
    WHERE hospital_id = :hospid
    ');
    $sql1->bindValue('hospid', $hospid);
    $sql1->execute();   
    $num_rows = $sql1->fetchcolumn();

    $sql = $dbh->prepare('
    SELECT * 
    FROM progress_steps
    WHERE hospital_id = :hospid
    ORDER BY step_number
    ');
    $sql->bindValue('hospid', $hospid);
    $sql->execute();
    if ($num_rows > 0) {
        $steps_table = '';
        $isOdd           = true;
        while (($row = $sql->fetch(PDO::FETCH_ASSOC)) !== false) {
            $steps_table .= "<div class='hover_hand' name='$row[step_id]' id='item_$row[step_id]'><div style='float:left' class='delete_it'><img src='../images/delete_icon.gif'></div> <div style='float:left' class='middle_text'>&nbsp;&nbsp;&nbsp;&nbsp;$row[step_name]</div><input type='hidden' name='itemid[]' value='$row[step_id]'/></div>";
        };
     } else {
        $steps_table = '';
            $steps_table .= "<div>You need to add steps.</div>";
    };
    return $steps_table;
}

1
我们需要你的HTML代码。该事件绑定在一个DOM元素上,很可能会被移除和重新添加,而不带有绑定的事件。 - Cymen
我正在使用Firebug,但它默默地失败了。控制台上没有任何弹出窗口。 - Dev Newb
3个回答

19

我假设(根据你的代码).delete_it元素在#step_list元素内部。

当你用ajax结果替换它的html时,也会删除绑定的事件处理程序。

你需要将处理程序绑定到DOM层次结构中不会被移除的元素上,例如#step_list本身。

因此,将绑定从以下内容更改:

$(".delete_it").on('click',function() {

$("#step_list").on('click','.delete_it', function() {

1
非常感谢您完美的回答和解决方案,它非常有效。非常感谢! - Dev Newb

3

从这里看不清楚,请问您能分享一下HTML代码吗?如果不知道data.success包含什么,那么也不容易理解。.html(data.success)会影响删除按钮吗?

您确定使用.live()方法正确吗?

$('.delete_it').live("click",function(){

});

如果您能提供更多信息,我或许可以帮上忙。

是的,我知道。但我永远无法理解为什么他们会弃用.live()。它有效,并且我从未见过它失败。它也非常简单,只需使用$.live,就像$.click()一样。$('.some class parent').on带有可选参数,对我来说太长了。哈哈,但你说得也对。 - Wap
我刚刚阅读了文档,毕竟它有一些缺点。但是我很固执,我会一直坚持使用.live(),直到它反噬我。 :D - Wap

2

事件绑定到DOM节点。如果你绑定的DOM被移除,相关联的事件也可能会被移除。你可以解决这个问题,或者利用DOM事件的“冒泡”特性来解决。例如,假设我的HTML如下:

<div id="container">
  <div class="item delete_me_on_click"></div>
  <div class="item delete_me_on_click"></div>
  <div class="item delete_me_on_click"></div>
</div>

我可以做的是绑定到#containerdocument以监听任何点击事件,并检查事件的目标以确定是否要采取行动。以下是上述HTML的示例:

$('#container').on('click', function (event) {
    var target = $(event.target);
    if (target.hasClass('delete_me')) {
        target.remove();
    }            
});​

这与以下内容相同:

$('#container').on('click', '.delete_me', function (event) {
    $(event.target).remove();      
});​

我可以在文档级别进行监听:

或者,我甚至可以在文档级别进行监听:

$(document).on('click', '.delete_me', function (event) {
    $(event.target).remove();      
});​

这里有一个可行的示例:http://jsfiddle.net/Kcapv/

请注意,如果在子节点上使用event.stopPropagation()将停止事件冒泡,因此如果您尝试使用此方法,需要小心观察stopPropagation的使用。


"live"已经被弃用了吗?我应该使用“on”吗,还是只能使用“live”?谢谢! - Dev Newb
显然这是根据jQuery网站的说法。on应该可以作为替代品。 - Cymen
你的帖子真的帮助我理解了这里发生了什么。所以我添加了我的php代码。我有一个嵌入在容器中的图像,我想触发该函数。如何在不点击整个容器或遇到仅触发一次的问题的情况下访问该元素? - Dev Newb
我们没有足够的信息来回答你的问题。这是你在 jsfiddle 上提供给我们的代码:http://jsfiddle.net/2NGe7/ 请注意,没有带有“delete_me”类名的元素,因此我们无法重现你的问题。 - Cymen
非常感谢你的帮助,你确实让我走上了正确的道路。Gaby 把所有东西都很好地整合在一起。谢谢你的建议! - Dev Newb
使用 jQuery(document).on 对我很有用。谢谢。 - Shawn W

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接