事件里面元素怎么立即刷新dom(页面),而不是等所有代码运行完再刷新。

用js更新dom是web系统中经常出现的场景,但是有时候可能会遇到这样的情况,在更新dom之后还执行了一段运行时间可能比较长的js代码,这时你会发现,你更新的dom不会立刻在页面显现出来,而要等所有js都执行完之后才能出现。

<!DOCTYPE html>
<html>  <head>  <meta charset="gbk" />  <title>Test Refresh</title>  <script src="js/jquery-1.7.1.js"></script>  <script type="text/javascript">  function runLongOperation(){  var d = new Date().getTime();  while (1) {  var current = new Date().getTime();  if (current - d > 3000) {  console.log("good");  break;  }  }  }  $(function(){  $("#submit1").click(function(){  var $n = $("#name");  $n.hide();  runLongOperation();  });  });  </script>  </head>  <body>  <input type="text" placeholder="please input your name" name="wd" id="name"/>  <input type="button" name="submit1" id="submit1" value="Hide"/>  </body>
</html>

点击按钮后首先执行的操作是隐藏输入框name,然后执行了一段长约3秒钟的操作,你会发现点击按钮后隐藏输入框的动作并不会立刻在浏览器上体现,而是等到runLongOperation执行完之后才发生(我试了在chrome,FF和IE上均是如此)。为什么会这样呢,在stackoverflow上找到一个大神的解释,“Mozilla (maybe IE as well) will cache/delay executing changes to the DOM which affect display, so that it can calculate all the changes at once instead of repeatedly after each and every statement.”。也就是说,浏览器会cache住影响dom展现的操作,直到所有的js都执行完,这时候它可以一次性地更新需要更新的dom,这样做可能是出于性能的考虑。

通常来说,这不会有什么问题,但有的时候也许会带来一些体验上的不同。以我最近接触的一个系统的场景来说,点击一个tab页签会加载一个页面,加载完后会执行先关的初始化js,也就是在set完这个tab容器的content后还要执行一段js。不幸的是,这段js执行的时间有点长(由于历史原因这段js必须执行),大约1~2秒的时间(IE下),所以用户会在点击tab页签后并不能马上看到页面,而是看到一个空白的区域并等待一段时间才能看到正常的画面,这就给了用户不好的体验。为了消除这个影响,我们想要强制浏览器让内容先展示出来,再执行剩下的js,使用户可较快地看到结果,虽然接下来js的执行的js也会影响用户的操作(单线程),但因为用户在点开页面后通常有段时间是不做任何操作的(通常要先看一眼什么的),这段时间可以让坑爹的js执行完。

接下来的问题是如何让浏览器强制刷新更新后的dom呢,我们找到了几种方法:

1.更新dom的js执行完后执行alert,会强制浏览器刷新dom。这个方法简单有效,但无可操作性,不可能在系统中无缘无故弹出一个alert框。

2.根据stackoverflow上某位大神的说法,“To force an update (to force an immediate, synchronous reflow or relayout), your JavaScript should read a property that’s affected by the change, e.g. the location of someSpan and otherSpan.:”,即是如果让js去读被改变的dom节点的相关属性,则可以迫使浏览器更新dom。但遵照这个思想试验只好发现没有起效,不知是否我的操作方法不当??望有高人指点!!

3.借助setTimeout,把后面影响刷新的js放在setTimeout里面执行。按我的理解,原来的一大段js是处在一个同步执行的逻辑中的,而浏览器会延迟一个dom刷新的机制也只是作用在同步代码中,如果我们将后面的js放在setTimeout里面,那相当于后面的代码处在一个异步逻辑中,浏览器就会认为当前的同步逻辑已经完成,可以刷新更改的dom了。但是,setTimeout的时间也不能设得太小,如果设为0,你会发现仍然可能不能立刻刷新更改后的dom。我想也许这跟各个浏览器的任务调度有关,当前的同步逻辑执行完之后,浏览器刷新dom的操作可能会被另一个任务抢占了,经试验把timeout的时间设在100左右较为理想。。。顺带提一句的是,js引擎都是单线程处理任务队列的,任何异步编程都是障眼法,可参考http://www.cnblogs.com/jeffwongishandsome/archive/2011/06/13/2080145.html。

最后,我的解决方案是将之前的代码改成如下形式:

$(function(){
$("#submit1").click(function(){  var $n = $("#name");  $n.hide();  setTimeout(runLongOperation, 100);
})
})

