[英]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.