如何在使用jQuery“打开”时阻止点击事件被触发?

时间:2012-05-14 12:00:24

标签: jquery

我有一个消息主题表,我已经使每个tr可点击导航到消息详细信息页面。但是,还有一个垃圾图标,用户可以通过$ .ajax点击以标记要删除的消息,这是通过首先关闭tr事件处理程序来完成的。问题是当重新启动tr click事件处理程序时,处理单击并导航用户到详细信息页面。

我试图添加e.stopPropogation();在$ .ajax调用之后和tr的“on”设置之前,这会阻止事件被打开。之后添加它不会阻止所需的行为。

所以我的问题是,如何在关闭之后将点击事件“打开”为tr,但不会在此过程中关闭事件。

代码:

$("#messageTable tbody tr").on("click", function () {
        var id = $(this).find('td:first').find('input').val();
        window.location.replace('/Messages/Read/'+id);
    });

    $('.icon-trash').on("click", function (e) {

        // turn off tr click to prevent navigation
        $("#messageTable tbody tr").off("click");

        // grab the message Id from the hidden input
        var messageId = $(this).parent().find('input').val();
        var tr = $(this).parent().parent();

        var request = $.ajax({
            url: "MarkMessageForDeletion"
            , type: "GET"
            , data: { id: messageId }
            , dataType: "json"
            , async: true
            , success: function (data) {
                if (data === "1") {
                    tr.remove();
                }
            }
        });

        // turn click back on 
        $("#messageTable tbody tr").on("click", function () {
            var id = $(this).find('td:first').find('input').val();
            window.location.replace('/Messages/Read/' + id);
        });           
    });

2 个答案:

答案 0 :(得分:0)

由于垃圾桶图标是tr的后代,因此无需关闭该行上的事件处理程序。只需从垃圾桶图标点击处理程序中调用stopPropagation()(注意拼写,也许这就是为什么它不适合你?)。

$("#messageTable tbody tr").on("click", function () {
    var id = $(this).find('td:first').find('input').val();
    window.location.replace('/Messages/Read/'+id);
});

$('.icon-trash').on("click", function (e) {

    // prevent the click reaching the row
    e.stopPropagation();

    // grab the message Id from the hidden input
    var messageId = $(this).parent().find('input').val();
    var tr = $(this).parent().parent();

    var request = $.ajax({
        url: "MarkMessageForDeletion"
        , type: "GET"
        , data: { id: messageId }
        , dataType: "json"
        , async: true
        , success: function (data) {
            if (data === "1") {
                tr.remove();
            }
        }
    });
});

Gratuitous live example


对于它的价值,您可以使用var tr = $(this).closest('tr');而非.parent().parent()使代码更健壮。 closest找到最匹配的祖先。

答案 1 :(得分:0)

我假设您在.icon-trash内有#messageTable tbody tr个元素,您可能想要做的是阻止它们冒泡并忘记off("click")调用:

$("#messageTable tbody tr").on("click", function () {
    var id = $(this).find('td:first').find('input').val();
    window.location.replace('/Messages/Read/'+id);
});

$('.icon-trash').on("click", function (e) {
    e.stopPropagation(); 

    // grab the message Id from the hidden input
    var messageId = $(this).parent().find('input').val();
    var tr = $(this).parent().parent();

    var request = $.ajax({
        url: "MarkMessageForDeletion"
        , type: "GET"
        , data: { id: messageId }
        , dataType: "json"
        , async: true
        , success: function (data) {
            if (data === "1") {
                tr.remove();
            }
        }
    });

    // I also like to return false from the handler,
    // which is an old-school way of e.stopPropagation()
    return false;
});

发生的事情是点击是在按钮上处理的,冒泡了,它也在tr元素上处理。 e.stopPropagation();return false;语句会阻止它发生,它不会冒出来。 offon调用没有改变这种行为,因为它们实际上并没有停止冒泡(在返回此函数后冒泡开始)。