更新 <progress> 元素在 Chrome 中可以工作,但在 Safari 中不起作用

huangapple go评论60阅读模式
英文:

Updating a <progress> element works in Chrome but not in Safari

问题

我正在尝试在异步函数内更新进度条。以下代码片段在Chrome中对我有效,但在Safari中不起作用:

<!DOCTYPE html>
<html>

<body>
  <progress id="progressBar" value="40" max="100"></progress>
  <script>
    (async () => {
      const progressBar = document.getElementById("progressBar");
      for (let i = 0; i <= 100; i++) {
        progressBar.value = i;
        await new Promise(resolve => setTimeout(resolve, 100)); // sleep for 0.1s
      }
    })();
  </script>
</body>

</html>

在Chrome中,进度条每0.1秒更新一次,与预期一致。

在Safari中,进度条不会更新(循环执行,甚至通过打印console.log(progressBar.value)可以看到progressBar的值正在更新,但该更改不会在UI中反映出来)。

我正在使用M1 MacBook Pro,Safari版本为Version 16.4 (18615.1.26.11.23)

英文:

I'm trying to update a progress bar from within an async function. The following snippet of code works for me in Chrome but not in Safari:

&lt;!DOCTYPE html&gt;
&lt;html&gt;

&lt;body&gt;
  &lt;progress id=&quot;progressBar&quot; value=&quot;40&quot; max=&quot;100&quot;&gt;&lt;/progress&gt;
  &lt;script&gt;
    (async () =&gt; {
      const progressBar = document.getElementById(&quot;progressBar&quot;);
      for (let i = 0; i &lt;= 100; i++) {
        progressBar.value = i;
        await new Promise(resolve =&gt; setTimeout(resolve, 100)); // sleep for 0.1s
      }
    })();
  &lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;

In chrome, the progress bar gets updated every 0.1s as expected.

In Safari, the progress bar doesn't get updated (the loop executes, and we can even see that the value of progressBar is being updated by printing console.log(progressBar.value), but that change doesn't get reflected in the UI).

I'm using an M1 Macbook Pro with Safari Version 16.4 (18615.1.26.11.23).

答案1

得分: 2

我可以在当前稳定版本16.4(18615.1.26.110.1)上重现相同的错误,但在最新的技术预览版(Release 170(Safari 16.4,WebKit 18616.1.14.5))上却没有发现这个问题。所以我想我们可以假设他们已经修复了这个问题,我们只需要等待修复版本发布。

如果需要一种解决方法,似乎有一个有效的方法是强制重新插入元素到DOM中:

(async () => {
  const progressBar = document.getElementById("progressBar");
  for (let i = 0; i <= 100; i++) {
    progressBar.value = i;
    // workaround Safari bug not updating the UI
    progressBar.replaceWith(progressBar);
    await new Promise(resolve => setTimeout(resolve, 100)); // sleep for 0.1s
  }
})();
<progress id="progressBar" value="40" max="100"></progress>

由于设置<progress>元素的.value IDL属性也会设置其value=""内容属性,所以这并不像听起来那么糟糕,因为设置IDL属性将已经触发内容属性的DOM变化记录,所以我们只是在同一个变化事件上堆叠了一个变化。

英文:

I can reproduce the same bug on the current stable Version 16.4 (18615.1.26.110.1) but not on the latest Technology Preview (Release 170 (Safari 16.4, WebKit 18616.1.14.5)). So I guess we can assume that they already did fix it and that all we have to do is to wait for that fix to be shipped in stable.

If you need a workaround, one that seems to work is to force the reinsertion of the element in the DOM:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

(async () =&gt; {
  const progressBar = document.getElementById(&quot;progressBar&quot;);
  for (let i = 0; i &lt;= 100; i++) {
    progressBar.value = i;
    // workaround Safari bug not updating the UI
    progressBar.replaceWith(progressBar);
    await new Promise(resolve =&gt; setTimeout(resolve, 100)); // sleep for 0.1s
  }
})();

<!-- language: lang-html -->

&lt;progress id=&quot;progressBar&quot; value=&quot;40&quot; max=&quot;100&quot;&gt;&lt;/progress&gt;

<!-- end snippet -->

Since setting the .value IDL attribute of the &lt;progress&gt; element will also set its value=&quot;&quot; content attribute, this shouldn't be as bad as it sounds, because setting the IDL attribute will anyway already trigger a DOM mutation record for the content attribute, so we're just pilling one up on that, in the same mutation event.

答案2

得分: 2

以下是翻译好的内容:

修复将会随着 Safari 16.6 版本发布,并在发行说明中提到。

修复了在&lt;meter&gt;和&lt;progress&gt;元素上数值未更新的问题。

英文:

The fix will be shipped with Safari 16.6 and it is mentioned in the release notes.

Fixed the value not updating on &lt;meter&gt; and &lt;progress&gt; elements.

huangapple
  • 本文由 发表于 2023年5月22日 02:24:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76301339.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定