[英]Javascript Typewriter Effect from element childNodes
我正在嘗試創建一個類型編寫器效果,它將獲取元素的節點,然后以給定的速度順序顯示這些節點的值。 如果節點是文本節點,我希望它進入並順序顯示該文本中的每個字符。
HTML:
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<!-- item will be appened to this layout -->
<div id="log" class="sl__chat__layout">
</div>
<!-- chat item -->
<script type="text/template" id="chatlist_item">
<div data-from="{from}" data-id="{messageId}" id="messageID">
<div id="messageBox">
<span id="message">
{message}
</span>
</div>
</div>
</script>
使用Javascript:
// Please use event listeners to run functions.
document.addEventListener('onLoad', function(obj) {
// obj will be empty for chat widget
// this will fire only once when the widget loads
});
document.addEventListener('onEventReceived', function(obj) {
// obj will contain information about the event
e++
typeEffect(e);
});
var speed = 50;
var e = 1;
function typeEffect(inp) {
var o = inp;
document.getElementById("messageID").id= "messageID"+o;
document.getElementById("message").id= "message"+o;
var text = $("#message"+o).text();
$("#message"+o).text('');
var i = 0;
var timer = setInterval(function() {
if(i < text.length) {
$("#message"+o).append(text.charAt(i));
i++;
}
else{
clearInterval(timer);
};
}, speed);
}
以下是id為“message2”的元素示例。 如您所見,它包含一些文本,然后是包含圖像的跨度,然后是一些文本。
<span id="message2">
Hello
<span class="emote">
<img src="https://static-cdn.jtvnw.net/emoticons/v1/1251411/1.0">
</span>
There
</span>
在我上面發布的代碼中,我能夠創建文本的打字機效果。 但是,使用上面的例子,我無法找到一種方法來鍵入“Hello”然后鍵入帶有圖像的跨度然后“There”。
我試圖得到這樣的節點:
var contents = document.getElementById("message"+o).childNodes;
當我將其記錄到控制台時,我得到:NodeList(3)[text,span.emote,text]
但是從那里我無法訪問nodeValues。 我一直在犯錯誤。 我不確定我做錯了什么。 從那里我也不確定正確的方法來清空“消息”+ o元素,然后用信息重新填充它。
希望這能解釋一切!
通過使用$.text()
,您將獲得Element的textContent
,並且其所有標記內容都已消失(實際上是其所有子項)。
為了保留此內容,您需要存儲DOM節點而不僅僅是textContent
。
從那里開始,你將不得不分離DOM樹並在附加每個Element時移動它,在每個TextNode的textContent
緩慢迭代。
但是,這樣做並不容易。 實際上,我們將在文檔中重新附加DOM節點的事實意味着我們正在行走的分離的DOM樹將被破壞。
為了避免這種情況,我們因此需要創建一個分離的DOM樹的副本,我們將保持完整,所以我們可以繼續走它,就像它是原始的一樣。
並且為了知道在哪里放置元素,我們需要將每個原始節點存儲為克隆的屬性。
為此,我們將創建兩個TreeWalkers ,一個用於原始節點,另一個用於克隆版本。 通過同時行走,我們可以輕松地設置克隆的.original
屬性。
然后,我們必須回到我們的克隆TreeWalker的根,然后再次開始它,這次能夠將正確的節點附加到其原始的parentNode。
async function typeWrite(root, freq) { // grab our element's content const content = [...root.childNodes]; // move it to a documentFragment const originals = document.createDocumentFragment(); originals.append.apply(originals, content); // clone this documentFragment so can keep a clean version of the DOM tree const clones = originals.cloneNode(true); // every clone will have an `original` node // clones documentFragment's one is the root Element, still in doc clones.original = root; // make two TreeWalkers const originals_walker = document.createTreeWalker(originals, NodeFilter.SHOW_ALL, null); const clones_walker = document.createTreeWalker(clones, NodeFilter.SHOW_ALL, null); while(originals_walker.nextNode() && clones_walker.nextNode()) { // link each original node to its clone clones_walker.currentNode.original = originals_walker.currentNode } while(clones_walker.parentNode()) { // go back to root } // walk down only our clones (will stay untouched now) while(clones_walker.nextNode()) { const clone = clones_walker.currentNode; const original = clone.original; // retrieve the original parentNode (which is already in doc) clone.parentNode.original .append(original); // and append the original version of our currentNode if(clone.nodeType === 3) { // TextNode const originalText = original.textContent; // we use a trimmed version to avoid all non visible characters const txt = originalText.trim().replace(/\\n/g, ''); original.textContent = ''; // in doc => empty for now let i = 0; while(i < txt.length) { await wait(freq); // TypeWriting effect... original.textContent += txt[i++]; } // restore original textContent (invisible to user) original.textContent = originalText; } } } typeWrite(message2, 200) .catch(console.error); function wait(time) { return new Promise(res => setTimeout(res, time)); }
<span id="message2"> Hello <span class="emote"> <img src="https://static-cdn.jtvnw.net/emoticons/v1/1251411/1.0"> </span> There </span>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.