jQuery:通过一组类旋转元素

jQuery:通过一组类旋转元素,jquery,class,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")) $(th

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方法或插件可以执行此操作?

将它们放在一个数组中:

var arr = ['A', 'B', 'C'];
var i = 0;
然后在处理程序中:

i = ++i % arr.length;

$(this).toggleClass( this.className + ' ' + arr[ i ] );
this.className
的使用假定没有其他类应用于此元素


如果可能存在其他类别,请使用以下选项:

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


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

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

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

此插件代码将在传递的类之间循环(无论有多少个(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);
}
$.fn.rotateClass(/*在此处传递多个类名*/){
for(var i=0;i=arguments.length){
i=0;
}
this.addClass(参数[i]);
返回(本);
}
}
//没有人找到这样的头等舱
如果(arguments.length>0){
this.addClass(参数[0]);
}
返回(本);
}

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

您仍然可以使用
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';
    }
});
但这不是最容易维护的代码,所以最好将其包装在插件中

现在,一个非常基本的插件(需要一点验证)。您只需传递一个包含要交换的类对的对象数组

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);
var classArray=[{current:'red',next:'green'},{current:'green',next:'blue'},{current:'blue',next:'red'}];
$('#hello')。单击(函数(){
$(this.toggleRotate(classArray);
});
(函数($){
$.fn.toggleRotate=函数(类){
return$(this.toggleClass(function()){
var l=类别。长度;
对于(变量i=0;i
我当前的解决方案:

$.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);
};

这是我的尝试

  $.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. 
           }
      }
  }
我们使用模运算符的原因是,如果i>数组的长度,那么我们需要正确的索引。例如,类的数组是['A','B','C'],如果元素上的当前类是'C',那么当前类的索引是2(数组是基于索引的0),那么如果我们增加2+1=3来得到我们想要旋转的类,但是我们在索引3没有任何类,因此3%3=0是'A'的索引,这就是我们想要的,因此,每次模数都会为我们提供正确的索引。

以下是我使用的:

$.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"]);
$("#randomDiv").rotateClass(["classA", "classB", "classC", "classD"]);