jQuery:通过一组类来旋转元素

时间:2011-12-06 15:26:35

标签: jquery class

toggleClass非常棒,如果我只想要使用两种演示风格,但很多时候我有两种以上的状态我想使用。

例如,如果我想要旋转三个类:

if ($(this).hasClass("A"))
   $(this).removeClass("A").addClass("B");
else if ($(this).hasClass("B"))
   $(this).removeClass("B").addClass("C");
else if ($(this).hasClass("C"))
   $(this).removeClass("C").addClass("A");

我想为我做一个简单的方法,例如:

$(this).rotateClass('A', 'B', 'C');

是否存在执行此操作的现有jQuery方法或插件?

6 个答案:

答案 0 :(得分:1)

这是我的尝试。

  $.fn.rotate= function( classes ) {
      $element = this;  // element the rotate is being applied to
      for( var i = 0; i <  classes.length; i++ ){   // look through the classes array
          if( $element.hasClass( classes[i] ) ){  // check if current element has the class specified in the array 
              $element.removeClass( classes[i] );  // if it does then remove the class 
              $element.addClass( classes[ ++i % classes.length ] );  
              return $element; // return the current element so other functions can be applied to it. 
           }
      }
  }

您可以通过调用元素上的.rotate并传入要旋转的类数组来使用它。

这是一个interactive演示。我刚刚添加了animate来表明你可以在旋转完成后将其他jQuery函数应用于元素。

 $('#test').rotate(['A','B','C']); 

我们使用模数运算符的原因是,如果i>然后我们想要正确的索引。例如,类的数组是['A','B','C'],如果我们元素上的当前类是'C',那么当前类的索引是2(数组是基于0的索引),那么如果我们增加2 + 1 = 3得到我们想要旋转它的类但我们在索引3没有任何类因此3%3 = 0这是'A'的索引,这就是我们想要的,因此模数每次都会给我们正确的索引。

答案 1 :(得分:1)

以下是我使用的内容:

$.fn.rotateClass = function(classes) {
    var $set = this.each(function () {
        var $this = $(this);
        var index = (($this.data("currentClassIndex")) ? $this.data("currentClassIndex") : 0) % classes.length;

        $this.removeClass(classes.join(" "))
             .addClass(classes[index])
             .data("currentClassIndex", ++index);
    });

    return $set;
}

没有for循环,没有hasClass调用,与元素集兼容,非常紧凑且性能非常高。

用法:

$("#randomDiv").rotateClass(["classA", "classB", "classC", "classD"]);

答案 2 :(得分:0)

将它们放入数组:

var arr = ['A', 'B', 'C'];
var i = 0;

然后在处理程序中:

i = ++i % arr.length;

$(this).toggleClass( this.className + ' ' + arr[ i ] );

使用this.className假设没有其他类应用于此元素。

<强> JSFIDDLE DEMO


如果可能有其他类,请使用:

$(this).removeClass( arr[ i ] );
i = ++i % arr.length;
$(this).addClass( arr[ i ] );

<强> JSFIDDLE DEMO


如果可能有其他元素,并且每个元素都需要自己的状态,则可以使用闭包将唯一i与每个元素相关联:

$('div').each(function() {
    var i = 0;

    $(this).click(function() {
        $(this).removeClass( arr[ i ] );
        i = ++i % arr.length;
        $(this).addClass( arr[ i ] );
    });
});

<强> JSFIDDLE DEMO

答案 3 :(得分:0)

此插件代码将在传递的类之间轮换(但是很多都有(2-n)。如果在对象上找不到任何传递的类,则设置第一个类。

$.fn.rotateClass(/* pass multiple class names here */) {
    for (var i = 0; i < arguments.length; i++) {
        if (this.hasClass(arguments[i])) {
            this.removeClass(arguments[i]));
            i++;
            if (i >= arguments.length) {
                i = 0;
            }
            this.addClass(arguments[i]);
            return(this);
        }
    }
    // none found so set the first class
    if (arguments.length > 0) {
        this.addClass(arguments[0]);
    }
    return(this);
}

此版本的代码假定您将相同的类应用于jQuery对象中的所有DOM对象,并且它们都具有相同的状态。它可以扩展为单独处理jQuery对象中的每个DOM对象,并在需要时单独旋转每个DOM对象。

答案 4 :(得分:0)

您仍然可以使用toggleClass并将其传递给函数:

$(this).toggleClass(function() {
    if ($(this).hasClass('red')) {
      return 'green red';
    }

    if ($(this).hasClass('green')) {
      return 'blue green';
    }

    if ($(this).hasClass('blue')) {
      return 'red blue';
    }
});

虽然不是最容易维护的代码,但将它包装在插件中可能会更好。

http://jsbin.com/inaduy/edit#javascript,html,live

现在进入一个非常基本的插件(需要一些验证)。您只需将包含类对的对象数组传递给swap。

var classArray = [{current: 'red', next:'green'}, {current:'green', next:'blue'}, {current:'blue', next:'red'}];

$('#hello').click(function() {
  $(this).toggleRotate(classArray);
});

(function($) {
  $.fn.toggleRotate = function(classes) {

    return $(this).toggleClass(function() {
      var l = classes.length;
      for (var i = 0; i < l; i++) {
        if ($(this).hasClass(classes[i].current)) {
          return classes[i].current + ' ' + classes[i].next;
        }        
      }
      // If it makes it here return the first current value
      return classes[0].current;
    });
  };
})(jQuery);

http://jsbin.com/inaduy/2/edit

答案 5 :(得分:0)

我目前的解决方案:

$.fn.mapClasses = function(mapping){
  return this.each(function(){
    this.className = this.className.split(/\s+/).map(function(klass){
      return mapping[klass] || klass
    }).join(' ');
  });
};
$.fn.rotateClasses(){
  var mapping = {};
  var prev = arguments[0];
  for (var i = arguments.length - 1; i >= 0; i--){
    mapping[ arguments[i] ] = prev;
    prev = arguments[i];
  }
  return this.mapClasses(mapping);
};