jjzjj

javascript - 如果我在 Javascript 事件处理程序中更改 DOM,这些更改是递增呈现的,还是只在最后呈现一次?

coder 2023-08-03 原文

假设我有以下 javascript 事件处理程序:

function handleEvent(e){
    document.body.style.backgroundColor = 'green';
    longRunningFunction();
    document.body.style.backgroundColor = 'red';
}

浏览器会先显示绿色背景然后再切换成红色吗?还是直接显示红色背景?

根据我的测试,它直接在事件处理程序的末尾显示红色。但那是规范的一部分,还是浏览器恰好是如何实现的?

更新:

我应该澄清一下,我并不是“瞄准”这种效果。相反,我想保证它不会发生。我的一些事件处理程序改变了很多东西,如果我可以假设没有呈现任何中间状态,它会让我的生活更轻松。

最佳答案

这是在 JavaScript 执行环境中会发生的事情:

  1. document.body.style.backgroundColor 会将其值更改为 'green'
  2. 将运行一个长时间运行的进程。
  3. document.body.style.backgroundColor 会将其值更改为 'red'

未指定如果 JavaScript 线程被阻塞,backgroundColor 属性的更改将如何影响页面的外观。

这是一个例子。如果你点击单词 hello,你会看到一个轻微的延迟,然后背景会变成红色:

function handleEvent(e){
    document.body.style.backgroundColor = 'green';
    longRunningFunction();
    document.body.style.backgroundColor = 'red';
}

function longRunningFunction() {
    for(var i=0; i<2000000000; ++i) { +i; }
}

document.body.addEventListener("click", handleEvent);
<div>hello</div>

这是因为响应 CSS 属性更改而重绘的浏览器渲染引擎被长时间运行的阻塞 JavaScript 函数阻塞。这不是指定的行为,而是所有浏览器的实现现实。参见 How can I force the browser to redraw while my script is doing some heavy processing?对于类似的问题。

我认为任何给定的浏览器都可以选择与 JavaScript 线程并发运行一个单独的重绘线程,但我认为目前没有任何主流浏览器这样做。这种方法可能存在固有的竞争条件复杂性;我从来没有写过浏览器,所以我不知道。


如果您想要显示中间状态,您可以在将backgroundColor 设置为绿色后使用非常快速的setTiemout 调用来清除JavaScript函数堆栈并允许渲染器重绘页面:

function handleEvent(e){
    document.body.style.backgroundColor = 'green';
    setTimeout(function() {
        longRunningFunction();
        document.body.style.backgroundColor = 'red';
    }, 4);
}

这会将 longRunningFunction 和第二次颜色更改排队,以便在未来 4 毫秒内运行。在那空闲的 4 毫秒内,渲染器有机会重绘页面。

关于javascript - 如果我在 Javascript 事件处理程序中更改 DOM,这些更改是递增呈现的,还是只在最后呈现一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30358521/

有关javascript - 如果我在 Javascript 事件处理程序中更改 DOM,这些更改是递增呈现的,还是只在最后呈现一次?的更多相关文章

  1. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  4. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  5. ruby - Capistrano 3 在任务中更改 ssh_options - 2

    我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

  6. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  7. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  8. ruby - 更改 ActiveRecord 中对象的类 - 2

    假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。

  9. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  10. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

随机推荐