思路:首先清除blink前面的节点,然后遍历str数组逐个创建元素,如果为\n则创建br元素,反之创建span元素,其中根据当前内容对空格、大于号、小于号进行转义,即&nbsp、&gt、&lt,最后使用定时器每间隔200秒向blink元素之前添加元素。

<body>
   <div class="content">
    <span class="word color23">h</span>
    <span class="word color22">e</span>
    <span class="word color4">l</span>
    <span class="word color24">l</span>
    <span class="word color17">o</span>
    <span class="word color2"> </span>
    <span class="word color9">w</span>
    <span class="word color3">o</span>
    <span class="word color1">r</span>
    <span class="word color23">l</span>
    <span class="word color15">d</span>
    <br>
    <span class="word color15">你</span>
    <span class="word color13">好</span>
    <span class="word color16">世</span>
    <span class="word color19">界</span>
    <span class="blink" id="jsBlink">|</span>
  </div>
  <script type="text/javascript">
  function output(str) 
  {
     let blink=document.getElementById("jsBlink")
     let div=document.querySelector(".content")
     //firstChild找到第一个子节点
     let node = div.firstChild
     //首先清除其前面所有节点
     while(node != blink)
     {
        //nextSibling找到下一个兄弟节点
        let next_node = node.nextSibling
        //removeChild用于父元素移除子节点
        div.removeChild(node)
        node=next_node
     }
     //元素数组
     let text = []
     for(let i=0;i<str.length;i++)
     {
        let curspan
        //换行是br标签
        if(str[i]=="\n")
        {
           curspan = document.createElement("br")
        }
        //其他是span标签
        else 
        {
           //1~24
           let ranv = Math.floor(Math.random()*24)+1
           curspan = document.createElement("span")
           curspan.classList.add("word")
           curspan.classList.add(`color${ranv}`)
           //转义<
           if(str[i]=="<")
              curspan.innerHTML = "<"
           //转义>
           else if(str[i]==">")
              curspan.innerHTML = ">"
           //转义空格
           else if(str[i]==" ")
              curspan.innerHTML = " "
           else
              curspan.innerHTML = str[i]
         }
         text.push(curspan)
     }
     j=0
     //每间隔200毫秒 不能与for一起使用 否则不对
     let id=setInterval(function(){
        if(j<text.length)
        {
           div.insertBefore(text[j],blink)
           j++
        }
        //结束则清空定时器
        else
        {
           clearInterval(id)
        }
     },200)
  }
  output("hello world  <hh>  \n  你好世界")
  </script>
</body>

总结:createElement用于创建元素,p.insertBefore(c1,c2)用于在父元素p中子节点c2前插入c1,firstChild用于获取元素的第一个子节点,nextSibling用于获取元素的下一个兄弟节点,removeChild用于父元素移除子节点,setInterval用于设置定时器,间隔多少时间干什么事情,返回定时器的id,clearInterval用于清除定时器。