我在页面上有大约400个元素,它们有点击事件(4个不同类型的按钮,每个按钮有100个实例,每个类型的点击事件执行相同的功能,但参数不同)。
我需要尽可能减少对性能的任何影响。通过将点击事件单独绑定到每个(使用JQuery的bind()
),我采取了什么样的性能(内存等)?在内联onclick
调用每个按钮上的函数会更有效吗?
编辑以澄清:):
我实际上有一个表(使用JQGrid生成),每行有数据列,后跟4个图标'按钮'列 - 删除&另外三个使AJAX调用回服务器的业务函数:
|id|description|__more data_|_X__|_+__|____|____| ------------------------------------------------- | 1|___data____|____data____|icon|icon|icon|icon| | 2|___data____|____data____|icon|icon|icon|icon| | 3|___data____|____data____|icon|icon|icon|icon| | 4|___data____|____data____|icon|icon|icon|icon|
我正在使用JQGrid的自定义格式化程序(http://www.trirand.com/jqgridwsiki/doku.php?id=wiki:custom_formatter)在每行中构建图标“按钮”(我无法从服务器检索按钮HTML)。
在我的自定义格式化程序功能中,我可以轻松地在内联onclick
中构建图标HTML和代码,并使用适当的参数调用相应的函数(来自该行中其他列的数据)。我使用行列中的数据作为我的函数的参数。
function removeFormatter(cellvalue, options, rowObject) {
return "<img src='img/favoritesAdd.gif' onclick='remove(\"" + options.rowId + "\")' title='Remove' style='cursor:pointer' />";
}
所以,我可以想到两个选择:
1)如上所述,内联onclick
- 或 -
2)delegate()
(如下面的答案所述(非常感谢你!))
data()
设置为delegate()
中的参数3}} JQGrid事件。 > $('#container').delegate('.your_buttons','click',function(e){
> e.preventDefault();
> var your_param = $(this).data('something'); // store your params in data, perhaps
> do_something_with( your_param );
> }); //(code snippet via @KenRedler)
处理程序应用于特定类的按钮(如下所述@KenRedler){{1}}
我不确定浏览器密集型选项#2是多少...我想确保Javascript远离我的DOM元素:)
答案 0 :(得分:8)
因为你不仅需要一些带有一些容器对象的通用解决方案,而且还有jqGrid的解决方案,我可以再提示一下。
问题是jqGrid已经创建了一些onClick
绑定。因此,如果您只使用jqGrid事件处理程序中的现有资源,则不会花费更多资源。两个事件处理程序对您有用:onCellSelect和beforeSelectRow。为了与您目前拥有的内容大致相近,我建议您使用beforeSelectRow事件。它的优点是,如果用户单击自定义按钮中的一个,则行选择可以保持不变。使用onCellSelect首先选择行,然后调用onCellSelect事件处理程序。
您可以使用以下按钮定义列
{ name: 'add', width: 18, sortable: false, search: false,
formatter:function(){
return "<span class='ui-icon ui-icon-plus'></span>"
}}
在上面的代码中,我使用了jqGrid的自定义格式化程序,但没有任何事件绑定。
的代码beforeSelectRow: function (rowid, e) {
var iCol = $.jgrid.getCellIndex(e.target);
if (iCol >= firstButtonColumnIndex) {
alert("rowid="+rowid+"\nButton name: "+buttonNames[iCol]);
}
// prevent row selection if one click on the button
return (iCol >= firstButtonColumnIndex)? false: true;
}
其中firstButtonColumnIndex = 8
和buttonNames = {8:'Add',9:'Edit',10:'Remove',11:'Details'}
。在您的代码中,您可以将alert
替换为相应的函数调用。
如果要在按钮上单击总是选择行,则可以将代码简化为以下
onCellSelect: function (rowid,iCol/*,cellcontent,e*/) {
if (iCol >= firstButtonColumnIndex) {
alert("rowid="+rowid+"\nButton name: "+buttonNames[iCol]);
}
}
使用绑定到整个表的一个现有 click
事件处理程序的方式(请参阅the source code),然后说jqGrid您想要使用的句柄。
我建议你另外总是使用gridview:true
来加速jqGrid的构建,但如果你使用afterInsertRow
函数作为一个选项,那就不能使用它。
您可以看到演示here。
更新:您还有一个选项是formatter:'actions'
使用为the demo准备的the answer。如果你看一下'actions'的代码,那么格式化程序的工作方式就像你当前的代码一样,如果你从事件绑定方面看它。
更新2 :您可以看到的here代码的更新版本。
答案 1 :(得分:2)
您应该使用.delegate()
方法通过jQuery将所有元素的单击处理程序绑定到所有按钮的父元素。
对于不同的参数,您可以对每个元素使用data-
属性,并使用.data()
方法检索它们。
答案 2 :(得分:2)
您是否考虑过使用delegate()
?你在容器元素上有一个处理程序而不是数百个。像这样:
$('#container').delegate('.your_buttons','click',function(e){
e.preventDefault();
var your_param = $(this).data('something'); // store your params in data, perhaps
do_something_with( your_param );
});
假设这样的总体布局:
<div id="container">
<!--- stuff here --->
<a class="your_buttons" href="#" data-something="foo">Alpha</a>
<a class="your_buttons" href="#" data-something="bar">Beta</a>
<a class="your_buttons" href="#" data-something="baz">Gamma</a>
<a class="something-else" href="#" data-something="baz">Omega</a>
<!--- hundreds more --->
</div>