简体   繁体   中英

JS function "Confirm" acting out of order

The following function mimics a pattern of behavior I would like in my system:

  1. Press button

  2. Change text to an Icon

  3. Ask for user confirmation

  4. Fire Ajax call to an endpoint, and handle the result

  5. Return the text to the previous state.

As it is written, step 3 happens before steps 2 and 4; making step 2 borderline pointless. The Ajax call as I have it in my system loads pretty quickly, but the jQuery function barely blinks the text across. I have made a testable snippet here.

How do I ensure that step 2 correctly in order?

 function callAjax() { $('#loadingIcon').css('display', 'inline-block'); $('#buttonText').css('display', 'none'); if (confirm('Are you sure would you like to proceed?')) { $.ajax({ url: "...", timeout: 60000, context: document.body, success: function (data) { location.reload(); }, error: function (data) { $('#loadingIcon').css('display', 'none'); $('#buttonText').css('display', 'initial'); } }); } else { $('#loadingIcon').css('display', 'none'); $('#buttonText').css('display', 'initial'); } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button onClick=callAjax()> <span id="buttonText">Loading Text</span> <span id="loadingIcon" style="display:none;">Icon</span> </button>

The UI doesn't update until the thread has finished doing what it's doing, and confirm (and prompt , and alert ) is a blocking operation.

Ideally you wouldn't use confirm at all. Instead, create a UI within the page to prompt the user for data. It could be form elements on the page, a "modal dialog", etc.

But if you want to use confirm , you'd need to allow the thread to finish first. It's a bit of a hack, but wrapping it in a near-immediate setTimeout should do the trick:

$('#loadingIcon').css('display', 'inline-block');
$('#buttonText').css('display', 'none');
setTimeout(function () {
  if (confirm('Are you sure would you like to proceed?')) {
    $.ajax({
      /* etc. */
    });
  } else {
    $('#loadingIcon').css('display', 'none');
    $('#buttonText').css('display', 'initial');
  }
}, 1); // only delaying 1ms

This introduces a 1ms delay, which would certainly be imperceptible. But by virtue of using setTimeout at all, the thread first finishes everything it's processing (including UI updates) and then executes what's scheduled in the timeout.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM