帮助减少文件.Getelementbyid dom调用或重写算法
help with reducing document.getelementbyid dom calls or rewrite the algorithm
我写了这个函数,它有一堆文档。Getelementbyid调用位于for循环中的id (a,b,c,d,e,f)的重复模式,使它们成为a1,b1,c1…a6,b6,c6…可以将变量赋值给文档。Getelementbyid而不给出特定的id,即var xyz = document.getelementbyid;我记得有一篇文章展示了不同的dom调用编写方法。
在这种情况下我能做的最好的就是var dom = document;
?基本上,我有多行div,每个div都有一个唯一的id。
谢谢。
编辑2我无法让Andrew的代码工作,但我按照他的想法重写了代码,结果比我最初设想的要简单。底部的最后一个代码块。
function display (namearr, current) {
var tldstr = document.getElementById("dlist").innerHTML;
tldstr = tldstr.slice(0, -1)
var tldarr = tldstr.split(",");
index = current - 1;
var arrlen = tldarr.length;
var img = "<img src='../loader1.gif' alt='loading' width='40' />";
for (z=0; z<10; z++){
i=z+1;
if (index >= arrlen) {
document.getElementById("a"+i).className = "tldn";
document.getElementById("b"+i).className = "tldn";
document.getElementById("c"+i).className = "tldn";
document.getElementById("d"+i).className = "tldn";
document.getElementById("e"+i).className = "tldn";
document.getElementById("f"+i).className = "tldn";
}
else if ( tldarr[index] == "n" || tldarr[index].length != 6)
{
document.getElementById("a"+i).innerHTML = img;
document.getElementById("b"+i).innerHTML = img;
document.getElementById("c"+i).innerHTML = img;
document.getElementById("d"+i).innerHTML = img;
document.getElementById("e"+i).innerHTML = img;
document.getElementById("f"+i).innerHTML = img;
}//close first elseif
else {
tldstr = tldarr[index];
document.getElementById("a"+i).className = "tld"+tldstr.charAt(0);
document.getElementById("b"+i).className = "tld"+tldstr.charAt(1);
document.getElementById("c"+i).className = "tld"+tldstr.charAt(2);
document.getElementById("d"+i).className = "tld"+tldstr.charAt(3);
document.getElementById("e"+i).className = "tld"+tldstr.charAt(4);
document.getElementById("f"+i).className = "tld"+tldstr.charAt(5);
}//close second elseif
index++;
}//close first for loop
}//end of function
HTML标记<div class="xyz">
<div class="tldn" id="a1">xxx</div>
<div class="tldn" id="b1">xxx</div>
<div class="tldn" id="c1">xxx</div>
<div class="tldn" id="d1">xxx</div>
<div class="tldn" id="e1">xxx</div>
<div class="tldn" id="f1">xxx</div>
</div>
<div class="123">
<div class="tldn" id="a2">xxx</div>
<div class="tldn" id="b2">xxx</div>
<div class="tldn" id="c2">xxx</div>
<div class="tldn" id="d2">xxx</div>
<div class="tldn" id="e2">xxx</div>
<div class="tldn" id="f2">xxx</div>
</div>
工作代码function display (namearr, current) {
var aarr = [];
var barr = [];
var carr = [];
var darr = [];
var earr = [];
var farr = [];
for (var z=1; z<=10; z++) {
c = z-1;
aarr[c] = document.getElementById("a"+z);
barr[c] = document.getElementById("b"+z);
carr[c] = document.getElementById("c"+z);
darr[c] = document.getElementById("d"+z);
earr[c] = document.getElementById("e"+z);
farr[c] = document.getElementById("f"+z);
var tldstr = document.getElementById("dlist").innerHTML;
tldstr = tldstr.slice(0, -1)
var tldarr = tldstr.split(",");
index = current - 1;
var arrlen = tldarr.length;
var img = "<img src='../loader1.gif' alt='loading' width='40' />";
for (i=0; i<10; i++){
if (index >= arrlen) {
aarr[i].className = "tldn";
barr[i].className = "tldn";
carr[i].className = "tldn";
.
.
.
}
else if ( tldarr[index] == "n" || tldarr[index].length != 6)
{
aarr[i].innerHTML = img;
barr[i].innerHTML = img;
.
.
.
}//close first elseif
else {
tldstr = tldarr[index];
aarr[i].className = "tld"+tldstr.charAt(0);
aarr[i].className = "tld"+tldstr.charAt(1);
.
.
.
}//close second elseif
index++;
}//close first for loop
}
不能将方法赋值给变量。不过你可以把它封装在一个函数中。
function setClassName(id, className) {
document.getElementByID(id).className = className;
}
if (index >= arrlen) {
setClassName("a"+i, "tldn");
setClassName("b"+i, "tldn");
//etc
}
或者创建一个字母数组,然后传入
//pseudocode
var foo = array(a, b, c, d, e, f);
function ( foo, className ) {
//iterate over array and apply class name
}
对我来说这似乎是一个分为两部分的问题:
减少作用域链的遍历
您引用的优化策略之一是分配给局部(函数作用域)变量。这样做通常是为了尽量减少访问该变量时需要遍历的作用域链。《高性能Javascript》一书(相关章节的PDF)很好地介绍了这一点。
沿着这些思路,将document
混叠到一个函数级变量可以通过缩短作用域链而在效率上获得一些边际增益。然而,这可以说是一个微优化,它不会处理您提到的主要潜在减速,即循环中重复的DOM调用。
简化DOM调用
为了更好的代码可维护性和效率,您应该消除按ID查询大量元素的方式(尽管按ID获取元素非常有效,但重复调用确实累加在一起,在这种情况下可能会使代码不那么清晰)。这样做的一个好方法依赖于jQuery或其他具有良好选择器支持的库。使用库(下面的示例假设为jQuery)将减少您必须编写的代码量,同时处理跨浏览器的差异。
考虑你引用的元素有哪些共同之处,以及如何将它们作为一个集合进行查询。一个好的策略是为每个元素分配类名(在当前设置元素id的服务器端代码中),从而明确每个元素属于哪个集合。class="cell type_a set_4"
将为当前ID为"a4"的元素设置类。
然后,立即检索完整的元素集合。指定父元素将使事情更有效率:
var elements = $('#id_of_parent_element .cell')
一旦检索到元素,就可以将列表过滤到所需的元素,而无需进一步调用DOM。下面是循环的最终代码(注意,这也比按ID分别获取所有这些代码要简单得多):
var elements = $('#id_of_parent_element .cell'); // get the "cell" elements
for (z=0; z<10; z++){
var current_elements = elements.filter('.set_' + z); // filter to numbered set
if (index >= arrlen) {
current_elements.addClass('tldn');
} else if ( tldarr[index] == "n" || tldarr[index].length != 6) {
current_elements.innerHTML = img;
} else {
var tldstr = tldarr[index];
current_elements.each(function(index, element) {
$(this).addClass("tld" + tldstr.charAt(index));
});
}
}
请注意,调用DOM的次数和运行时间将取决于浏览器,因为jQuery尝试在可能的情况下使用像document.getElementsByClassName
这样的本地函数,同时仍然支持没有它们的旧版本。但是最终的结果应该是更少的DOM调用、边际的效率提升和更少的代码行维护。
如果div
s的计数在页面存在期间是恒定的,那么接下来的代码可以减少document.getElementsById
的调用,提高display()
函数的速度:
var divsObj={a:[],b:[],c:[],d:[],e:[],f:[]};
for (var i=1; i<=10; i++) {
divsObj.a.push(document.getElementById("a"+i));
divsObj.b.push(document.getElementById("b"+i));
divsObj.c.push(document.getElementById("c"+i));
divsObj.d.push(document.getElementById("d"+i));
divsObj.e.push(document.getElementById("e"+i));
divsObj.f.push(document.getElementById("f"+i));
}
function display (namearr, current) {
var tldstr = document.getElementById("dlist").innerHTML;
tldstr = tldstr.slice(0, -1)
var tldarr = tldstr.split(",");
//index = current - 1;
var index = current - 1; // if *index* not global or closur variable use *var*
var arrlen = tldarr.length;
var img = "<img src='../loader1.gif' alt='loading' width='40' />";
for (var i=0; i<10; i++) {
if (index >= arrlen) {
divsObj.a[i].className = "tldn";
divsObj.b[i].className = "tldn";
divsObj.c[i].className = "tldn";
divsObj.d[i].className = "tldn";
divsObj.e[i].className = "tldn";
divsObj.f[i].className = "tldn";
}
else if ( tldarr[index] === "n" || tldarr[index].length !== 6) {
divsObj.a[i].innerHTML = img;
divsObj.b[i].innerHTML = img;
divsObj.c[i].innerHTML = img;
divsObj.d[i].innerHTML = img;
divsObj.e[i].innerHTML = img;
divsObj.f[i].innerHTML = img;
}
else {
tldstr = tldarr[index];
divsObj.a[i].className = "tld"+tldstr.charAt(0);
divsObj.b[i].className = "tld"+tldstr.charAt(1);
divsObj.c[i].className = "tld"+tldstr.charAt(2);
divsObj.d[i].className = "tld"+tldstr.charAt(3);
divsObj.e[i].className = "tld"+tldstr.charAt(4);
divsObj.f[i].className = "tld"+tldstr.charAt(5);
}
index++;
}
}
是否要为document.getElementById创建快捷方式?如果有,你可以这样做
yourshortcut = function(id) { return document.getElementById(id); };
如果您使用模块模式并将窗口和文档作为参数传递给它,那么任何好的缩小器都会将文档减少到单个字母。还可以考虑接受undefined作为调用函数时不传入的第三个参数。
我强烈推荐阅读http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
我喜欢使用带有附加参数的松散增强格式:
var MODULE = (function (my, window, document, undefined) {
// add capabilities...
return my;
}(MODULE || {}, window, document));
注意这是如何保证undefined是未定义的——这可能被恶意代码设置。这篇文章来自Paul Irish的《我从jQuery源中学到的10件事》——也是一篇很好的阅读文章。
我不建议这样做,但我认为您正在寻找将函数分配为变量(即函数指针)。
var getById = document.getElementById;
然后是:
getById("a"+i).className = "tldn";
我建议使用像prototype或jQuery这样的库来清理你的代码。然后你的代码可以写得更简洁:
$ (" # " + i) .addClass("tldn");
另外,就像一个关于风格的注释-你为什么要分配个人id呢?听起来,您应该在标记中放入"tldn"类来引用一组元素(毕竟,这是元素上的"class"属性的预期用途)。然后,您可以使用document.getElementsByClassName("tldn")
来引用所有元素,而不是编写六行代码来引用一组元素。
注意:getElementsByClassName不支持旧版本的浏览器,如IE8及以下版本
- 如何使jQuery插件函数可调用以供独立使用,而不在集合上操作
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 如何用JQuery$.Deferred重写AJAX调用
- Mootools 类扩展了调用重写的父方法
- 重写立即调用的函数
- 文件上传器表单提交事件调用面板以显示包含文件更新程序我想删除代码重写在 jquery 中使用循环重写所有文件类型
- 调用原型的重写方法,然后调用下一个原型的重写方法错误
- 调用在父类中被重写的函数
- 重写Javascript本机方法并调用super
- 重写对象'的克隆属性超出了最大调用堆栈大小
- 从父类调用重写的静态方法
- Javascript数组或对象可以被重写为可调用的吗?
- 当多次调用Angular服务时,它会重写自身
- 是否可以重写“调用”?函数
- 帮助减少文件.Getelementbyid dom调用或重写算法
- 有没有一种好的模式可以让JavaScript在不知道特定父类的情况下调用父类中的重写函数?
- WPF应用程序在重写CefApp.GetRenderProcessHandler()以使JS调用c#后崩溃
- Javascript,从重写方法调用超类方法的方便方法
- 从Java Script中子类中的重写方法调用超类方法
- 重写数组push时调用原始方法