I span every character of a paragraph with jQuery to animate it later.
// span each character
$('#testText p').children().andSelf().contents().each(function(){
if (this.nodeType == 3) {
var $this = $(this);
$this.replaceWith($this.text().replace(/(\w)/g, "<span>$&</span>"));
}
});
// store each span
$spanCharacters = $('#testText p span');
I have around 800 characters. It goes very slow... I wondered if there is any way to get it faster.
Like now it creates a style for every span:
<span style="position: relative; top: 8.763065797205456px; left: 0px;">i</span>
Is it possible to change the position directly?
Here is the complete code, notice i have the draw method off!
If you turn it on, be aware things go slowly.
var TWO_PI = 6.2831855;
var frameCount = 0;
var $spanCharacters = new Array();
$(document).ready(function() {
// span each character
$('#testText p').children().andSelf().contents().each(function(){
if (this.nodeType == 3) {
var $this = $(this);
$this.replaceWith($this.text().replace(/(\w)/g, "<span>$&</span>"));
}
});
// store each span
$spanCharacters = $('#testText p span');
//var handle = setInterval(draw, 80);
draw();
});
function draw() {
frameCount++;
var width = 500;
$spanCharacters.each(function() {
var offsetLeft = $(this).offset().left;
var offsetTop = $(this).offset().top;
var posLeft = $(this).position().left;
var a = map(posLeft+frameCount, 0, width/5, 0, TWO_PI);
var c = Math.cos(a);
var addOffset = c*10;
//console.log(addOffset);
$(this).offset({ top: offsetTop+addOffset, left: offsetLeft });
});
}
function map(value, istart, istop, ostart, ostop) {
return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}
So in short, how can this be sped up?
$.offset()
does a lot of checks you probably don't need. You should also cache your jQuery objects instead of constantly recreating them. For example:
Replace $(this)
with var self = $(this)
and just make calls to self
. Everytime you use the $()
function jQuery creates another object.
You could do the following which would be much faster:
$spanCharacters.each(function() {
var a = map(this.offsetLeft + frameCount, 0, width/5, 0, TWO_PI);
var c = Math.cos(a);
var addOffset = c * 10;
this.style.position = "relative";
this.style.top = addOffset + "px";
});
Here is a performance test comparing the two: http://jsperf.com/span-position-speed-test/ This version is roughly twice as fast in my browser. It is still relatively slow but this always will be as you are editing such a large number of DOM elements.