Kevin L Kevin L - 6 days ago 4
HTML Question

Disabling elements with alert message different in IE and Chrome

I have a button (lets call it Toggler) that changes the

disabled
property of another button then displays an
alert()
message.

In Internet Explorer 11, when one clicks on Toggler, the button visually becomes disabled when the alert message displays.

However, in Chrome (54.0.2840.99), when one clicks on Toggler, the button does NOT visually become disabled when the alert message displays. Only after closing the alert box does the button become disabled.

How would I make both browsers (and Safari, Edge, etc - company computer so I don't have them) have the button appear disabled when the alert message pops up?

Barebones code to demonstrate



var btn;
var enabled = true;

function toggle() {
if (enabled) {
disableBtn(btn);
alert("Now Disabled");
} else {
enableBtn(btn);
alert("Now Enabled");
}
enabled = !enabled
}

function disableBtn(element) {
element.disabled = true;
}

function enableBtn(element) {
element.disabled = false;
}

window.onload = function() {
btn = document.getElementById("btn");
}

<button onclick="toggle();">Button to toggle things</button>
<br />
<br />
<button id="btn">Button that shows if enabled or not</button>




Answer

Alerts are "blocking", that is that they block the UI from updating. The sequence that the UI gets updated is based on how fast the code is processed. In your case the JavaScript engine is processing the alert() code before it can update the page (which is not actually handled by the JavaScript runtime - - that's handled by the operating system).

So basically, you've got the JavaScript runtime processing your JavaScript (one statement at a time) and it gets a request to disable a button. So, the JavaScript runtime sends a message to the operating system to do just that and then the JavaScript runtime moves on to the next instruction, which is to show an alert. What's happening is the alert is being created by the browser faster than the operating system can update the display of the button.

To solve this, you can add a delay to the alert() with setTimeout()

var btn;
var enabled=true;

function toggle() {
  if(enabled) {
	disableBtn(btn);
  
    // Add a short delay to allow the UI to catch up
    setTimeout(function(){		
      alert("Now Disabled");
    }, 250);
    
  } else {
    enableBtn(btn);
    
    setTimeout(function(){		
      alert("Now Enabled");
    }, 100);
    
  }

  enabled = !enabled
}

function disableBtn(element) {  element.disabled = true; }
function enableBtn(element) {  element.disabled = false; }
window.onload = function () { btn = document.getElementById("btn"); }
<button onclick="toggle();">Button to toggle things</button><br /><br />
<button id="btn">Button that shows if enabled or not</button>