Javascript 最小化jquery.append站点的DOM访问
下面是一些代码,它们代表了我一直在为我的站点编写代码的一般风格:Javascript 最小化jquery.append站点的DOM访问,javascript,jquery,html,dom,append,Javascript,Jquery,Html,Dom,Append,下面是一些代码,它们代表了我一直在为我的站点编写代码的一般风格: !function(){ window.ResultsGrid = Class.extend(function(){ this.constructor = function($container, options){ this.items = []; this.$container = $($container); this.opti
!function(){
window.ResultsGrid = Class.extend(function(){
this.constructor = function($container, options){
this.items = [];
this.$container = $($container);
this.options = $.extend({}, defaultOptions, options);
this.$grid = $(
'<div class="results-grid">\
<ul></ul>\
</div>'
)
.css("margin", -this.options.spacing / 2);
this.$list = this.$grid.find("ul");
this.$container.append(this.$grid);
};
this.setItems = function(datas) {
this.$grid.addClass("display-none");
this.clear();
for (var k in datas) this.addItem(datas[k]);
this.$grid.removeClass("display-none");
};
this.addItem = function(data) {
var width = this.options.columnWidth;
var height = this.options.rowHeight;
var padding = this.options.spacing / 2;
if (this.options.columns > 0) width = (this.$container.width() - this.options.columns * this.options.spacing) / this.options.columns;
if (this.options.rows > 0) height = (this.$container.height() - this.options.rows * this.options.spacing) / this.options.rows;
if (this.options.ratio > 0) height = width / this.options.ratio;
var item = new (this.options.class)(this.$list, {
data: data,
type: this.options.type,
width: width,
height: height,
padding: padding
});
this.items.push(item);
};
this.clear = function() {
for (var k in this.items) this.items[k].destroy();
this.items.length = 0;
};
this.destroy = function() {
this.clear();
this.$grid.find("*").off();
this.$grid.remove();
}
});
var defaultOptions = {
class: ResultsItem.Game,
type: ResultsItem.Game.COMPACT,
columns:1,
rows:0,
spacing: 10,
rowHeight: 80,
ratio: 0,
columnWidth: 0
};
}();
!函数(){
window.ResultsGrid=Class.extend(函数(){
this.constructor=函数($container,options){
此参数为.items=[];
此.$container=$($container);
this.options=$.extend({},defaultOptions,options);
这是。$grid=$(
'\
\
'
)
.css(“边距”,-this.options.spating/2);
this.$list=this.$grid.find(“ul”);
this.$container.append(this.$grid);
};
this.setItems=函数(数据){
此.grid.addClass(“显示无”);
这个.clear();
对于(数据中的var k)此.addItem(数据[k]);
此.grid.removeClass(“显示无”);
};
this.addItem=函数(数据){
var width=this.options.columnWidth;
var height=this.options.rowHeight;
var padding=this.options.spating/2;
如果(this.options.columns>0)宽度=(this.$container.width()-this.options.columns*this.options.spating)/this.options.columns;
如果(this.options.rows>0)高度=(this.$container.height()-this.options.rows*this.options.spating)/this.options.rows;
如果(this.options.ratio>0)高度=宽度/this.options.ratio;
var item=new(this.options.class)(this.$list{
数据:数据,
类型:this.options.type,
宽度:宽度,
高度:高度,,
填充:填充
});
此.items.push(item);
};
this.clear=函数(){
对于(this.items中的var k)this.items[k].destroy();
this.items.length=0;
};
this.destroy=函数(){
这个.clear();
这是.$grid.find(“*”).off();
这是。$grid.remove();
}
});
var defaultOptions={
类别:ResultsItem.Game,
类型:ResultsItem.Game.COMPACT,
栏目:1,
行:0,
间距:10,
行高:80,
比率:0,
列宽:0
};
}();
这是我用于项目列表的东西,它只是一个基类,所以看起来毫无意义。
在我的主页上,我有一些这样的“结果网格”,我总共有大约100个项目要添加。这些项中的每一项都会对其代表性的jquery对象调用append、addClass、css等5次,因此在呈现之前需要大量的HTML处理。
问题是,有相当明显的时间延迟,因为我刚刚了解到,通过为每个项调用jquery.append之类的方法,我访问DOM的次数不必要
显而易见的解决方案是通过连接每个项目的html字符串为每个ResultsGrid做一个大的附加,但是我想知道在这和我目前的方法之间是否有一个中间地带,它的性能也会一样好,否则我将不得不重写大量代码
我喜欢从$(“”)开始,然后一点一点地追加,但显然这在性能上并不好,因为它会不断地重新计算内容,但我不需要知道每一步的宽度、高度和位置。理想情况下,我希望告诉它在我告诉它之前不要对DOM做任何事情。如果jquery无法做到这一点,那么我希望有一个库可以让我做到这一点。
我已经简要介绍了js模板库,但它们看起来不太吸引人。特别是角度。我不知道您要做什么,但据我所知,您可以尝试使用jquery的
$.detach()
函数
this.setItems = function(datas) {
//store the parent of this grid
this.parent = this.$grid.parent();
this.$grid.detach();
this.$grid.addClass("display-none");
this.clear();
//here you add your html/etc to the grid
for (var k in datas) this.addItem(datas[k]);
//reattach the grid to the parent
this.parent.append(this.$grid);
this.$grid.removeClass("display-none");
};
在分离的元素上执行DOM操作应该快得多,并像您所想的那样为您提供中间解决方案。
这是一个性能技巧,您可以找到,还有其他一些有用的技巧。我不知道您要做什么,但据我所知,您可以尝试使用jquery的
$.detach()
函数
this.setItems = function(datas) {
//store the parent of this grid
this.parent = this.$grid.parent();
this.$grid.detach();
this.$grid.addClass("display-none");
this.clear();
//here you add your html/etc to the grid
for (var k in datas) this.addItem(datas[k]);
//reattach the grid to the parent
this.parent.append(this.$grid);
this.$grid.removeClass("display-none");
};
在分离的元素上执行DOM操作应该快得多,并像您所想的那样为您提供中间解决方案。
这是一个性能技巧,您可以找到,还有其他一些有用的技巧。我在您包含的代码中只看到一个
.append()
,因此很难理解您要修复的.append()
操作。我在您包含的代码中只看到一个.append()
,因此很难理解是哪个.append()
您试图修复的操作。当jq对象被分离时,它仍然链接到Dom片段,当它被更改时,Dom片段会重新计算维度等等,对吗?我想知道是否有一个库允许我一点一点地创建dom元素,但在分离时,元素不会链接到dom,也不会接触dom或做任何无关的工作(直到我最终想将其添加到dom中),jquery处理所有的更改,而且速度更快,因为DOM不需要在每次修改时更新其所有结构。使用jquery已经在DOM之外创建了元素,相当于document.createElement()
,只有当您将它附加到另一个DOM元素时,该项才会“接触”DOM。啊,现在(我想)得到了它。我被误解所困扰。一些快速测试表明,detach节省了大量时间,谢谢!当一个jq对象被分离时,它仍然链接到一个Dom片段,当它被改变时,这个Dom片段会重新计算维度等等,对吗?我想知道是否有一个库允许我一点一点地创建dom元素,但是在分离时,不必接触dom或做任何无关的工作(直到我最终想将其添加到dom),元素不会链接到dom,jquery会处理所有这些