0

How to change the order of events when they are set via the .on method?

It turns out to change the order only for directly installed handlers
Example: https://jsfiddle.net/Bozon/3gcea2q1/8/
I was expecting this output:

click # 4 = # div1  
click # 3 = # div1  
click # 2 = # div1  
click # 1 = # div1   

I need this to reverse the order of events for a dynamically created block:

  1. The handler for the dynamic block is created in advance
    $('body').on("click", 'div2', function(){ });
  2. Then another handler is created
    $('body').on("click", 'div2', function(){ });
  3. Then a block is created
    $("body").prepend('<div id="div2">Text div2</div>');
  4. How to make the second handler run ahead of the first?

Example: https://jsfiddle.net/Bozon/3gcea2q1/11/

I need 'click # 2' to be displayed first

Example code:

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
  <style>
  #div1 {background-color:red;width:150px;height:50px;}
  #div2 {background-color:yellow;width:150px;height:50px;}
  #output {margin:15px;width:50%}
  </style>
 </head>
 <body>
<div id="div1">CLICK HERE ( div1 )</div>
<script>
$(document).ready(function() {

    var selector = '#div2';
    $('body').on("click", selector, function(){ 
        output("click #1 = " + selector);
    });

    $('body').on("click", selector, function(){ 
        output("click #2 = " + selector);
    });

    $(selector).click(function() {
        output("click #3 = " + selector);
    });
    
    $(selector).click(function() {
        output("click #4 = " + selector);
    });

    $("body").prepend('<div id="div2">CLICK HERE ( div2 )</div>');
    
    $('body').on("change load", selector, function(){ 
        output("load el with selector = " + selector); // does not work for some reason, then it will use "mouseover" event
    });
    
    $('body').one("mouseover", selector, function(){ 
        var elem = $(selector).get(0);
        var all_events = $.data(elem, 'events') || $._data(elem).events;
        if( typeof all_events !== "undefined" ){
            all_events['click'].reverse();
        }
        else {
            output("all_events is undefined");
        }
        //output( all_events['click'] );
    });

    function output(text) {
        console.log(text);
        $("#output").html(function(i, h) {
            return h + text + "<br />";
        });
    }
});

</script>
<div id="output"></div>
 </body> 
</html>
Sergey
  • 1
  • 1
  • Can you please create a snippet in the question which contains all relevant code. This is because if the external source is down or has technical issues, which jsFiddle is having right now, we cannot see a demo of the issue. – Rory McCrossan Apr 22 '21 at 16:30
  • Why are you binding the click event to body div2 more than once? You only need to bind it once. And then maybe use a condition inside the function to determine what action you want to take? – devlin carnate Apr 22 '21 at 16:54
  • This is a simplified case. My plugin runs on the page after another handler is already bound to the created element. But I need that my handler to be executed first . – Sergey Apr 22 '21 at 17:30
  • Then unbind the existing handler, and bind the one you want. – devlin carnate Apr 22 '21 at 17:33
  • Does this answer your question? [How to unbind a specific event handler](https://stackoverflow.com/questions/3972886/how-to-unbind-a-specific-event-handler) – devlin carnate Apr 22 '21 at 17:34
  • but I need both events (just in a different order, first 'click #2' then 'click #1') and I cannot swap them because all_events is undefined if events are bound via .on method – Sergey Apr 22 '21 at 17:45
  • Then re-bind the original handler after you bind your handler. Also, more info on jQuery event ordering [here](https://stackoverflow.com/questions/2360655/jquery-event-handlers-always-execute-in-order-they-were-bound-any-way-around-t) – devlin carnate Apr 22 '21 at 17:51
  • the problem is I can't get the first bound handler (which is bound by the .on method) in this case the array of events is retrieved via jquery - jQuery._data (, "events"); is undefined for this element ($ ("# div2")) – Sergey Apr 22 '21 at 18:04

1 Answers1

0

the mistake turned out to be obvious, it was necessary to take the events of the element to which the .on method is applied

https://jsfiddle.net/Bozon/rnpcf53a/1/

$(document).ready(function() {

    var selector = '#div2';
    $('body').on("click", selector, function(){ 
        output("click #1 = " + selector);
    });

    $('body').on("click", selector, function(){ 
        output("click #2 = " + selector);
    });

    $(selector).click(function() {
        output("click #3 = " + selector);
    });
    
    $(selector).click(function() {
        output("click #4 = " + selector);
    });

    $("body").prepend('<div id="div2">CLICK HERE ( div2 )</div>');
    
    $('body').on("change load", selector, function(){ 
        output("load el with selector = " + selector);
    });
    
    $('body').one("mouseover", selector, function(){ 
        var elem = $('body').get(0);
        var all_events = $.data(elem, 'events') || $._data(elem).events;
        if( typeof all_events !== "undefined" ){
            all_events['click'].reverse();
        }
        else {
            output("all_events is undefined");
        }
        //output( all_events['click'] );
    });

    function output(text) {
        console.log(text);
        $("#output").html(function(i, h) {
            return h + text + "<br />";
        });
    }
});
Sergey
  • 1
  • 1