diff --git a/README.md b/README.md index 9c9e5d4..bb0c4e5 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,18 @@ Configuration ================= cycleClass takes an array of classnames as first parameter. If none of the supplied classnames are set, the first one is set. -As second parameter cycleClass takes a config options with 2 possible options: +As second parameter cycleClass takes a config object with 4 possible options: * backwards - a boolean. Default false. If true, the cycling is done backwards. Beware that it is much faster to use a pre-reversed array to cycle backwards than to let cycleClass reverse the array on each call * onRoundTrip - a callback function taking the current element as only parameter. This callback is called everytime a round trip happens. +* transition - a callback function taking the current element, the old classname and the new classname as 3 parameters. this callback is responsible for changing the classes on the element and allows for transition effects to take place. +* toIndex - an integer. If toIndex is set, cycleClass does not cycle to the next class in the classList, but instead cycles to the class with the index toIndex. If toIndex is negative, the index is taken from the back. + +Note: onRoundTrip is called after transition. + Project Structure ================= -All you need is `cycleclass.jquery.js`. It does not use much jQuery, therefore should work with any jQuery version. Only newest jQuery is supported though (tests are ran against newest jQuery). +All you need is `cycleclass.jquery.js` or `cycleclass.jquery.min.js`. It does not use much jQuery, therefore should work with any jQuery version. Only newest jQuery is supported though (tests are ran against newest jQuery). In the directory `demo` you'll find a simple demo how it works. It's currently in german though. diff --git a/cycleclass.jquery.js b/cycleclass.jquery.js index 243fade..423261e 100644 --- a/cycleclass.jquery.js +++ b/cycleclass.jquery.js @@ -40,17 +40,22 @@ * @param {Array} classList array of classnames * @param {Object} [options] options object * @config {Boolean} [backwards] set to true if you want to cycle backwards + * @config {Integer} [toIndex] doesn't cycle to the next class, but cycles to the toIndex class in the classList. * @config {Function} [onRoundTrip] callback function if a round trip happens, receives the element as only argument + * @config {Function} [transition] callback function, called with 3 arguments (this element, old class, new class) which is responsible for the transition between the classes (cycleClass won't change classes if transition is set, this is tranisition's responsibility) * @return this */ $.fn.cycleClass = function(classList, options) { + var classCount = classList.length; options = options || {}; if(options.backwards) { classList = arrayReverseCopy(classList); } + if(options.toIndex < 0) { + options.toIndex += classCount; + } //TODO: test if its faster to sanitize classList - var classCount = classList.length; return this.each(function() { //abort if this is not an ELEMENT_NODE @@ -67,18 +72,30 @@ } //only remove class if a class was found + var cur=""; if(pos!==-1) { - var cur = classList[pos]; + cur = classList[pos]; className=className.replace(" "+cur+" ", " "); } //get next element, beware of round trips - var next = classList[(pos+1)%classCount]; + var next=""; + if(options.toIndex === undefined) { + next = classList[(pos+1)%classCount]; + } else { + next = classList[options.toIndex]; + } + //be tricky and put next as first classname for faster retrieval next time className=next+" "+className; //commit classname changes - this.className = $.trim(className); + //if transition, then classname change is done by transition function + if(options.transition) { + options.transition(this, cur, next); + } else { + this.className = $.trim(className); + } if(options.onRoundTrip) { if(pos===classCount-1) { @@ -87,4 +104,4 @@ } }); }; -})(jQuery); +})(jQuery); \ No newline at end of file diff --git a/cycleclass.jquery.json b/cycleclass.jquery.json index d065d6f..d52c173 100644 --- a/cycleclass.jquery.json +++ b/cycleclass.jquery.json @@ -1,7 +1,7 @@ { "name": "cycleclass", "title": "cycleClass - jQuery css-class cycling", - "description": "A small plugin that allows you to cycle throug css class, kind of like toggleClass on steroids.", + "description": "A small plugin that allows you to cycle through css classes, kind of like toggleClass on steroids.", "keywords": [ "toggle", "cycle" @@ -12,7 +12,7 @@ "url": "http://opensource.org/licenses/MIT" } ], - "version": "1.0.0", + "version": "1.2.0", "author": { "name": "Toni Schornboeck", "email": "toni.schornboeck@gmail.com" diff --git a/cycleclass.jquery.min.js b/cycleclass.jquery.min.js index 36aecab..e2d9070 100644 --- a/cycleclass.jquery.min.js +++ b/cycleclass.jquery.min.js @@ -7,4 +7,4 @@ * Released unter the MIT License * http://opensource.org/licenses/MIT */ -(function(g){g.fn.cycleClass=function(b,d){d=d||{};if(d.backwards){for(var h=b,j=[],k=h.length,a=k-1;0<=a;--a)j[k-a-1]=h[a];b=j}var f=b.length;return this.each(function(){if(1===this.nodeType){for(var c=(" "+this.className+" ").replace(/[\t\r\n]/g," "),e=-1,a=0;aa.toIndex&&(a.toIndex+=g);return this.each(function(){if(1===this.nodeType){for(var e=(" "+this.className+" ").replace(/[\t\r\n]/g," "),f=-1,c=0;c"); + var classList=["one", "two", "three"]; + + ok(testClasses($elem, ["one", "other"], ["two", "three"]), "setup"); + $elem.cycleClass(classList); + ok(testClasses($elem, ["two", "other"], ["one", "three"]), "first step"); +}); + +test("don't remove partial class names", function() { + var $elem=$("
"); + var classList=["one", "two", "three"]; + + ok(testClasses($elem, ["one", "oneone"], ["two", "three"]), "setup"); + $elem.cycleClass(classList); + ok(testClasses($elem, ["two", "oneone"], ["one", "three"]), "first step"); +}); + +test("transition call", function() { + var $elem=$("
"); + var classList=["one", "two", "three"]; + + var transitionCalled=false; + + var config={ + transition:function() { ok(transitionCalled===false, "transition call"); transitionCalled=true; } + }; + + ok(testClasses($elem, ["one"], ["two", "three"]), "setup"); + $elem.cycleClass(classList, config); + ok(testClasses($elem, ["one"], ["two", "three"]), "first step"); + + ok(transitionCalled===true, "transition called"); +}); + +test("correct transition parameter", function() { + var $elem=$("
"); + var classList=["one", "two", "three"]; + + var config={ + transition:function(e, oldClass, newClass) { + ok($(e).data("dings")==="dangs", "element parameter"); + ok(oldClass==="one", "old class parameter"); + ok(newClass==="two", "new class parameter"); + } + }; + + ok(testClasses($elem, ["one"], ["two", "three"]), "setup"); + $elem.cycleClass(classList, config); + ok(testClasses($elem, ["one"], ["two", "three"]), "first step"); +}); + +test("jump to index", function() { + var $elem=$("
"); + var classList=["one", "two", "three"]; + var config={ + toIndex: 2 + }; + + ok(testClasses($elem, ["one"], ["two", "three"]), "setup"); + $elem.cycleClass(classList, config); + ok(testClasses($elem, ["three"], ["one", "two"]), "first step"); +}); + +test("jump to negative index", function() { + var $elem=$("
"); + var classList=["one", "two", "three"]; + var config={ + toIndex: -3 + }; + + ok(testClasses($elem, ["three"], ["one", "two"]), "setup"); + $elem.cycleClass(classList, config); + ok(testClasses($elem, ["one"], ["tow", "three"]), "first step"); }); \ No newline at end of file