Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
369 views
in Technique[技术] by (71.8m points)

javascript - 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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What's happening is the alert is being created by the browser (native code) faster than the JavaScript runtime can update the display of the button.

An alert() isn't actually created by JavaScript. JavaScript can initiate a request for one, but an alert is part of the window API (it's actually window.alert()) and the window API is managed by the browser, not the JavaScript runtime.

So, if you've got some JavaScript on one line that does something that should cause the UI to update and the next line initiates a request for an alert, even though the two lines were processed one at a time, they happen one right after the other with very little delay between them. At that point, it's a race between the browser and the JavaScript runtime to see which can update the UI first. Since the browser (which is written in native code) is faster than the JS runtime, the browser wins the race (even though its instruction came second) and produces the alert() before the button's rendering is completed.

Now, because an alert is a "blocking" component, that is it blocks the UI from updating, the button's display now cannot be updated until the alert completes.

To solve this, you can delay the request for the alert() just long enough to ensure the button's rendering changes first with setTimeout(). setTimeout() (another window API), requires you pass it a function that will run after a specified millisecond delay, when the JavaScript runtime is idle, which won't happen until (at least) the current function completes.

var btn = document.getElementById("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");
        }, 20);  
    } else {
        enableBtn(btn);
    
        setTimeout(function() {
            alert("Now Enabled");
        }, 20);
    }
    enabled = !enabled;
}

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...