Javascript/jQuery文本动画性能低下

Javascript/jQuery文本动画性能低下,javascript,jquery,html,css,animation,Javascript,Jquery,Html,Css,Animation,这是我的代码的简化和解释版本: var ptext=parr.find('div.ptext'); //Text Container var pt=ptext.html(); //Text Container's string var pdv=[pt.split(" ")]; //Text Container's array of words pdv.push(pdv[0].length);

这是我的代码的简化和解释版本:

    var ptext=parr.find('div.ptext');   //Text Container

    var pt=ptext.html();                //Text Container's string
    var pdv=[pt.split(" ")];            //Text Container's array of words
        pdv.push(pdv[0].length);    //Write also the number of words

    var ht=hp.html();               //Text Container's new string
    var hdv=[ht.split(" ")];            //Text Container's new array of words
    hdv.push(hdv[0].length);            //New number of words

    var kakaka=0;                       //If they begin with the same,
    for (var j=0;j<hdv[0].length;j++){  //Animate only from the position
        if (hdv[0][j]==pdv[0][j])   //where they differ
            kakaka+=2;
    }

    window.clearTimeout(ptext.data('curt'));  //Clear current animation's interval
    ptext.data('count',kakaka);      //Set starting position    
    ptext.data('curt',                      //Set interval's var into object
        window.setInterval((function (item,pdv,hdv,text_callback) {
                return function() {       //item = text obj, text_callback= callback function
                        var i=item.data('count');
                            i=(i==undefined)?0:1+i;
                        item.data('count',i);     //increase counter
                                //first phase - remove old text
                        if (i<=pdv[1])       // go on
                        {
                            item.html((pdv[0].slice(0,pdv[1]-i)).join(' '));
                        }       //if reached the position, add new text
                        else if (i<=pdv[1]+hdv[1])
                        {
                            item.html((hdv[0].slice(0,i-pdv[1])).join(' '));
                        }        //if finish clear timeout and call callback
                        else {
                            item.data('count',0);
                            window.clearTimeout(item.data('curt'));
                            text_callback();
                        }
                }
            })(ptext,pdv,hdv,text_callback),8)   //8 = supposed interval
       );


}
var ptext=parr.find('div.ptext')//文本容器
var pt=ptext.html()//文本容器的字符串
var pdv=[pt.split(“”]//文本容器的单词数组
pdv.push(pdv[0].长度)//同时写下字数
var ht=hp.html()//文本容器的新字符串
var hdv=[ht.分割(“”]//文本容器的新单词数组
hdv.push(hdv[0].长度)//新词数
var kakaka=0//如果它们以相同的开头,
对于(var j=0;j你可以

  • 尝试使容器具有设置的宽度和高度,以避免重新绘制和回流文档。操作后调整元素的大小
  • 然后可以避免数组操作(拆分和联接),而直接使用字符串操作
  • 通过在循环操作外部存储引用,避免重复调用同一元素
  • 使用
    text()
    而不是
    html()
    ,这样,DOM只创建文本节点
它在我信任的奔腾4上运行得非常快

$(function() {

    function clearText(selector, callback) {
        //cache repeatedly used items
        var element = $(selector),
            elementText = element.text() + ' '; 

        //set element dimensions to fixed
        element.width(element.width());    
        element.height(element.height());

        (function erase() {
            if (elementText) {
                //use slice operations instead
                elementText = elementText.slice(elementText.indexOf(' ')+1);
                //use "text()"
                element.text(elementText);
                //loop
                setTimeout(function() {
                    erase();
                }, 8);
            } else {
                //set the dimensions back to auto
                element.width('auto').height('auto');   
                //execute callback returning the jQuery element
                callback.apply(element); 
            }
        }())

    }

    clearText('#foo', function() {
        //"this" is jQuery object "#foo"
        this.text('hello world');
    });
});​

这就可以了,你可能想改变setTimeout调用之间的延迟。它可以变得更加独立,但我现在没有动力:

<script type="text/javascript">

// Some support functions
(function(g) {
  var el = document.createElement('div');
  if (typeof el.textContent == 'string') {
    g.getText = function(el) {return el.textContent};
    g.setText = function(el, text) {el.textContent = text};
  }

  if (typeof el.innerText == 'string') {
    g.getText = function(el) {return el.innerText};
    g.setText = function(el, text) {el.innerText = text};
  }
}(this));

function annoyUser(el, text) {
  var re = /\s+/g;
  var oText = getText(el).split(re);

  if (oText.length == 1) {
    setText(el, text);

  } else {
    oText.pop();
    setText(el, oText.join(' '));
    setTimeout(function(){annoyUser(el, text)}, 100);
  }
}

window.onload = function() {
  setTimeout(function() {
    annoyUser(document.getElementById('d0'), 'hello world')
  }, 1000);
}

</script>

<div id="d0">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas
 metus sapien, lobortis non dictum et, mollis vitae lorem. Nulla facilisi. Morbi eget
 ante diam.</div>

//一些支持功能
(职能(g){
var el=document.createElement('div');
if(type of el.textContent=='string'){
g、 getText=函数(el){return el.textContent};
g、 setText=函数(el,text){el.textContent=text};
}
if(type of el.innerText=='string'){
g、 getText=函数(el){return el.innerText};
g、 setText=函数(el,text){el.innerText=text};
}
}(本);;
功能用户(el,文本){
var re=/\s+/g;
var-oText=getText(el).split(re);
如果(oText.length==1){
setText(el,text);
}否则{
oText.pop();
setText(el,oText.join(“”));
setTimeout(函数(){user(el,text)},100);
}
}
window.onload=函数(){
setTimeout(函数(){
用户(document.getElementById('d0'),'hello world')
}, 1000);
}
洛雷姆·伊普苏姆·多洛·西特,一位杰出的献身者
智者之美,无言者之美,生命之美,无言者之美,无言者之美
前直径。

这是一个完美的函数,其整体思想是将其包装成跨距,然后对于每个跨距,我们将更改可见性,当它进入相反阶段时,替换为包装成跨距的不同文本

我不能保证你会理解任何东西,但你肯定会知道我是如何解决它的。注意,基本上主要的输入是pdv和hdv-是输入文本和输出文本的单词数组

function letsdance(obj,op,type,text_callback){  //animate text

    if (text_callback==undefined) var text_callback=function(){};

    var parr=obj.parents('.pconter');
    var ptext=parr.find('div.ptext');


    var pt=ptext.html();

    var ppp=ptext.children();
    var pdv=[[]];
    for (var i=0;i<ppp.length;i++)
        pdv[0].push(    ppp[i].outerHTML    );



    if (ppp.length==0){
    var pdv=[pt.split(" ")];
        for (var i=0;i<pdv[0].length;i++)
            pdv[0][i]='<span>'+pdv[0][i]+'</span>';
        ptext.html(pdv[0].join(' '));
    }

    pdv.push(pdv[0].length-1);

    if (op){
        if (type===1)
            {
                var ht=obj.html();
            }
        else if (type==2)
            {
                var ht=ptext.data('orig');  
            }
        else {
        var ide=(obj.attr('id').match(/_[\da-zA-Z]*_[\da-zA-Z]*$/))[0];
        var hp=parr.find('div.hptext[id$="'+ide+'"]');
        var ht=hp.html();   
        }
        var hdv=[ht.split(" ")];
            hdv.push(hdv[0].length-1);  
    } else {    
        var current_selection=parseInt(ptext.data('current_section'));
        if (current_selection>0){
            var pto=ptext.siblings('.subptext[id$="NN'+current_selection+'"]').html();
            }
        else 
            var pto=ptext.data('orig');

        var hdv=[pto.split(" ")];
            hdv.push(hdv[0].length-1);  
    }

    var kakaka=0;
    var kaka=false;
    for (var i=0;i<=hdv[1];i++){
        if (pdv[0][i]!=undefined&&!kaka&&hdv[0][i]==pdv[0][i].replace(/(<([^>]+)>)/ig,"")&&!/invis/.test(pdv[0][i])){
                        kakaka+=1;  
        }
        else {
            kaka=true;
            hdv[0][i]='<span class="invis">'+hdv[0][i]+'</span>'; 
        }
    }
    var invi_count=pdv[1];
    for (invi_count;invi_count>=0;invi_count--)
        if (!/invis/.test(pdv[0][invi_count])) break;

    window.clearInterval(ptext.data('curt'));
    ptext.data('count',invi_count).data('index',kakaka).data('phase',0)//data('skip',0);            
    ptext.data('curt',
        window.setInterval((function (item,pdv,hdv,text_callback) {
                return function() {
                    var i=item.data('count');      
                    var phase=item.data('phase');      
                    var index=item.data('index');    
                    switch (phase)
                    {
                        case 0:
                                item.children(':eq('+i+')').addClass('invis');
                                if (i>index)    
                                    item.data('count',i-1);
                                else
                                    item.data('count',index).data('phase',1)
                                    .html((pdv[0].slice(0,index)).join(' ')).append(' '+hdv[0].slice(index,hdv[1]).join(' '));
                        break;  
                        case 1:
                                item.children(':eq('+i+')').removeClass('invis');
                                if (i<hdv[1])
                                    item.data('count',i+1);
                                else{
                                    //item.data('count',0).data('phase',0);
                                    window.clearInterval(item.data('curt'));
                                    text_callback();
                                }
                        break;      
                    }
                }
            })(ptext,pdv,hdv,text_callback),4)
       );


}
函数letsdance(obj,op,type,text\u回调){//设置文本动画
if(text_callback==undefined)var text_callback=function(){};
var parr=对象父对象('.pconter');
var ptext=parr.find('div.ptext');
var pt=ptext.html();
var ppp=ptext.children();
var-pdv=[[]];
对于(var i=0;i0){
var pto=ptext.sibbines('.subtext[id$=“NN'+当前选择+''“]')).html();
}
其他的
var pto=ptext.data(“原始”);
var hdv=[pto.拆分(“”];
hdv.push(hdv[0].length-1);
}
var kakaka=0;
var kaka=假;
对于(var i=0;i)/ig,“”&/invis/.test(pdv[0][i])){
kakaka+=1;
}
否则{
卡卡=真;
hdv[0][i]=''+hdv[0][i]+'';
}
}
var invi_count=pdv[1];
对于(因维计数;因维计数>=0;因维计数--)
如果(!/invis/.test(pdv[0][invi_count])中断;
clearInterval(ptext.data('curt'));
ptext.data('count',invi_count).data('index',kakaka).data('phase',0)//data('skip',0);
ptext.data('curt',
setInterval((函数(项、pdv、hdv、text_回调){
返回函数(){
var i=项目数据(“计数”);
var阶段=项目数据(“阶段”);
风险值指数=项目数据(“指数”);
开关(相位)
{
案例0:
item.children(':eq('+i+')).addClass('invi');
如果(i>索引)
项目数据(“计数”,i-1);
其他的
项目数据('计数',索引).数据('阶段',1)
.html((pdv[0]。切片(0,索引)).join(“”)).append(“”+hdv[0]。切片(索引,hdv[1]).join(“”));
打破
案例1:
item.children(':eq('+i+')).removeClass('invi');

如果(我为什么你要一个接一个地把它们挑出来?这段代码在整体上有什么作用?我们可以在你的方法中提出备选方案。它有一个描述文本,一段很长,是一个设计特性,可以逐字从一个描述转换到另一个描述。我会选择一个更快、CPU密集度更低的解决方案,包括juSt将它应用到整个句子中。你把浏览器推到了极限,如果用户让他们的体验慢了,你就不会在乎你的酷功能。而且,你选择的变量名让我想逃走尖叫。考虑使用一些对名字更有意义的东西。8毫秒的间隔是每秒125帧。这有点要求太高了。不是为了这么简单的东西,而是在一个好的浏览器中,但是人们不希望看到的东西的目的是什么?你可以在更长的间隔内做更多的工作,具有相同的效果。无论如何,我不在乎,因为我找到了我的答案,我只是在分享。