繁体   English   中英

我有大量的元素,而jQuery的each()函数正在杀死我的浏览器-如何改善我的代码?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM