【问题标题】:Disabling elements with alert message different in IE and Chrome在 IE 和 Chrome 中禁用带有不同警报消息的元素
【发布时间】:2016-11-30 22:41:24
【问题描述】:

我有一个按钮(我们称之为 Toggler),它可以更改另一个按钮的 disabled 属性,然后显示 alert() 消息。

在 Internet Explorer 11 中,当单击 Toggler 时,该按钮会在显示警报消息时视觉上变为禁用。

但是,在 Chrome (54.0.2840.99) 中,当单击 Toggler 时,显示警报消息时该按钮不会在视觉上变为禁用状态。只有在关闭警报框后,按钮才会被禁用。

如何让两个浏览器(以及 Safari、Edge 等 - 公司计算机,所以我没有它们)在弹出警报消息时显示为禁用按钮?

用于演示的准系统代码

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>

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    发生的情况是浏览器(本机代码)创建警报的速度快于 JavaScript 运行时更新按钮显示的速度。

    alert() 实际上并不是由 JavaScript 创建的。 JavaScript 可以发起请求,但 alertwindow API 的一部分(实际上是 window.alert()),window API 由浏览器管理,而不是 JavaScript 运行时。

    因此,如果您在一行中有一些 JavaScript 执行了一些应该导致 UI 更新的操作,并且下一行发起了对 alert 的请求,即使这两行是一次处理的,它们一个接一个地发生,它们之间几乎没有延迟。那时,浏览器和 JavaScript 运行时之间的竞赛就是看哪个可以先更新 UI。由于浏览器(用本机代码编写)比 JS 运行时更快,因此浏览器赢得了比赛(即使它的指令排在第二位)并在按钮渲染完成之前生成alert()

    现在,因为 alert 是一个“阻止”组件,即它阻止 UI 更新,所以在 alert 完成之前无法更新按钮的显示。

    要解决此问题,您可以将alert() 的请求延迟足够长的时间,以确保首先使用setTimeout() 更改按钮的呈现。 setTimeout()(另一个 window API)要求您向它传递一个函数,该函数将在 JavaScript 运行时空闲时在指定的毫秒延迟后运行,这在(至少)当前函数完成之前不会发生。

    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>

    【讨论】:

    • 你知道需要什么样的延迟才能让它在不同的机器/浏览器上工作吗?理想情况下,我会使用更新所有内容所需的最小延迟。
    • 我想它不应该超过 1/10 秒就可以确定。在我的示例中,我使用了 1/4 秒(250 毫秒)。
    • @Sébastien 请将您对其他人问题/答案的编辑限制为更正,而不是您的个人偏好。我故意按照我的方式格式化了代码。修改它以匹配您的特定编码偏好并不是编辑的目的。
    • ??这一定是我第一波的一部分。再次抱歉,在您昨天发表第一条评论后,我没有再编辑您的帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多