[英]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.