How do you change the order of events of the same event?

The jquery bind is amazing, but I donโ€™t know in what order the binding occurs. My current problem is:

$(document.body).delegate('form', methods.checkForm); $('form').bind('submit', methods.submitFormIfCheckedFormIsTrue); methods.checkForm = function (e) { if (!$(this).isVerified()) { return false; } return true; }; methods.submitFormIfCheckedFormIsTrue = function (e) { e.preventDefault(); $.ajax("/submitForm", { data:$(this).serialize(), type:"post" }); }; 

This is obviously not the actual code that I use, but it is pretty close. It happens that the submitFormIfCheckedFormIsTrue function starts before or during the checkForm function, so checking is pretty useless. My hack for this was to add the โ€œverifiedโ€ class to the form and check if the form has this class in another function ... but then you click the Submit button, it checks, then you have to click it again to send it if everything went right ... which is behind.

Another important thing related to this problem is that I am completely in different parts of my application for reasons that cannot change. In addition, they load asynchronously.

The main thing I want to know is then ... how to reorder or prioritize events in some way ...

+4
source share
2 answers

If you use a "delegate", as you have in your example, then the ajax view will be launched first, so the short answer to your question is "You cannot." Your delegate is attached to the body element, so events related to elements closer to the form in the DOM tree will fire first.

The event of bubbles from the form โ†’ body, therefore, when it is created, it is not ordered.

One option is for you to check the trigger of the second event.

 methods.checkForm = function (e) { e.preventDefault() if ($(this).isVerified()) { $(this).trigger('form-verified'); } }; 

Then, instead of binding another handler to 'submit' you bind it to 'form-verified' .

 $('form').bind('form-verified', methods.submitFormIfCheckedFormIsTrue); 

This is also another way to execute an ordering event if they are bound to the same element instead of using a delegate.

Also, if you use jQuery> = 1.7, you should use on instead of bind and delegate . http://api.jquery.com/on/

Update

If both are associated with the same element, then they will be launched in the order in which they were attached to the element. Assuming checkForm is linked before another, the problem is that return false; does not stop other events on startup if they are bound to the same element. You will also need e.stopImmediatePropagation() .

 methods.checkForm = function (e) { e.preventDefault() if (!$(this).isVerified()) { e.stopImmediatePropagation(); } }; 

There is also a helpful answer here if you ever have to tune the order of events. JQuery event handlers are always executed so that they are bound - in any way, is this?

+3
source

In a general sense, event handlers will be called in the order in which they were connected, but only if they are connected at the same level. In your case, you bind one directly to the form, and the other a delegated handler, linked at the document.body level. A directly connected one will happen first, and then the event bubbles up to be processed by the other.

If you bind both handlers at the same level with .delegate() , then they should be called in the order:

 $(document.body).delegate('form', 'submit', methods.checkForm); $(document.body).delegate('form', 'submit', methods.submitFormIfCheckedFormIsTrue); 

Then in the first (general) handler, you must call the event.stopImmediatePropagation() method to prevent other handlers from being called (noting that just returning false prevents the default and stops the event, increasing, but does not stop the execution of other handlers at this level):

 methods.checkForm = function (e) { if (!$(this).isVerified()) { e.stopImmediatePropagation(); return false; } return true; }; 

(By the way, the code shown in the question left the event (second parameter) from the .delegate() call - I entered it in my code.)

Or bind both handlers directly, rather than using .delegate() . Speaking of using .delegate() , if you are using the latest version of jQuery, you can switch to using .on() new do-all event binding method.

"It happens that the submitFormIfCheckedFormIsTrue function runs before or during the checkForm function"

Definitely earlier, not during. (In almost all browsers) JavaScript runs in a single thread, so you wonโ€™t run two functions at the same time.

0
source

Source: https://habr.com/ru/post/1396738/


All Articles