[英]I have a huge set of elements and jQuery's each() function is killing my browser - How can I improve my code?
我使用編寫的兩個插件來查找所有單選/復選框輸入並選擇表單中的框並為其設置樣式。
我現在有一個很大的表格,里面有很多復選框,而Firefox在我的插件嘗試為每個樣式設置樣式時都掛了。
這是插件代碼:
(function($)
{
$.fn.stylecheck = function(options)
{
/*
Parameters:
image: the image to load in place of the checkboxes/radio buttons
offset: the Y offset (background-position) to show the 'on' position of the image
*/
return this.each(function()
{
if (!$(this).is(':checkbox') && !$(this).is(':radio'))
return;
var $input = $(this);
var $image = null;
var $contianer = null;
// Wrap the input and then hide it
$input.wrap('<div class="stylecheck-container" style="display: inline" />').addClass('stylecheck').hide();
$container = $input.parent('div.stylecheck-container');
$image = $container.append('<div class="stylecheck-image" />').children('div.stylecheck-image');
$image.css(
{
"width" : options['width'],
"height" : (options['height'] / 2),
"display" : "inline-block",
"background" : ($input.is(':checked')) ? ("url('" + options['image'] + "') no-repeat 0px -17px") : ("url('" + options['image'] + "') no-repeat 0px 0px")
});
if ($container.parent('label').length > 0)
{
$container.append('<label style="display: inline; position: relative; top: -2px">' + $container.parent('label').text() + '</label> ');
$container.parent('label').replaceWith($container);
}
$input.change(function()
{
if ($input.is(':checked'))
$image.css("background-position", "0px -" + (options['height'] / 2) + "px");
else
$image.css("background-position", "0px 0px");
});
$container.click(function()
{
if ($input.is(':checkbox'))
{
if (!$input.is(':checked'))
$input.attr('checked', true);
else
$input.removeAttr('checked');
}
if ($input.is(':radio') && !$input.is(':checked'))
{
$findme = $('input[name="' + $input.attr('name') + '"]:checked')
if ($findme.length > 0)
$findme.each(function() { $(this).attr('checked', false); $(this).trigger('change'); });
$input.attr('checked', true);
}
$input.trigger('change');
});
});
};
})(jQuery);
我猜測問題出在jQuery的each()函數搜索數百個我的復選框...
無論如何,有沒有改進我的插件?
頁面加載時並非所有復選框都可見(顯示:隱藏)。 因此,我認為一種替代方法是僅在切換可見性時才設置復選框的樣式-不過,如果可以改進我的上述代碼,我想把它保留為最后的選擇。
干杯。
這是您可以改進的一件事。 您正在創建兩個jQuery對象,並針對兩個對象調用.is()
。 然后在下一行中,您將創建另一個,並將其緩存在變量中。
在if()
語句之前將其緩存在變量中,然后使用緩存的版本,或者將jQuery對象完全拋棄在if()
語句中,然后執行以下操作:
var type = this.type.toLowerCase();
if (type != 'checkbox' && type != 'radio')
return;
其余的將是@Nick Craver發布的jsFiddle的文檔。
總體而言,請盡量避免使用jQuery。 使用本機API更快。 當您確實使用jQuery時,請以盡可能最小的方式使用它。
您可以更改此行:
$container = $input.parent('div.stylecheck-container');
對此:
$container = $input.parent();
由於包裝了$ input,因此無需使用選擇器測試父級。
更改此行:
"background" : ($input.is(':checked')) ? ("url('" + options['image'] + "') no-repeat 0px -17px") : ("url('" + options['image'] + "') no-repeat 0px 0px")
為此,以避免調用.is()
。 這樣做this.checked
返回一個布爾值:
"background" : this.checked ? ("url('" + options['image'] + "') no-repeat 0px -17px") : ("url('" + options['image'] + "') no-repeat 0px 0px")
在您分配的處理程序中,將$input.is('checked')
更改$input[0].checked
。 這將獲取DOM元素,並獲取checked
屬性。 這不會加快插件的執行速度,但會改善處理程序。
同樣,將$input.is(':checkbox')
更改$input[0].type == "checkbox"
(同樣使用radio
)。 您甚至可以像我在此答案頂部所做的那樣,將類型緩存在變量中,然后使用該值。 如在type == "checkbox"
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.