2015-12-14 151 views
0

我正在使用WordPress插件。其特點之一是使用<span>按類別隱藏和顯示文本片段。延遲使用Javascript

此功能可以正常工作,但我一直希望通過讓文本片段一次顯示一個字母(當然很快),好像它們正在快速輸入一樣,而不是一次全部放大塊。

我知道這裏有動畫,這可能是更好的解決方案,但我一直在努力保持它。但功能並不是真正的圖形或「動畫」導向;我的意圖更多的是使基於文本的功能看起來更漂亮。

我已經獲得了按字符構建每段文本字符的代碼部分,但我試圖在每個字符之間插入一個非常短的(5-10毫秒)延遲,以便實際上可以看到效果。我根本無法使setTimeout函數正常工作;任何人都可以請給我一些建議?

爲了簡單起見,我只是包括這樣做的文本段;讓我知道是否需要更多的上下文。以下是FOR循環,它遍歷一個名爲cols []的數組的每個元素,並按字符顯示數組中的每個元素。此代碼有效,但從未觀察到延遲。

numberofSnippets = the size of the array cols[] 

    for (c = 0; c < numberofSnippets; c++)     
     { 
      h=0; 
     currentshown = '';     
     snippet = cols[c].textContent;   
     sniplength = snippet.length;   

     (function addNextCharacter() 
     { 
      onecharacter = snippet.charAt(h); 
       currentshown = currentshown.concat(onecharacter); 
      cols[c].textContent = currentshown; 
      h=h+1; 
      if (h < sniplength) {window.setTimeout(addNextCharacter, 200); } 

      })();*/ 


      } 

    }  
}   
+0

'setTimeout'接受毫秒作爲第二個參數,5-10ms不可見,您可能想傳入類似'200'的東西,然後從那裏開始。 – adeneo

+0

謝謝 - 剛剛更新了文字以反映這一點。我已經嘗試過數字達到1000,並且不會延遲。 – NFB

+0

下面是上面和上面提供的更新之後的更多信息:當我逐句通過這段代碼時,它第一次到達'if(h NFB

回答

0

你的代碼中有一些古怪的東西阻止了setTimeout的按預期執行,主要原因是由於循環不會等待IIFE完成而導致閉環在循環中重用變量用setTimeout遞歸執行。我通過將這些變量移動到傳遞給addNextCharacter的參數來解決這個問題。

var cols = document.getElementsByClassName('foo'); 
 
var numberofSnippets = cols.length; 
 

 
for (var c = 0; c < numberofSnippets; c++) { 
 
    (function addNextCharacter(h, c, snippet, sniplength, currentshown) { 
 
    var onecharacter = snippet.charAt(h); 
 
    currentshown = currentshown.concat(onecharacter); 
 
    cols[c].textContent = currentshown; 
 
    h = h + 1; 
 
    if (h < sniplength) { 
 
     setTimeout(function() { 
 
     addNextCharacter(h, c, snippet, sniplength, currentshown); 
 
     }, 10); 
 
    } 
 
    })(0, c, cols[c].textContent, cols[c].textContent.length, ''); 
 
}
<div class="foo">Apple</div> 
 
<div class="foo">Banana</div> 
 
<div class="foo">Orange</div> 
 
<p class="foo">There were a few oddities in your code that was preventing the setTimeout from performing as expected, mostly due to the closure reusing variables within the loop due to the fact that the loop isn't going to wait for the IIFE to finish recursively executing with a setTimeout. I solved that by moving those variables to parameters passed to addNextCharacter.</p>

下面是其避免了需要圍繞傳遞變量作爲參數強制性.forEach版本。

var cols = document.getElementsByClassName('foo'); 
var numberofSnippets = cols.length; 

[].forEach.call(cols, function(el) { 
    var snippet = el.textContent; 
    var sniplength = snippet.length; 
    var currentshown = ''; 
    (function addNextCharacter(h) { 
    var onecharacter = snippet.charAt(h); 
    currentshown = currentshown.concat(onecharacter); 
    el.textContent = currentshown; 
    h = h + 1; 
    if (h < sniplength) { 
     setTimeout(function() { 
     addNextCharacter(h); 
     }, 1000); 
    } 
    })(0); 
}); 
+0

哇。謝謝。現在在上下文中嘗試此代碼,並在結果中很快再次發佈。 – NFB

+0

你是什麼意思它跳出循環?它必須在完成延遲迭代之前離開循環。你無法繞過它,如果它不離開循環,瀏覽器將無法逐步呈現文本。 –

+0

好的 - 我看到它在代碼窗口中有效,但是在原始問題中沒有包含另一個複雜因素。在這部分代碼運行之前,有關的類完全隱藏。爲了能夠顯示它們,FOR循環將每個cols [c]值存儲在var snippet中,然後設置col [c] ='',並在運行reveal循環之前將其設置爲顯示:inline。這意味着col [c] .textContent不能直接傳遞給addNextCharacter循環。而當我試圖通過代碼片段傳遞它時,我得到了跳出的相同問題。 – NFB

0

好吧,有一個問題是,你的超時設置爲0,這意味着,有效的下勾「。例如,如果您想延遲5秒,則需要將5000作爲第二參數。

+0

是的,謝謝抱歉 - 我已經嘗試過,但最終因爲另一個原因將其設置爲零。我會更新示例以反映10ms。 – NFB