How to continue event propagation after cancelling?

前端 未结 8 692
孤街浪徒
孤街浪徒 2020-12-13 11:41

When a user clicks a certain link I would like to present them with a confirmation dialog. If they click \"Yes\" I would like to continue the original navigation. One catch:

8条回答
  •  攒了一身酷
    2020-12-13 12:30

    I solved this by:

    1. placing a event listener on a parent element
    2. removing the class from the link ONLY when the user confirms
    3. reclicking the link after I have removed the class.

    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!')
    });
    
    
    

    The reason I added the event listener to the parent and not the link itself is because the jQuery's on event will bind to the element until told otherwise. So even though the element does not have the class another-page it still has the event listener attached thus you have to take advantage of event delegation to solve this problem.

    GOTCHAS this is very state based. i.e. if you need to ask the user EVERYTIME they click on a link you'll have to add a 2nd listener to readd the another-page class back on to the link. i.e.:

    $('body').on('click', function (e) {
      $(e.currentTarget).addClass('another-page');
    });
    

    side note you could also remove the event listener on container if the user accepts, if you do this make sure you use namespace events because there might be other listeners on container you might inadvertently remove. see https://api.jquery.com/event.namespace/ for more details.

提交回复
热议问题