- 浏览: 75096 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
128340haha:
这里只是一个前台的 图片裁剪与预览~!要截图的成品 用得到的参 ...
一枚基于jQuery的头像截取插件imgareaselect -
Shmily奕蝶:
指教一下,我按你说的弄了,可怎么还是截不了图啊,这是哪里的原因 ...
一枚基于jQuery的头像截取插件imgareaselect -
snake13456:
小图的定位不够准确,要自行修改一下
一枚基于jQuery的头像截取插件imgareaselect -
fuhao200866:
没事自己坐沙发,哈哈
q:before, q:after { content:''; }问题【记录用】
在我们开发互联网富应用(RIA)时,我们经常写一些JavaScript脚本来修改或者增加页面元素,这些工作最终是DOM——或者说文档对象模型——来完成的,而我们的实现方式会影响到应用的响应速度。
DOM操作会导致浏览器重解析(reflow),这是浏览器的一个决定页面元素如何展现的计算过程。直接修改DOM,修改元素的CSS样式,修改浏览器的窗口大小,都会触发重解析。读取元素的布局属性比如offsetHeithe或者offsetWidth也会触发重解析。重解析需要花费计算时间,因此重解析触发的越少,应用就会越快。
DOM操作通常要不就是修改已经存在的页面上的元素,要不就是创建新的页面元素。下面的4种优化方案覆盖了修改和创建DOM节点两种方式,帮助你减少触发浏览器重解析的次数。
方案一:通过CSS类名切换来修改DOM
这个方案让我们可以一次性修改一个元素和它的子元素的多个样式属性而只触发一次重解析。
需求
我们现在需要写一个函数来修改一个超链接的几个样式规则。要实现很简单,把这几个规则对应的属性逐一改了就好了。但是带来的问题是,每修改一个样式属性,都会导致一次页面的重解析。
- function selectAnchor(element) {
- element.style.fontWeight = 'bold';
- element.style.textDecoration = 'none';
- element.style.color = '#000';
- }
解决方案
要解决这个问题,我们可以先创建一个样式名,并且把要修改的样式规则都放到这个类名上,然后我们给超链接添加上这个新类名,就可以实现添加几个样式规则而只触发一次重解析了。这个模式还有个好处是也实现了表现和逻辑相分离。
- .selectedAnchor {
- font-weight: bold;
- text-decoration: none;
- color: #000;
- }
- function selectAnchor(element) {
- element.className = 'selectedAnchor';
- }
方案二:在非渲染区修改DOM
上一个方案解决的是修改一个超链接的问题,当一次需要对很多个超链接进行相同修改的时候,这个方案就可以大显身手了。
需求
需求是这样的,我们要写一个函数来修改一个指定元素的子元素中所有的超链接的样式名(className)属性。要实现很简单,我们可以通过遍历每个超链接并且修改它们的样式名来完成任务。但是带来的问题就是,每修改一个超链接都会导致一次重解析。
- function updateAllAnchors(element, anchorClass) {
- var anchors = element.getElementsByTagName('a');
- for (var i = 0, length = anchors.length; i < length; i ++) {
- anchors.className = anchorClass;
- }
- }
解决方案
要解决这个问题,我们可以把被修改的指定元素从DOM里面移除,再修改所有的超链接,然后在把这个元素插入回到它原来的位置上。为了完成这个复杂的操作,我们可以先写一个可重用的函数,它不但移除了这个DOM节点,还返回了一个把元素插回到原来的位置的函数。
- /**
- * Remove an element and provide a function that inserts it into its original position
- * @param element {Element} The element to be temporarily removed
- * @return {Function} A function that inserts the element into its original position
- **/
- function removeToInsertLater(element) {
- var parentNode = element.parentNode;
- var nextSibling = element.nextSibling;
- parentNode.removeChild(element);
- return function() {
- if (nextSibling) {
- parentNode.insertBefore(element, nextSibling);
- } else {
- parentNode.appendChild(element);
- }
- };
- }
有了上面这个函数,现在我们就可以在一个不需要解析渲染的元素上面修改那些超链接了。这样只在移除和插入元素的时候各触发一次重解析。
- function updateAllAnchors(element, anchorClass) {
- var insertFunction = removeToInsertLater(element);
- var anchors = element.getElementsByTagName('a');
- for (var i = 0, length = anchors.length; i < length; i ++) {
- anchors.className = anchorClass;
- }
- insertFunction();
- }
方案三:一次性的DOM元素生成
这个方案让我们创建一个元素的过程只触发一次重解析。在创建完元素以后,先进行所有需要的修改,最后才把它插入到DOM里面去就可以了
需求
需求是这样的,实现一个函数,往一个指定的父元素上插入一个超链接元素。这个函数要同时可以设置这个超链接的显示文字和样式类。我们可以这样做:创建元素,插入到DOM里面,然后设置相应的属性。这就要触发3次重解析。
- function addAnchor(parentElement, anchorText, anchorClass) {
- var element = document.createElement('a');
- parentElement.appendChild(element);
- element.innerHTML = anchorText;
- element.className = anchorClass;
- }
解决方案
很简单,我们只要把插入元素这个操作放到最后做,就可以只进行一次重解析了。
- var element = document.createElement('a');
- element.innerHTML = anchorText;
- element.className = anchorClass;
- parentElement.appendChild(element);
- }
复制代码不过,要是我们想要插入很多个超链接到一个元素里面的话,那么这个做法还是有问题:每插入一个超链接还是要触发一次重解析。下一个方案可以解决这个问题。
方案四:通过文档片段对象(DocumentFragment)创建一组元素
这个方案允许我们创建并插入很多个元素而只触发一次重解析。要实现这点需要用到所谓的文档片段对象(DocumentFragment)。我们先在 DOM之外创建一个文档片段对象(这样它也就不需要解析和渲染),然后我们在文档片段对象中创建很多个元素,最后我们把这个文档片段对象中所有的元素一次性放到DOM里面去,只触发一次重解析。
需求
我们要写一个函数,往一个指定的元素上面增加10个超链接。如果我们简单的直接插入10个超链接到元素上面,就会触发10次重解析。
- function addAnchors(element) {
- var anchor;
- for (var i = 0; i < 10; i ++) {
- anchor = document.createElement('a');
- anchor.innerHTML = 'test';
- element.appendChild(anchor);
- }
- }
解决方案
要解决这个问题,我们要先创建一个文档片段对象,然后把每个新创建的超链接都插入到它里面去。当我们把文档片段对象用appendChild命令插入到指定的节点时,这个文档片段对象的所有子节点就一起被插入到指定的元素里面,而且只需要触发一次重解析。
- function addAnchors(element) {
- var anchor, fragment = document.createDocumentFragment();
- for (var i = 0; i < 10; i ++) {
- anchor = document.createElement('a');
- anchor.innerHTML = 'test';
- fragment.appendChild(anchor);
- }
- element.appendChild(fragment);
- }
发表评论
-
跨域iframe高度自适应(兼容IE/FF/OP/Chrome)
2011-11-23 16:23 1020采用JavaScript来控制iframe元素的高度是ifra ... -
微博加关注按钮
2011-11-18 16:00 927新浪微博:uid替换成自己的。 <iframe wid ... -
使用两种简单的方式解析 JSON 格式字符串
2011-08-12 15:33 972//使用两种简单的方式解析 JSON 格式字符串 ... -
ajax请求
2011-07-29 10:53 743window.ajax = function(data){ ... -
Js实现检测、添加、移除样式(className)
2011-07-26 16:27 2377// 说明:添加、移除、检测 className ... -
插入话题后部分文字选中
2011-07-07 20:51 793var btn = document.getElement ... -
阻止事件冒泡
2011-07-07 14:26 721(ev || event).cancelBubble = tr ... -
js常见错误积累
2011-06-29 23:15 692unterminated string literal ... -
一个自定义背景色渐变对象,弥补jQuery的animate函数不足
2011-06-01 15:41 1415一个自定义对象fadeColor,来看下底层代码: wi ... -
Js操作Select大全
2011-05-27 18:28 755判断select选项中 是否存在Value="par ... -
JavaScript blog式日历控件新算法
2011-05-27 17:33 722<!DOCTYPE html PUBLIC &quo ... -
一个随机颜色的函数
2011-05-17 17:07 909function randomColor() { //16进制 ... -
常用JS判断正则
2011-05-06 18:45 912//是否含有汉字 function hasChinese(s ... -
40种网页常用小技巧(javascript)
2011-05-04 10:07 5411. oncontextmenu="window.e ... -
火狐与非火狐获取键值问题keyCode
2011-04-26 20:09 985一次项目中,用到Enter 后ajax提交功能。keyCode ... -
获取浏览器窗口、页面等元素的大小
2011-04-20 12:01 718网页可见区域宽:document.body.clientWid ... -
获取浏览器窗口、页面等元素的大小
2011-04-20 12:00 764网页可见区域宽:document.body.clientWid ... -
自定义一个方法原型,取得json对象某个值
2011-04-19 13:10 899Object.prototype.k = function(n ... -
JS获取父页面元素
2011-04-11 01:22 1038//iframe下获取父元素 var oParent = p ... -
一个关于获取修改后文本域值的问题
2011-04-10 23:56 802一个Textarea文本域问题。 <textarea ...
相关推荐
3.1 DOM不是JavaScript,它是文档 3.2 DOM的级别 3.2.1 DOM 0 级 3.2.2 DOM 1 级 3.2.3 DOM 2 级 3.2.4 DOM 3 级 3.2.5 哪个级别适合你 3.3 创建示例文档 3.3.1 创建DOM...
并且在所有浏览器中的行为都是一致的,原因也不难理解:浏览器需要一个稳定的DOM结构,而JavaScript可能会修改DOM(改变DOM结构或修改某个DOM节点),如果在JavaScript执行的同时还继续进行页面的解析,那么整个解析...
DOM文档对象模型是HTML和XML的应用程序接口(API),DOM将整个页面规划成由节点层次构成的文档。...由于DOM的使用上的简便,因此它成为了Web浏览器和javascript最喜欢的方法。document对象是BOM的对
html-dom-parser 在服务器(Node.js)和客户端(浏览器)上均可使用HTML到DOM解析器: HTMLDOMParser(string[, options])解析器将HTML字符串转换为描述DOM树JavaScript对象。例子const parse = require ( '...
3.1 DOM不是JavaScript,它是文档 3.2 DOM的级别 3.2.1 DOM 0 级 3.2.2 DOM 1 级 3.2.3 DOM 2 级 3.2.4 DOM 3 级 3.2.5 哪个级别适合你 3.3 创建示例文档 3.3.1 创建DOM...
3.1 DOM不是JavaScript,它是文档 3.2 DOM的级别 3.2.1 DOM 0 级 3.2.2 DOM 1 级 3.2.3 DOM 2 级 3.2.4 DOM 3 级 3.2.5 哪个级别适合你 3.3 创建示例文档 3.3.1 创建DOM...
第2章介绍了如何在浏览器中运用JavaScript语言,初步提到适时运用CSS规则、提升用户体验的原则。第3章解析与DOM、数据存储、创建交互层等有关的术语。第4章介绍DOM的基本构成和操作。第5章讲解了JavaScript数据存储...
使用javascript正则表达式的dom解析器。 不需要节点环境或特殊的浏览器!!! 支持react,react-native,vue等... 安装 npm install --save react-native-dom-parser 用法 import DomSelector from 'react-native-...
JS解析器只是JS代码运行的一种环境,浏览器是JS运行的一种环境,浏览器为JS提供了操作DOM对象和window对象等接口。Node.js也是JS的一种运行环境,node.js为JS提供操作文件、创建http服务、创建TCP、UDP服务等接口,...
DOM树由文档中的所有节点(元素节点、文本节点、注释节点等)所构成的一个树结构,DOM树的解析和构建是浏览器要实现的关键功能。既然DOM树是一个树结构,那么我们就可以使用遍历树结构的相关方法来对DOM树进行遍历,...
前端性能优化实践# 知识体系与小册格局 ## 写给读者 提起性能优化,大家现在脑海里第一时间会映射出什么内容呢? 可能是类似[“雅虎军规”]...具体来说,DNS 解析花时间,能不能尽量减少解析次数
浏览器对象模型 (BOM) 使 JavaScript 有能力与浏览器”对话”。 浏览器对象模型 (BOM) 浏览器对象模型(Browser Object Model (BOM))尚无正式标准。 由于现代浏览器已经(几乎)实现了 JavaScript 交互性方面的...
12.1.4 HTML结构和DOM对象的关系--用JavaScript通过DOM来操作HTML文档 12.2 DOM与浏览器实现 12.2.1 关于DOM HTML API 12.2.2 DOM的级别和特性 12.2.3 DOM的一致性 12.2.4 差异性--浏览器的...
由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,就需要通过JavaScript来操作DOM。 始终记住DOM是一个树形结构。操作一个DOM节点实际上就是这么几个操作: 更新:更新该DOM节点的内容,相当于更新了该...
目录1. DOM的概念和作用2.节点树3.DOM选择器:(查询、创建、添加,修改,删除)4.DOM的基本操作①.... 浏览器会根据 DOM 模型,将结构化文档(比如 HTML和 XML)解析成一系列的节点,再由这些节点组成一个树状结
3、采用简易的语言来描述大段的字串以及Dom/DHTML操作 4、可以很方便的解析XML文件格式的数据到指定模板。 采用该引擎,可以让它来完全处理View方面的事情,服务端Module直接输出Data就可以。让你的MVC模式连成一体...
DOM的作用是将网页转为一个javascript对象,从而可以使用javascript对网页进行各种操作(比如增删内容)。浏览器会根据DOM模型,将HTML文档解析成一系列的节点,再由这些节点组成一个树状结构。DOM的最小组成单位叫做...
刚接触到JavaScript的时候,便知道JavaScript是按顺序执行的,是如浏览器的解析DOM树一样的流程,解析DOM结构的时候,如果遇到JS脚本或者外联脚本便会停止解析,继续下载脚本之后,执行脚本,然后再解析DOM。...
先回顾下前一篇文章高性能JavaScript DOM编程,主要提了两点优化,一是尽量减少DOM的访问,而把运算放在ECMAScript这一端,二是尽量缓存局部变量,比如length等等,最后介绍了两个新的API querySelector()以及...