浏览器内存使用比较:内联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和代码onclickonclick调用适当的函数与适当的参数(该行中的其他列的数据)。 我使用行列中的数据作为我的函数的参数。

  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() (如下面的答案中提到的(非常感谢你!))

  1. 使用自定义格式化程序构build图标图像(每个图标types都有自己的类名称)。
  2. 将图标的data()设置为afterInsertRow JQGrid事件中的参数。
  3. 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 = 8buttonNames = {8:'Add',9:'Edit',10:'Remove',11:'Details'} 。 在您的代码中,您可以将alertreplace为相应的函数调用。

如果你想在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>