5

In Javascript, how can I attach an event handler so that it gets run after the default action?

<form target="_blank" action="submit.php" onsubmit="doThisAfterSubmit()">
    <input type="submit" onclick="doThisAfterSubmit()" />
</form>

Similar but insufficient Stack Overflow questions:

javascript: Possible to add event handler that runs after the default behavior?

How to catch event after default action was performed in JavaScript

I have read these but they are dealing with keystroke events solved with using a variation such as keyup over keypress. The only other solution I have seen is the setTimeout() method. I want to avoid using setTimeout() in favor of a more elegant solution if one exists.

My use case is that I want to remove the form from the DOM after the submit.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
km6zla
  • 4,787
  • 2
  • 29
  • 51
  • What do you mean by "after the default behaviour"? When the POST request has been sent? When the response has been received? – lonesomeday Jun 12 '13 at 22:20
  • 2
    Once the submit has completed, another page is loaded, and your javascript is lost, so the answer is simple, you can't! – adeneo Jun 12 '13 at 22:22
  • 2
    @adeneo Hint: look at the form's `target` attribute. – lonesomeday Jun 12 '13 at 22:24
  • Give the form an ID (lets use `test`), `onclick="document.getElementById('test').style.display = 'none';"`. Form gets submitted, disappears. – tymeJV Jun 12 '13 at 22:25
  • `onsubmit="this.style.display = 'none';"` works perfectly. Perhaps the problem is in your `doThisAfterSubmit()` function? – NikitaBaksalyar Jun 12 '13 at 22:29
  • @lonesomeday You get it. The form is posting to a new tab/window. I know how to hide a window and that is not what I am doing. I am removing it from the DOM. – km6zla Jun 12 '13 at 23:08
  • I want the event handler to run as soon as the request has been sent. – km6zla Jun 12 '13 at 23:08

2 Answers2

4

You could perform the default action yourself, then do what you want, and then prevent the default action from running.

<form target="_blank" action="submit.php"
        onsubmit="this.submit(); doThisAfterSubmit(this); return false;">
    <input type="submit" />
</form>

Note: Calling this.submit() in "onsubmit" will not cause an infinite loop as you might think.

jsfiddle demo

EDIT: My original jsfiddle was only displaying text after the form submit. I tried it again, but changed it to remove the form like you want. That caused the form to no longer submit, even though this.submit() was called first. In that case, you can use setTimeout() to delay the removal of the form until the original thread is finished executing, like this:

function doThisAfterSubmit(form) {
    setTimeout(function() {
        $(form).remove();
    }, 0);
};

Now the form is submitted before it is removed.

jsfiddle demo

John S
  • 21,212
  • 8
  • 46
  • 56
  • The first part of your answer got me excited, then having to use `setTimeout()` bummed me out. Then I tried your second fiddle and removed the `setTimeout()` and just ran `$(form).remove()` and it worked perfectly! – km6zla Jun 13 '13 at 15:36
  • @ogc-nick - I wondered if it would work differently on different browsers, and apparently it does. It works without `setTimeout()` on Chrome 27 and IE 10, but not on Firefox 27. – John S Jun 13 '13 at 16:28
  • Ah very interesting. Yes I was testing it in chrome. My target browser is Firefox unfortunately, I just didn't expect FF and Chrome to differ on the point. I still like the approach though. – km6zla Jun 13 '13 at 20:33
  • What about for events that are not cancellable? – Pasha Skender Apr 20 '17 at 16:11
  • @LorenShqipognja - What kind of event are you thinking of? – John S Apr 20 '17 at 21:11
  • @JohnS DOMNodeRemoved for example (although deprecated still used for older browsers that do not support the observer pattern). In this scenario the node is not actually removed until the event has finished executing and bubbling, and I cannot seem to find a way to have a callback execute after it is completed. – Pasha Skender Apr 24 '17 at 21:27
1

You can use event bubbling instead:

<div onclick="this.remove();">
  <form target="_blank" action="submit.php" onsubmit="alert('submitted);">
    <input type="submit" />
  </form>
</div>
bert bruynooghe
  • 2,985
  • 1
  • 20
  • 18