加快设置很多跨度位置

时间:2013-05-29 13:27:31

标签: jquery optimization offset

我使用jQuery跨越段落的每个字符,以便稍后为其设置动画。

// 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');

我有大约800个字符。它变得很慢......我想知道是否有任何方法可以让它更快。

就像现在一样,它为每个范围创建一个样式:

<span style="position: relative; top: 8.763065797205456px; left: 0px;">i</span>

是否可以直接更改位置?

这是完整的代码,请注意我关闭了绘制方法!

如果你打开它,请注意事情进展缓慢。

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

简而言之,这怎么可以加快呢?

http://jsfiddle.net/LwD42/4/

3 个答案:

答案 0 :(得分:3)

$.offset()做了很多你可能不需要的检查。您还应该缓存jQuery对象,而不是不断地重新创建它们。例如:

$(this)替换为var self = $(this),然后拨打self。每次使用$()函数时,jQuery都会创建另一个对象。

您可以执行以下更快的操作:

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

http://jsfiddle.net/LwD42/9/

这是一个比较两者的性能测试:http://jsperf.com/span-position-speed-test/ 这个版本在浏览器中大约快两倍。它仍然相对较慢,但这总是在编辑如此大量的DOM元素时。

答案 1 :(得分:0)

作为@George Reith的补充回答。您可以将字符串操作优化为一个DOM插入:

 // span each character
var text = "", 
    topOffset = 0;
$('#testText p').children().andSelf().contents().each(function(){
    if (this.nodeType == 3) {
        var $this = $(this);
        text += $this.text().replace(/(\w)/g, "<span>$&</span>");
    }
}).replaceWith(text);

答案 2 :(得分:0)

您可以更改framecount以移动超过1

function draw() {
frameCount+=10;
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;
   $(this).offset({ top: offsetTop+addOffset, left: offsetLeft });
});
}      

我使用.animate设置此jsfiddle

的顶部