2012-05-18 31 views
0

這是我的代碼的簡化,並解釋版本:使用Javascript/jQuery的文字動畫性能緩慢

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


} 

它得到的話從DIV,迅速刪除它們一個接一個,然後用填充它新的文字。

它採用.setInterval()函數,這是應該每隔8ms回調。這在我的i5 CPU上運行得非常好,但是它在i3筆記本電腦上速度非常慢。

你能就如何提高性能一些建議嗎?

+0

你爲什麼一個接一個地挑選它們?這個代碼在全局中做了什麼?我們可以在您的方法中建議替代方案 – Joseph

+0

那麼它有一個說明文字中,一個長款,這是一個設計功能,使從一個描述過渡到另 - 一個字一個字。 – Anonymous

+0

我會選擇一個更快,更少CPU密集的解決方案,只需將其應用於整個句子。您將瀏覽器推向了極限,如果用戶的體驗變慢,用戶不會關心您的酷炫功能。另外,你選擇變量名稱會讓我想逃跑尖叫。考慮使用一些對名稱更有意義的東西。 :) – jmort253

回答

-1

這是做到了完美的功能,整個想法是把它包在跨,然後爲每個我們將跨越更改可視性,並在達到反向階段時,用跨度中包含的不同文本進行替換。

我不保證你永遠都不懂,但你一定能夠得到一個想法我如何解決它。請注意,基本上主要輸入是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) 
     ); 


} 
+0

LOHL ,爲什麼減去投票? – Anonymous

+0

無論如何,我不在乎,因爲我找到了我的答案,我只是分享。 – Anonymous

1

你可以

  • 嘗試使容器有一套寬度和高度,以避免文件的重繪和迴流。操作後調整元素的大小。
  • 那麼你就可以避免陣列操作(分割和結合​​),只是直接使用字符串操作。
  • 避免通過在循環操作之外存儲引用來重複調用相同元素
  • 使用text()而不是html(),那樣,DOM僅創建文本節點。

Here's a demo,它運行速度非常快對我的信賴奔騰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'); 
    }); 
});​ 
1

這將做的工作,你可能要改變的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>