浏览器内存使用比较:内联onClick与使用JQuery .bind()
我有400个元素在页面上有点击事件绑定到他们(4种不同types的button,每个100个实例,每种types的点击事件执行相同的function,但具有不同的参数)。
我需要尽量减less这可能对性能造成的影响。 通过绑定单击事件到每个单独的事件(使用JQuery的bind()
),我正在采取什么样的性能(内存等)? 让内联onclick
调用每个button上的function会更有效率吗?
编辑澄清:):
我实际上有一个表(使用JQGrid生成),每行都有数据列,其后是4个图标“button”列,删除和其他三个业务function,使AJAX调用回到服务器:
| id | description | __ more data_ | _X__ | _ + __ | ____ | ____ | ------------------------------------------------- | 1 | ___数据____ | ____数据____ |图标|图标|图标|图标| | 2 | ___数据____ | ____数据____ |图标|图标|图标|图标| | 3 | ___数据____ | ____数据____ |图标|图标|图标|图标| | 4 | ___数据____ | ____数据____ |图标|图标|图标|图标|
我正在使用JQGrid的自定义格式化程序( http://www.trirand.com/jqgridwsiki/doku.php?id=wiki:custom_formatter )在每一行中构build图标“button”(我无法从服务器检索HTMLbutton)。
这是在我的自定义格式化函数,我可以很容易地build立图标的HTML和代码onclick
联onclick
调用适当的函数与适当的参数(该行中的其他列的数据)。 我使用行列中的数据作为我的函数的参数。
function removeFormatter(cellvalue, options, rowObject) { return "<img src='img/favoritesAdd.gif' onclick='remove(\"" + options.rowId + "\")' title='Remove' style='cursor:pointer' />"; }
所以,我可以想到两个select:
1)像我上面解释的那样在线onclick
– 要么 –
2) delegate()
(如下面的答案中提到的(非常感谢你!))
- 使用自定义格式化程序构build图标图像(每个图标types都有自己的类名称)。
- 将图标的
data()
设置为afterInsertRow JQGrid事件中的参数。 - 将
delegate()
处理程序应用于特定类的button(如下面所示的@KenRedler)
> $('#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)
我不知道如何浏览器密集型选项#2是我猜…但我喜欢保持远离我的DOM元素的Javascript 🙂
因为你不仅需要一个容器对象的通用解决scheme,而且对于jqGrid的解决scheme我可以给你一个更好的build议。
问题是,jqGrid已经使一些onClick
绑定。 所以如果只使用jqGrid事件处理程序中的现有资源,则不会花费更多的资源。 两个事件处理程序可以用于你: onCellSelect和beforeSelectRow 。 主要closures行为,你现在有什么build议你使用beforeSelectRow事件。 这样做的好处是,如果用户点击自定义button中的一个,行select可以保持不变。 使用onCellSelect ,将首先select行,然后调用onCellSelect事件处理程序。
你可以用如下的button来定义列
{ 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; }
where firstButtonColumnIndex = 8
和buttonNames = {8:'Add',9:'Edit',10:'Remove',11:'Details'}
。 在您的代码中,您可以将alert
replace为相应的函数调用。
如果你想在button上点击总是选中的行,你可以简化代码,直到下面的代码
onCellSelect: function (rowid,iCol/*,cellcontent,e*/) { if (iCol >= firstButtonColumnIndex) { alert("rowid="+rowid+"\nButton name: "+buttonNames[iCol]); } }
在你使用绑定到整个表的一个现有的 click
事件处理程序的方式(见源代码 ),只是说jqGrid你想要使用的处理。
我build议你另外总是使用gridview:true
来加速jqGrid的构build,但是如果你使用afterInsertRow
函数,那么你就不能使用它作为选项。
你可以在这里看到演示。
更新 :你有更多的select是使用formatter:'actions'
看到为答案准备的演示 。 如果你看“行为”格式的代码,如果你从事件绑定的angular度来看,它的工作大部分就像你当前的代码。
更新2 :代码的更新版本,你可以在这里看到。
您应该使用.delegate()
方法通过jQuery将所有元素的单个处理程序绑定到所有button的父元素。
对于不同的参数,你可以使用data-
属性到每个元素,并用.data()
方法检索它们。
你有没有考虑使用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>