jQuery点击事件阻止默认行为

8
如果我有一个标签:
<a id="delete-event" href="/delete/1234">Delete</a>

还有一些JavaScript代码,用于提示是否确认删除:

 $("#delete-event").click(function(e) {
    e.preventDefault();

    bootbox.confirm("Are you sure you wish to delete this?", function(confirmed) {
        if(confirmed) {
            return true;
        }
    }); 
});

我认为执行e.preventDefault()应该可以阻止a href的触发,但事实并非如此。当我点击a标签时,它只是简单地跳转到URL,而不执行JavaScript。我该怎么做才能让它起作用?
谢谢。

你的jQuery是在a被渲染到页面之后还是在ready事件内? - Brandon
是的,上面的JS代码位于$(document).ready()函数内部。 - Justin
bootbox.confirm 替换为 JS 警告以查看是否可以到达该点。我认为在执行 preventDefault() 后,return true 不会导致链接触发。 - sachleen
有没有一种jQuery的方式可以使用e对象触发事件,而不需要使用window.location的hack方法? - Justin
@Justin,说实话我不确定,但我不认为使用window.location是一种hack。我知道你可以使用.trigger(),但那也会再次执行你的代码。 - sachleen
显示剩余2条评论
5个回答

15

这段代码可行:

在执行了 e.preventDefault() 后,你不能只简单地执行 return true 并期望链接能够触发。我不得不使用JS confirm替换你的 bootbox.confirm(),但它应该仍然有效。

$("#delete-event").click(function(e) {
    e.preventDefault();
    var a = confirm("yes?");
    if(a) window.location = $('#delete-event').attr('href');
});​

演示

尝试用我提供的代码块替换您的代码块。如果那样可以工作,把你的bootbox确认放回去再试一次。这将告诉您错误出在哪里。


7

只有在必要的时候才最好进行预防。例如,如果用户从确认框中选择了“取消”,则应该防止默认操作。

$("#delete-event").click(function(e) {
    if (!confirm('Are you sure you wish to delete this?')) {
        e.preventDefault();
    } 
});​

演示: http://jsfiddle.net/SCCDX/

通常,在需要确认时,这是最好的实现方式,对于提交表单之前的确认更加有用。

我不确定 bootbox 是否复制了浏览器在请求确认时的行为。所以在这种情况下可能无法正常工作。如果是这种情况,更好的方法是在某个地方设置一个标志。

$("#delete-event").click(function(e) {
    if (!$(this).data('confirmed')) {
       e.preventDefault()
    } else {
       bootbox.confirm("Are you sure you wish to delete this?", function(confirmed) {
          if(confirmed) {
              $(this).data('confirmed', 1).click();           
          }
       });        
    }
});​

// Disclaimer: This code is untested. clicking on the link may cause data loss. lol 

我不太喜欢使用window.location方法,因为它可能会导致其他附加在该元素上的事件失败。


2

我也遇到了这个问题。

你可以使用window.location让浏览器访问新页面,但当前页面不会被记录在浏览器历史记录中(至少在谷歌浏览器中是如此)。

因此,我赞同SMathew的观点,应该触发新事件。但由于某些安全原因,由jQuery触发的锚点点击事件不能使浏览器访问新页面。最后,我发现以下代码可行。

$("a.confirm").on('click', function(e) {
    if (!$(this).data('confirmed')) {
        e.preventDefault();
        var a = this;
        bootbox.confirm("Are you sure?", "No", "Yes", function(result) {
            if(result) {
                $(a).data('confirmed', 1);
                if (document.createEvent) {
                    var evObj = document.createEvent('MouseEvents');
                    evObj.initEvent('click', true, true);
                    a.dispatchEvent(evObj);
                }
                else if (document.createEventObject) {
                    a.fireEvent('onclick');
                }
            }
        });
    }
});

我刚在Google Chrome中测试了以上代码,并从https://getsatisfaction.com/issuu/topics/opening_the_issuu_smartlook_viewer_with_my_flash_website?utm_content=topic_link&utm_medium=email&utm_source=reply_notification找到了fire event代码。

MORE

我发现这篇文章https://dev59.com/RnRA5IYBdhLWcg3w8ikl#18132076,并且可以使用jQuery.simulate来解决这个问题。我的最终代码如下:

$("[data-toggle=confirm]").on('click', function(e) {
    var a = $(this);
    if (!a.data('confirmed')) {
        e.preventDefault();

        var question = a.data('question');
        if (!question) question = 'Are you sure?';

        var yes = a.data('yes');
        if (!yes) yes = 'Yes';

        var no = a.data('no');
        if (!no) no = 'No';

        bootbox.confirm(question, no, yes, function(result) {
            if(result) {
                a.data('confirmed', 1).simulate('click');
            }
        });
    }
});

它适用于锚点和表单按钮。


0

尝试这段代码:

$(".SelectedPassengers").each(function () {
            debugger;

        if ($(this).text() == "") {
            debugger;
            var id = this.id.split('-');
            alert("Please Select Passenger " + id[1]);
            var h = "" + this.id;
          // $(this).preventDefault();
           //$('#' + h).focus();
           //this.preventDefault();
           stopEvent = "enter";
        }

    });
    if (stopEvent != "") {
        stopEvent = "";
        event.preventDefault();
        return false;
    }

0

对于锚点标签,您需要使用return false;

请参见this jsFiddle


奇怪。我今天遇到了同样的问题,返回 false 解决了它。 - Dean Brundage
return false 只有当你有类似于 <a href="page.html" onclick="alert('hi'); return false;">afd</a> 的东西时才能起作用,但 e.preventDefault() 已经解决了这个问题。 - sachleen
我的情况也类似:一个jQuery点击处理程序,而不是内联javascript。 - Dean Brundage
@DeanBrundage 在这段代码中,仅使用 return false(在结尾处)也可以工作。我只是想说没有必要两个都用。我需要看看你的代码才能知道发生了什么。 - sachleen

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