jQuery - 将事件处理程序附加到预先存在的click事件

时间:2011-03-03 16:26:33

标签: javascript jquery events

我已经定义了一个点击事件。我想知道在不触及此代码的情况下将另一个事件处理程序附加到此事件的最佳方法是什么(如果可能)。

有没有办法只将另一个事件处理程序附加到已定义的点击事件?

这是当前的点击事件定义:

 $(".HwYesButton", "#HwQuizQuestions")
        .append("<a href='javascript:void(0);' rel='.HwYesButton'>Yes</a>")
        .click(function(event) {
            var button = $(this).parent();
            var questionId = button.attr('id');
            $iadp.decisionPoint["HwQuizYourself"].Input.inputProvided(questionId);
            button.find(".HwNoButton").removeClass("HwButtonSelected");
            $(this).addClass("HwButtonSelected");
            button.removeClass("HwQuestionSkipped");

            $iadp.flat.setBoolean(questionId, true);
            return false;
        });

5 个答案:

答案 0 :(得分:30)

你唯一能做的就是附加另一个(额外的)处理程序:

$(".HwYesButton", "#HwQuizQuestions").click(function() {
    // something else
});

jQuery将按照它们附加到元素的顺序调用处理程序。

您无法“扩展”已定义的处理程序。


顺便说一下。你的表述有点不精确。您没有定义点击事件。您只附加点击事件处理程序 。当用户点击某个元素时,浏览器会生成click事件。

您可以为一个元素添加任意数量的点击处理程序。也许你已经习惯了普通的JavaScript:

element.onclick = function() {}

使用此方法,您确实只能附加一个处理程序。但我假设jQuery使用JavaScript provides some advanced event handling methods

答案 1 :(得分:6)

我知道这是一个老帖子,但也许这仍然可以帮助某人,因为我在搜索过程中仍然遇到了这个问题......

我正在尝试做同样的事情,除了我希望我的动作在现有的内联onClick事件之前触发。这是我到目前为止所做的,它在我的初步测试后似乎正常工作。它可能不会处理非内联的事件,例如受其他javascipt约束的事件。

        $(function() {
            $("[onClick]").each(function(){
                var x = $(this).attr("onClick");
                $(this).removeAttr("onClick").unbind("click");
                $(this).click(function(e){
                    // do what you want here...
                    eval(x); // do original action here...
                });
            });
        });

答案 2 :(得分:5)

您可以将另一个点击事件写入同一个事件,并且两者都会被触发。见here

<a id="clickme">clickme</a>
<script>
    $('#clickme').click(function () {
        alert('first click handler triggered');
    });
    $('#clickme').click(function () {
        alert('second click handler triggered');
    });
</script>

答案 3 :(得分:0)

Ajax可能会使问题复杂化。如果您调用两个事件,第一个事件是ajax调用,那么第二个事件可能会在响应返回之前触发。

所以即使事件是按照正确的顺序触发的,你真正需要的是进入ajax调用中的回调函数。

如果不编辑原始代码,很难做到。

答案 4 :(得分:0)

可以。假设我有一个标签云,点击标签会默认删除标签。像这样:

<div class="tags">
  <div class="tag">Tag 1</div>
  <div class="tag">Tag 2</div>
</div>

<script>
$(document).ready(function(){
  $('.tag').click(function(e){
    e.preventDefault();
    $(this).fadeOut('slow',function(){
      $(this).remove();
    });
    return false;
  });
});
</script>

现在,我们将其捆绑到一个项目的随附库中,但是您想提供一种开发人员友好的方法来拦截那些单击事件并提示用户一个AYS(您确定吗?)对话框。在您的脑海中,您可能会想到类似的东西:

<script>
$(document).ready(function(){
  $('.tag').beforeRemove(function(){
    if (AYS() === false) {
      return false; // don't allow the removal
    }
    return true; // allow the removal
  });
});
</script>

因此,解决方案是:

<div class="tags">
  <div class="tag">Tag 1</div>
  <div class="tag">Tag 2</div>
</div>

<script><!-- included library script -->
$(document).ready(function(){

  $.fn.beforeRemove = $.fn.click;

  $('BODY').on('click','.tag',function(e){
    e.preventDefault();
    console.log('debug: called standard click event');
    $(this).fadeOut('slow',function(){
      $(this).remove();
    });
    return false;
  });
});
</script>

<script><!-- included in your page, after the library is loaded -->
$(document).ready(function(){

  $('.tag').beforeRemove(function(){
    var sWhich = $(this).text();
    console.log('debug: before remove - ' + sWhich);
    return false; // simulate AYS response was no
    // change return false to true to simulate AYS response was yes
  });

});

</script>

在此示例中,诀窍是我们使用beforeRemove触发器的click触发器扩展了jQuery。接下来,通过使库利用$('BODY').on('click','.tag',function(e){...});处理程序,我们使其延迟并在触发页面的beforeRemove触发器之后调用。因此,如果AYS条件为负,则可以在false中返回beforeRemove,因此不允许click事件继续。

因此,运行上面的内容,您将看到单击标记不会删除该项目。现在,切换beforeRemove函数以返回true(就像您对AYS提示有肯定的响应一样),并且允许click事件继续。您已将事件处理程序附加到预先存在的click事件中。