多种状态之间切换的最佳策略?

时间:2013-12-10 05:02:37

标签: jquery performance

我目前有三个课程:abc

元素一次只有这些类中的一个。

我目前的做法是每次需要更改课程时简单地调用以下内容:

$('#element').addClass('a').removeClass('b c');

还有其他方法可以达到相同的效果 - 但是,例如,使用属性选择器从长远来看可能会更昂贵。这不是一个三态循环,因为我有时可能需要将a切换为b ,反之亦然。我的上述方法是否是性能最有效的策略?如果不是,那么什么是更好的,或者我可以搜索哪些条款来指出我正确的方向?

2 个答案:

答案 0 :(得分:1)

使用toggleClass怎么样?如果你只有3个类,你可以保留一些数组,如下所示:

var states = {
  a: true,
  b: false,
  c: false
}

function toggle(el, state) { 
    var $el = $(el);
    for( var class in state)
        $el.toggleClass(class, state[class]);
}

toggle( someEl, states);

它也可以作为jQuery插件完成。 当然,这不是最快的方式,但我认为它具有很强的可读性。为了提高效率,您可以使用原生el.className(当您只有3个类时,它可能是最好的方法)。

答案 1 :(得分:1)

首先,除非你一次成千上万次这样做,否则我怀疑调用.removeClass('b c')的表现是否会引人注目。我的一般规则是按顺序编写具有以下优先级的代码:

  1. 正确性
  2. 可读性和可维护性
  3. 高效/紧凑
  4. 性能
  5. 如果我发现了一个合理的性能问题并且已经分析/测量了足以知道哪些代码需要改进的内容并且可以衡量我是否确实是改善它。

    如果对象上没有其他类,那么最简单的方法就是设置新的类名:

     $('#element').attr('class', 'a');
    

    如果你在对象上有其他类名,并且你事先知道它们是什么,那么你可以这样做:

     $('#element').attr('class', 'a ' + otherClassNmes);
    

    如果您不想假设其他类名的任何先验知识,那么您将需要查找其他类名并删除它们(如果存在)。您可以查看.removeClass()的jQuery代码,并确切了解它的作用。

    removeClass: function( value ) {
        var classes, elem, cur, clazz, j,
            i = 0,
            len = this.length,
            proceed = arguments.length === 0 || typeof value === "string" && value;
    
        if ( jQuery.isFunction( value ) ) {
            return this.each(function( j ) {
                jQuery( this ).removeClass( value.call( this, j, this.className ) );
            });
        }
        if ( proceed ) {
            classes = ( value || "" ).match( core_rnotwhite ) || [];
    
            for ( ; i < len; i++ ) {
                elem = this[ i ];
                // This expression is here for better compressibility (see addClass)
                cur = elem.nodeType === 1 && ( elem.className ?
                    ( " " + elem.className + " " ).replace( rclass, " " ) :
                    ""
                );
    
                if ( cur ) {
                    j = 0;
                    while ( (clazz = classes[j++]) ) {
                        // Remove *all* instances
                        while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
                            cur = cur.replace( " " + clazz + " ", " " );
                        }
                    }
                    elem.className = value ? jQuery.trim( cur ) : "";
                }
            }
        }
    
        return this;
    },