In this short tutorial we will be making a jQuery plugin that will shuffle the text content of any DOM element – an interesting effect that can be used in headings, logos and slideshows.
Updated on 10 Sep 2011: The plugin was slightly improved by including a callback function, called when the animation is complete. Just pass it as a property of the arguments object: $(‘#el’).shuffleLetters({callback:function(){}});
The Code
The first step is to write the backbone of our jQuery plugin. We will place the code inside a self-executing anonymous function, and extend $.fn.
assets/js/jquery.shuffleLetters.js
(function($){
$.fn.shuffleLetters = function(prop){
// Handling default arguments
var options = $.extend({
// Default arguments
},prop)
return this.each(function(){
// The main plugin code goes here
});
};
// A helper function
function randomChar(type){
// Generate and return a random character
}
})(jQuery);
Next we will turn our attention to the randomChar() helper function. It will take a type argument (one of “lowerLetter“, “upperLetter” or “symbol“) and return a random character.
function randomChar(type){
var pool = "";
if (type == "lowerLetter"){
pool = "abcdefghijklmnopqrstuvwxyz0123456789";
}
else if (type == "upperLetter"){
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}
else if (type == "symbol"){
pool = ",.?/\\(^)![]{}*&^%$#'\"";
}
var arr = pool.split('');
return arr[Math.floor(Math.random()*arr.length)];
}
We could have used a single pool string for all types of characters, but this will do for a better effect.
Now lets write the body of the plugin!
$.fn.shuffleLetters = function(prop){
var options = $.extend({
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
},prop)
return this.each(function(){
var el = $(this),
str = "";
if(options.text) {
str = options.text.split('');
}
else {
str = el.text().split('');
}
// The types array holds the type for each character;
// Letters holds the positions of non-space characters;
var types = [],
letters = [];
// Looping through all the chars of the string
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
el.html("");
// Self executing named function expression:
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at this position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
el.text(strCopy.join(""));
setTimeout(function(){
shuffle(start+1);
},1000/options.fps);
})(-options.step);
});
};
The plugin will take either the contents of the DOM element it was called on, or the text property of the object passed as an argument. It then splits the string into characters and determines the type of each one. The shuffle function then uses setTimeout() to call itself and randomize the string, updating the DOM element on each step.
When you head on to the demo you will see that you are able to type your own text and test it out. Here is how I did it:
assets/js/script.js
$(function(){
// container is the DOM element;
// userText is the textbox
var container = $("#container")
userText = $('#userText');
// Shuffle the contents of container
container.shuffleLetters();
// Bind events
userText.click(function () {
userText.val("");
}).bind('keypress',function(e){
if(e.keyCode == 13){
// The return key was pressed
container.shuffleLetters({
"text": userText.val()
});
userText.val("");
}
}).hide();
// Leave a 4 second pause
setTimeout(function(){
// Shuffle the container with custom text
container.shuffleLetters({
"text": "Test it for yourself!"
});
userText.val("type anything and hit return..").fadeIn();
},4000);
});
The fragment above also shows how you can use the plugin and the custom text parameter.
Done
I hope you find this plugin useful and have fun with it. It is released under the MIT license.





35 Comments
woooo veeeery great!
Really great plugin, I will be going to use it…
WOOW!! Awesome!
I will made a Airport Timetable-like style basing on this script to scroll the letters!!
Awesome.
Totally love it! I’m so gonna use this! Thank you very much!
Wow, it’s cool… I was thinking to make it myself, but thanks god, you done it.
Great work… thanks!!
Nice effect
But when we enter some text of our own and hit Return
the shuffling occurs just once
can anyone help ?
Can you give a screenshot?
really cool I was looking for it,
It’s really Super Awesome and it also works in Blogger(Blogspot) blogs!!!!!
WOW! simple and awesome :)
it’s a cool and attractive ☺
thanks^^
Thanks for this, Martin.
It really amazes me how easy it is for you to produce great stuff.
Oh my god !
It’s so amazing !
Like call of duty 4 mission briefing.
I add this to user login effect.
“System activated” )
Great plugin, I really like the idea.
In demo, when I fast press Enter button two times result is random sequence of symbols.
Regards, A_Minko
The second time you hit enter, the plugin is run again, taking the current content of the div (shuffled by the previous call to the plugin) and animating it. It is not much of a problem, as the plugin is meant to animate static text and not to be interactive like in the demo. But if you need to, you can set a flag to prevent animations running in parallel.
Hello Martin,
I must say, nice tutorial indeed. I am following tutorialzine for a long time now.
This one is great. I often use jQuery a lot in websites. I am going to use this piece of fine code snippet to make a drupal module for my site.
Thank you again for this awesome piece of jQuery.
Amazing ! Great plugin, thanks :)
Nice effect !
I wonder if there is a way to integrate this effect on a slideshow, or in combination with slide deck
By the way, I’m amazed by the quantity and the quality of your tuts. And this effect opened great perspectives… Thanks.
Very good plugin!
Just one question: how to detect the end of the animation ?
+ +
The plugin can now take a callback property that is called when the animation is complete.
Can I change this script to loop through certain DOMs within a parent, and shuffle one into the next? So basically one string will shuffle and become the next one, and so on.
The strings would be children of a certain DOM.
Yes this won’t be that difficult. If you have an unordered list (each li being a phrase you would shuffle), you can simply call the plugin for each phrase. You can use the text argument and the newly added callback to trigger the plugin with the next string.
Hey Martin, am trying to get one word shuffle to fade in to another word after the 4seconds (have made the unordered list with each li as a word).
What should I change in script.js to remove the user input and feed the pre-set words from the list?
So they go through the list and stop on the last word.
Any pointers greatly appreciated and will post the finished bit of play when done, thanks for great example!
another great plugin, thanks man
Nice! :D
Well done.
Very Nice jQuery Tutorial!
Just in case, and as nobody appears to be mentioning this..
The plugin writes in all languages your browser support, try Arabic or Russian for example ;)
Looks like seen it before but just decided to use it now. Cool demo!!
Thank you for this magnificent descriptive guide and the provided demo. Will be using this plugin for sure!
Very cool, thanks!
Does not seem to work on IE 8?
Thanks! That one was clean and cool! I really like it.
But it only shuffles latin chars. If you enter text in some other language – you will end up with shuffling symbols whereas there was a letter. But it’s easy to tune with just a couple of extra if statements.
... else if(/[A-Z]/.test(ch)){ types[i] = "upperLetter"; } else if(/[а-я]/.test(ch)){ types[i] = "lowerLetterRus"; } else if(/[А-Я]/.test(ch)){ types[i] = "upperLetterRus"; } ... ... else if (type == "upperLetter"){ pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; } if (type == "lowerLetterRus"){ pool = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя0123456789"; } else if (type == "upperLetterRus"){ pool = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ0123456789"; } ...That’s it for russian letters in case anyone need it.