【问题标题】:How to force browser repaint and avoid UI update delay?如何强制浏览器重绘并避免 UI 更新延迟?
【发布时间】:2016-04-12 01:12:09
【问题描述】:

我需要浏览器在长时间(呃)操作完成之前更新我的 UI。目前浏览器正在等待一切完成后再更新 UI,这意味着 UI 会冻结 1-2 秒然后更新。

因此,用户点击 UI 中的按钮,然后执行以下代码:

$('#mybutton').click(function(e) {

e.preventDefault();// prevent the default anchor functionality

$('#mainctrldiv').css('display', 'none');
$('#otherctrldiv').css('display', 'block');

var img = $('<img id="spareimg" style="display:none;">');
img.attr('src', canvas.getActiveObject().toDataURL()); // This is causing the delay!
img.appendTo('body');
}

花时间的是 canvas.getActiveObject().toDataURL()(一个 FabricJS 函数)。我希望在 2 个 div 向用户明显显示之后发生这种情况,因为他们没有注意到。需要它在所有常用的浏览器中工作! (移动设备和桌面设备)。

研究表明,在设置后立即读取 css 显示属性会强制浏览器重新绘制,所以我在设置这些属性后直接添加了以下代码,但延迟仍然存在:

$('#mainctrldiv').css('display');
$('#otherctrldiv').css('display');

非常感谢您的任何建议!

【问题讨论】:

  • delay 是什么意思?如果画布太大,将其转换为数据URL 可能会在相当长的时间内阻塞主线程。延迟的具体表现如何?
  • 可以在 dom 中的某个点扔一个隐藏的、禁用的复选框,该复选框可以同时看到 #mainctrldiv#otherctrldiv 并具有切换的 css 规则,基于此切换获得 display:nonedisplay:block复选框为:checked。但是,我觉得这与 jQuery 管理事物的方式有关,而不是严格地说它试图做什么。
  • $('#mainctrldiv').css('display'); 不完整。你是说$('#mainctrldiv').css('display', 'block'); 吗?
  • @Cristy 谢谢。如前所述,延迟为 1 - 2 秒。用户在 UI 中单击 ID 为“#mybutton”的按钮,并且 div 交换(一个 div 被隐藏,另一个显示)应该是即时的,但是所有内容都会冻结 - 即使按钮被取消选择也会冻结 - 直到 canvas.getActiveObject( ).toDataURL() 完成。我知道这是负责任的,因为将其注释掉可以解决问题。
  • @Cristy 你写的“如果画布太大,将其转换为数据 URL 可能会在相当长的时间内阻塞主线程” - 是的,我知道,这就是我在这里发帖的原因:) 我需要延迟数据 URL 转换,直到 div 更新后(根据代码流),但浏览器在重绘之前组合了所有操作,所以我需要一个解决方法!

标签: javascript jquery css css-animations html5-animation


【解决方案1】:

尝试使用setTimeoutzero delay,它会将这些推到线程的末尾。如果零延迟对您不起作用,您也可以尝试添加一些延迟。但我不确定那条确切的线路是否会导致问题,如果发布另一个关于如何优化和减少时间的问题。

$('#mybutton').click(function(e) {
  e.preventDefault(); // prevent the default anchor functionality
  $('#mainctrldiv').css('display', 'none');
  $('#otherctrldiv').css('display', 'block');
  setTimeout(function() {
    var img = $('<img id="spareimg" style="display:none;">');
    img.attr('src', canvas.getActiveObject().toDataURL()); // This is causing the delay!
    img.appendTo('body');
  }, 0);
}

需要注意的是函数或代码sn-p不能 一直执行到调用 setTimeout() 的线程终止。

【讨论】:

  • 谢谢,这解决了问题:)
  • @AlexKerr 已经一年了 :)
  • 我知道,我被转移到了其他事情上,才刚刚开始解决这个问题,但很高兴看到你的建议既快速又简单!谢谢。
  • 太棒了,是的,它永远不会太晚:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 2012-02-03
  • 2010-09-10
  • 1970-01-01
  • 2012-11-04
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多