Michael S.
Michael S.

Reputation: 23

Lost "click" event during AJAX refresh

$(":input").on("change", function(e) {
  console.log("change triggered");
	$("#section").html("<button id='order'>Order</button>");
  registerButtons();
});

function registerButtons() {
  $("#order").on("click", function(e) {
 	  console.log("click triggered");
  	alert("Hello World");
  });
  $("#order").on("mousedown mouseup", function(e) {
 	  console.log(e.type + " triggered");
  });
}

registerButtons();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="123"/>
<div id="section">
  <button id="order">Order</button>
</div>

I have a web page with a button and some input fields.

The onChange will trigger an AJAX server call, and the result will replace parts of the web page - including the button. After AJAX result is processed, all listener are registered again.

Now the problem. A user changes the value of an input field, and clicks directly the button - but to slow (lets assume the user needs 500ms for the click), so the onChange event is fired and the page is "updated/replaced". Now the "old" button fires an onMouseDown and the "new" button fires an onMouseUp event - but no onClick.

My current workaround is, to register the two mouseDown/mouseUp events, get the timestamp of the mouse down, and if the mouse up comes in 2 seconds, do what should be done by the onClick. It is no option to remove the button part from the AJAX response - in worst case the button could be removed and replaced by an user info.

My hope is, that there is a better solution... any ideas?

Upvotes: 2

Views: 2230

Answers (1)

Yasin Yaqoobi
Yasin Yaqoobi

Reputation: 2040

You can take advantage of the event delegation and set your listener on the container instead of the button.

You are adding a click listener to your old button and your adding a new button to the dom. So the click won't work.

The button wasn't working because for some reason it can't focus when you hover over it. So I added a getFocus method and now it should work.

$("input").on("change", function(e) {

    console.log("change triggered");

    $("#section").html("<button id='order'>Order</button>");

});


function registerButtons() {
   
  $('#section').on("mouseup", '#order', function(e) {
       
        alert('Clicked!');
 });

}

registerButtons();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="123"/>
<div id="section">
  <button id="order">Order</button>
</div>

I just found out that jQuery provides a sweet API that can be used for event delegation. This way we don't have to manually check for event target. Check it out http://api.jquery.com/on/

$("input").on("change", function(e) {
  console.log("change triggered");
    $("#section").html("<button id='order'>Order</button>");
});


    function registerButtons() {
      $("#section").on("click", '#order', function(e) {
            console.log("click triggered");
            alert("Hello World");
     });

    $("#section").on('mouseover','#order', function(e){
            $(this).focus();
    });
}

registerButtons();

Upvotes: 1

Related Questions