【问题标题】:Wait for css of element to be updated when it is dynamically changed with JS/Jquery当使用 JS/Jquery 动态更改元素时,等待元素的 css 被更新
【发布时间】:2021-04-03 11:27:49
【问题描述】:

所以在对我遇到的问题进行了大量搜索之后,我发现我遇到的问题是,因为当我将 css 应用于元素时,信息无法立即获得,这就是我的意思:

我有一个元素,我用display: block;display: none; 隐藏和显示,问题是在我显示元素后,我需要获取它的高度:

$element.css({ display: "block"});

console.log($element.outerHeight()); // <- this returns 0

所以我在某个时候开始尝试超时,即使有 1 毫秒的超时,它仍然可以工作并返回正确的高度:

setTimeout(() => {
    console.log($element.outerHeight()); // with 1ms timeout, it works and gives real height
}, 1)

在弄清楚这一点后,有 1 毫秒的延迟它不可能是某种继承的转换或任何东西,所以这让我想到,也许在从 display: block; 跳转到 .outerHeight() 之间,经过一番挖掘,某些东西尚未更新我发现了这个:

引用:“您将在不同的浏览器中看到不同的行为,因为 jQuery 使用内联样式更新标记并且浏览器决定何时重绘。”

Does jQuery's css method block until the change is fully applied?

这似乎是我的实际问题,所以现在的问题是,我如何确定重绘发生的时间,我尝试了 onloadload 事件,但没有一个事件被触发。

我还尝试了该帖子中建议的带有动画的代码:

$element.animate({
  display: 'block'
}, {
  duration: 0,
  done: function(animation, jumpedToEnd) {
    console.log($element.outerHeight());
  }
})

但这也不起作用。

【问题讨论】:

    标签: javascript jquery css


    【解决方案1】:

    您遇到的问题是您无法真正控制浏览器如何显示更改。正如您所指出的那样,该信息无法立即获得,即使超时在技术上是一种解决方案,但它缺乏优雅并危及您进入 callback hell 的 UI。

    您需要测试哪些更优雅的解决方案是否有效

    1。是否在 0 毫秒内工作

    如果它的工作时间为 0 毫秒,那么基本上 UI 会在 function 成功执行之后和 event loop 的下一个 function 运行之前刷新。

    2。不使用 jQuery 的行为是否不同

    比较行为

    $element.css({ display: "block"});
    

    for (let index = 0; index < $element.length; index++) {
        $element[index].style.display = "block";
    }
    

    是等价的。如果是这样,那么这不是 jQuery 问题。如果不是,那就是 jQuery 的问题。

    结论

    作为一般指导,您可能需要类似回调的行为,并且您可能需要使用promise architecture。如果有效。

    【讨论】:

    • 我刚刚尝试过,是的,它确实可以使用 0 ms 的 timeouf,我也尝试过使用纯 JS 并且没有超时 document.getElementsByClassName("classofelement")[0].style.display = "block"; 这不起作用,所以它不是 jQuery 问题。我有能力通过承诺来做到这一点,但是,我不知道,我必须等待什么,我可以使用 .then() 的功能是什么,以便我可以做任何我想做的事情事件循环运行后怎么办?
    • @Darkbound 所以,大概是这样的流程: 1. 你的函数改变了一些 CSS 值 2. 函数结束 3. 浏览器显示基于 CSS 变化的一些变化,随后属性值被改变 4 . 你的下一个函数被执行。回调行为成功的原因是 3. 发生在 2. 和 4. 之间。立即访问失败的原因是在这种情况下,您在 3. 之前调用了 1. 和 2. 之间的属性。这就是问题所在这就是为什么类似回调的行为起作用的原因。
    • @Darkbound 了解更多信息,我建议您可以阅读有关事件循环的内容,然后您将了解 Javascript 如何处理函数调用。假设您知道事件循环是如何工作的,您需要的信息是在函数调用之间刷新 UI。 Javascript 是单线程的,对于浏览器来说,由于更改而在函数内部进行更改是次优的,因为可能会有几个更改。
    • @Darkbound 假设您有一个包含 1000 次 UI 更改的函数,如果浏览器将所有这些都单独进行,那么从用户的角度来看,它将很快被淹没并且毫无用处。由于浏览器在该模型中的用户体验不佳,因此可以推测(我之前的实验证实了这一点)浏览器在 JS 函数运行时不会刷新 UI。因此,它必须刷新事件循环中节点之间的 UI。
    • @Darkbound 请注意,您可以使其易于使用:function myFunction(callback) {setTimeout(callback, 0);},然后您可以将其称为 myFunction(callback),使用时不必担心 setTimeout。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 2021-10-09
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多