事件里面元素怎么立即刷新dom(页面),而不是等所有代码运行完再刷新。(强制刷新DOM)相关推荐

  1. 微信html开发返回刷新页面,解决微信内置浏览器返回上一页强制刷新问题方法...

    微信内置浏览器在返回上一页面,且上一页面包含AJAX代码时,页面就会被强制刷新,极度影响用户体验.而我们想要的效果是:返回上一页面时,页面还停留在原来的状态,AJAX获取到的数据还在,滚动条也在原来的 ...

  2. jquery刷新iframe页面的方法(兼容主流)

    1,reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet])    参数: bForceGet, 可选参数, 默认为 false,从客户端缓存 ...

  3. java弹框刷新原页面_JavaScript:关闭弹出窗口时刷新父窗口

    说明: 关闭弹出窗口时刷新父窗口也可以说是关闭子窗口时自动刷新父窗口中的信息,即用户通过window对象的open()方法打开一个新窗口(子窗口),当用 户在该子窗口中进行了数据库操作(如数据添加.修 ...

  4. 最实用的vue刷新当前页面,provide / inject 组合 方式实现vue页面刷新

    这是一种最实用的vue刷新当前页面,其他方式一般会出现一个瞬间的空白页面,体验不好,相当于按ctrl+F5 强制刷新那种 方式:provide / inject 组合 方式实现vue页面刷新 1.修改 ...

  5. chrome打开本地html自动刷新,chrome自动刷新怎么设置_chrome浏览器如何自动刷新当前页面-win7之家...

    我们在使用电脑中的chrome浏览器浏览网页中内容的时候,为了能够查看到最新的发布的内容,许多用户都会对网页进行及时的刷新,然而这样的操作很是麻烦,因此有些用户就想要给网页设置成自动刷新,那么chro ...

  6. Vue 三种强制刷新方法的机制、使用场景、开销说明

    前言 在日常 Vue 项目开发中,我们或多或少需要对组件进行强制刷新操作.比如,明明更新了 data 属性的值,但是页面上显示的还是旧的数据.又比如,在某些时候,我们想要一个全新的.干净的组件:或者是 ...

  7. vue 双向绑定,列表、条件渲染,解决强制刷新闪烁问题

    vue 双向绑定 v-model 列表渲染 v-for 条件渲染 v-if v-show 解决强制刷新闪烁问题 v-clock 双向绑定 v-model v-model 是 vue 中进行数据双向绑定 ...

  8. angular 强制更新视图_angular4强制刷新视图的方法

    angular4强制刷新视图的方法 使用angular的过程中有时会出现数据已经更新了,但是对于的视图没有更新,针对这一情况,可以是用angular提供的方法强制更新视图. 这里使用NGZone来更新 ...

  9. vue双向数据绑定没有生效----vue强制更新dom结构

    vue中使用v-for渲染的页面无法通过v-if或v-show动态隐藏 当你的数剧层次太多,数据是变化了的,但是dom没有更新,没有自动双向数据驱动 这时候可以手动强制刷新 this.$forceUp ...

最新文章

  1. 2011年5月系统分析师考试­
  2. 隐藏在管理员登录页面的危险
  3. LCD1602液晶显示模块的单片机驱动深入详解之硬件篇
  4. Mybatis中传参包There is no getter for property named XXX in class java.lang.String
  5. SHLL脚本从1到100自加
  6. 错误日志类-也可以用于查看输出结构
  7. python如何改变数据类型_如何改变numpy数组的数据类型和形状?
  8. cuSPARSE库:(十五)已经弃用的函数(1)
  9. js初化加载页面时ajax会调用两次的原因_在前端开发中,有哪些因素会导致页面卡顿
  10. 苹果X可以升级5G吗_郭明錤:苹果5G手机明年推出 屏幕最大升级至6.7寸
  11. 【回归预测】基于matlab鲸鱼算法优化BP神经网络回归预测(多输入单输出)【含Matlab源码 1554期】
  12. find命令之xargs
  13. 计算机启动dos,开机怎么进入dos_开机怎么进入dos界面
  14. wps空白页怎么删除,迅速帮你解决问题
  15. 超宽带雷达P440?雷达的快时间慢时间是什么意思?
  16. 深度学习 - 其本质是什么?
  17. Python语音识别,让人工智能给你读读书,你是想听——萝莉音?御姐音?大叔音?正太音?这些任你选择哦~~~
  18. php中redis的exec()用法,Redis Exec 命令 - Redis 教程 - 自强学堂
  19. 【让我们为你连接到网络】未识别的网络进行修复
  20. Python 3.8+moviepy报错:TypeError: ‘module‘ object is not callable

热门文章

  1. [转摘]必须学好C++么?
  2. 云深互联:跨越界限的集成者
  3. 教你如何使用Google进行搜索
  4. 小程序开发系列之基础部分-基础部分
  5. 第十二届蓝桥杯--第二场--B-双阶乘
  6. 明川和治功现在正说牛家沟那个“母老虎”的事
  7. 华为、阿里、腾讯、百度、360,不能再打了。
  8. Android 手机十大必备软件
  9. 服务的基本使用:定义、启动和停止服务
  10. —个幸存者游戏给出的10个启示(经典)