取消后如何继续事件传播?

当用户点击某个链接时,我想给他们一个确认对话框。 如果他们点击“是”,我想继续原来的导航。 一个catch:我的确认对话框是通过返回一个jQuery.Deferred对象来实现的,只有当用户点击Yesbutton时才parsing。 所以基本上确认对话框是asynchronous的。

所以基本上我想要这样的东西:

$('a.my-link').click(function(e) { e.preventDefault(); e.stopPropogation(); MyApp.confirm("Are you sure you want to navigate away?") .done(function() { //continue propogation of e }) }) 

当然,我可以设置一个标志,并重新触发点击,但这是混乱的。 任何自然的方式呢?

以下是Chrome 13中实际工作的代码,令我惊讶的是。

 function handler (evt ) { var t = evt.target; ... setTimeout( function() { t.dispatchEvent( evt ) }, 1000); return false; } 

这是不是很跨浏览器,也许将来会被修复,因为它感觉像安全风险,恕我直言。

如果您取消事件传播,我不知道会发生什么。

如果我正确地理解了这个问题,我认为你可以把事件更新成你在那里closures的原始事件。 所以只需在.done函数中设置e = e.originalEvent。

https://jsfiddle.net/oyetxu54/

 MyApp.confirm("confirmation?") .done(function(){ e = e.originalEvent;}) 

这里是一个不同的例子(保持控制台打开,所以你可以看到消息)的小提琴:这对我在铬和Firefox

我通过这种方式在我的一个项目上解决了问题。 这个例子适用于一些基本的事件处理,比如点击等等。Handler的确认必须是第一个处理程序绑定的。

  // This example assumes clickFunction is first event handled. // // you have to preserve called function handler to ignore it // when you continue calling. // // store it in object to preserve function reference var ignoredHandler = { fn: false }; // function which will continues processing var go = function(e, el){ // process href var href = $(el).attr('href'); if (href) { window.location = href; } // process events var events = $(el).data('events'); for (prop in events) { if (events.hasOwnProperty(prop)) { var event = events[prop]; $.each(event, function(idx, handler){ // do not run for clickFunction if (ignoredHandler.fn != handler.handler) { handler.handler.call(el, e); } }); } } } // click handler var clickFunction = function(e){ e.preventDefault(); e.stopImmediatePropagation(); MyApp.confirm("Are you sure you want to navigate away?") .done(go.apply(this, e)); }; // preserve ignored handler ignoredHandler.fn = clickFunction; $('.confirmable').click(clickFunction); // a little bit longer but it works :) 

我解决了这个问题:

  1. 将事件监听器放在父元素上
  2. 只有在用户确认时才从链接中删除课程
  3. 在我删除课程后重新点击链接。
 function async() { var dfd = $.Deferred(); // simulate async setTimeout(function () { if (confirm('Stackoverflow FTW')) { dfd.resolve(); } else { dfd.reject(); } }, 0); return dfd.promise(); }; $('.container').on('click', '.another-page', function (e) { e.stopPropagation(); e.preventDefault(); async().done(function () { $(e.currentTarget).removeClass('another-page').click(); }); }); $('body').on('click', function (e) { alert('navigating somewhere else woot!') }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <a href="#" class="another-page">Somewhere else</a> </div> 

我们在项目中有类似的要求,这对我有用。 在Chrome和IE11testing。

 $('a.my-link').click(function(e) { e.preventDefault(); if (do_something === true) { e.stopPropogation(); MyApp.confirm("Are you sure you want to navigate away?") .done(function() { do_something = false; // this allows user to navigate $(e.target).click(); }) } }) 

这是未经testing,但可能作为您的解决方法

 $('a.my-link').click(function(e) { e.preventDefault(); e.stopPropogation(); MyApp.confirm("Are you sure you want to navigate away?") .done(function() { //continue propogation of e $(this).unbind('click').click() }) })