【问题标题】:Javascript typing effectJavascript打字效果
【发布时间】:2013-11-11 17:32:45
【问题描述】:

该问题与last time 的问题相同。我的网站运行在一个静态域上,所以我希望能够在每个网站上使用此脚本,而无需制作重复副本。

它起到打字文本效果的作用,我希望能够定义它从网页本身而不是脚本打印出来的文本。

Javascript

var index = 0;
var text = 'Text';

function type()
{
    document.getElementById('screen').innerHTML += text.charAt(index);
    index += 1;
    var t = setTimeout('type()',100);
}

我尝试过修改代码并使用与我上一篇文章相同的方法,但我似乎无法让它工作。

【问题讨论】:

  • 不是解决方案,但是... 不要将字符串传递给setTimeout。那使用eval,这很糟糕。你应该传递函数:var t = setTimeout(type, 100);
  • @RocketHazmat 哎呀-谢谢!
  • @JarrodRoberson 这不是我之前帖子的重复。它围绕同一个问题展开,另一篇帖子上发布的答案并没有解决这个问题。
  • 检查this one
  • 同意你的观点@JakeGriffin 我对你的问题投了赞成票,因为你提到的那个人(JarrodRoberson)对你的问题投了赞成票。

标签: javascript


【解决方案1】:

好的,我不喜欢上面的任何代码。一旦到达输入文本的末尾,您的原始代码也不会停止运行,我认为其他任何建议的解决方案也不会停止。

这是一个用纯 JS 重写的函数:

function type(i, t, ie, oe) {
    input = document.getElementById(ie).innerHTML;
    document.getElementById(oe).innerHTML += input.charAt(i);
    setTimeout(function(){
        ((i < input.length - 1) ? type(i+1, t, ie, oe) : false);
    }, t);
}

你可以这样称呼:

type(0, 100, "text", "screen");

参数为:beginning indexspeedinput elementoutput element

您的 HTML 将如下所示:

<div id="screen"></div>
<div id="text" style="display:none">Hello Bobby</div>

您可以将 div 重命名为您喜欢的任何名称,只要您相应地更新参数即可。我敢肯定还有一种更简单的方法来编写它,但我最喜欢这种方法。


演示

function type(i, t, ie, oe) {
    input = document.getElementById(ie).innerHTML;
    document.getElementById(oe).innerHTML += input.charAt(i);
    setTimeout(function(){
        ((i < input.length - 1) ? type(i+1, t, ie, oe) : false);
    }, t);
}

type(0, 100, "text", "screen");
<div id="screen"></div>
<div id="text" style="display:none">Hello Bobby</div>

【讨论】:

  • 这在 jsfiddle 上运行良好,但在我实际将其上传到服务器时却不行。我将 Javascript 添加到 js 文件并将其放在我的静态域中,但它不起作用。
【解决方案2】:

问得好,LMGTFY 过去经常让我傻笑。我认为您可能会发现以下内容很容易随处可见。它只是添加到目标容器的几个属性,以及启动打字机的调用。

在这里,我同时运行其中的 4 个,只是为了好玩。在此示例中,可能值得将 forEachNode 丢弃,而不是使用几行注释。如果 getElementsByClassName 的结果是一个真正的数组,您可以只调用数组具有的 .forEach 方法。不幸的是,一个 nodeList 是相似的但不一样 - 因此需要这样的功能。我在意识到没有它可能会更清楚之前使用它。无论如何,这是我发现很多次方便的功能。我会把它留在那里,以感谢您考虑这么有趣的问题。

function forEachNode(nodeList, func) {
  var i, n = nodeList.length;
  for (i = 0; i < n; i++) {
    func(nodeList[i], i, nodeList);
  }
}

window.addEventListener('load', mInit, false);

function typeWriter(el) {
  var myDelay = el.getAttribute('keyDelay');

  if (el.getAttribute('curIndex') == undefined)
    el.setAttribute('curIndex', 0);

  var curIndex = el.getAttribute('curIndex');
  var curStr = el.getAttribute('typewriterdata');
  el.innerHTML += curStr.charAt(curIndex);
  curIndex++;
  el.setAttribute('curIndex', curIndex);

  if (curIndex < curStr.length)
    setTimeout(callback, myDelay);
  else {
    if (el.getAttribute('nextline') != undefined) {
      var nextTgt = el.getAttribute('nextline');
      typeWriter(document.getElementById(nextTgt));
    }
  }

  function callback() {
    typeWriter(el);
  }
}

function mInit() {
  typeWriter(document.getElementById('line1'));

  var i, n, elementList;
  elementList = document.getElementsByClassName('autoType');
  forEachNode(elementList, typeWriter);
  //	n = elementList.length;
  //	for (i=0; i<n; i++)
  //		typeWriter( elementList[i] );
}
.multi {
  border: solid 2px #333333;
  width: 400px;
}
<body>
  <div class='autoType' typewriterdata='Enter this string letter by letter' keydelay='300'></div>
  <div class='autoType' typewriterdata='Enter this string letter by letter' keydelay='200'></div>
  <div class='autoType' typewriterdata='This is short but slooooow' keydelay='1000'></div>
  <div class='autoType' typewriterdata='The rain falls mainly on the plain in Spain' keydelay='100'></div>

  <div class='multi'>
    <div id='line1' typewriterdata='This is line 1' keydelay='300' nextline='line2'></div>
    <div id='line2' typewriterdata='This is line 2' keydelay='300' nextline='line3'></div>
    <div id='line3' typewriterdata='This is line 3' keydelay='300' nextline='line4'></div>
    <div id='line4' typewriterdata='This is line 4' keydelay='300'></div>
  </div>
</body>

【讨论】:

  • 这实际上回答了我的问题和更多!我试图找出一种方法来拥有多条线路!不过,快速的问题是,您将如何做到第二行在第一行完成之前不会完成?
  • 哈哈,有趣的是你应该问那个 - (我猜你打算在第一行完成后有第二行 start,对不起,如果我错了)如果不满足curIndex &lt; curStr.length 条件,我几乎添加了调用用户指定函数的能力。如果你这样做了,你可以在第一个打字机完成时调用的函数中启动第二台打字机。
  • @JakeGriffin - 请查看我更新的解决方案。如果你愿意,你可以从一行链接到下一行,或者像我最初那样使用它。我很高兴你问! (回调会很讨厌,可能会让我们求助于 eval 或一些相当丑陋和令人费解的东西 - 因此能够从一行链接到下一行。)
  • 现在首选 data-* attributesdata-typewriter-datadata-key-delaytypewriterdatakeydelay 等自定义属性。可以通过el.dataset.typewriterDatael.dataset.keyDelay 访问它们。
【解决方案3】:

您可以将网页中的文本嵌入到隐藏元素中,如下所示:

HTML

<span id="hiddenText" style="display: none">Text you want to type out.</span>

然后你可以像这样从网页本身获取文本:

Javascript

var text = document.getElementById('hiddenText').innerHTML;

这是您可以看到的 jsfiddle:http://jsfiddle.net/FMq6d/。 这对您的代码所做的更改最少。

【讨论】:

  • 对不起,我替换了“var text = 'Text';”用你的建议?我编辑了我的代码,但它似乎不起作用。
  • 需要在 HTML 中的 JS 代码之前声明 span;或者你应该把你的 JS 代码放在一个 document.ready() 包装器中。让我为你创建一个 JSfiddle。
【解决方案4】:

2 年后:

看看这个很棒的Typing & erasing effect plus a blinking cursor - CodePen

简而言之

var index = 0;
var text = "The Typing Effect - In a Nutshell";

function type(){
  var screenEl = $('#screen');
  screenEl.html(text.substr(0, index++));

  if (index < text.length) {
    // Feel free to type
    setTimeout('type()', 50);
  } else {
    // Reset and restart.
    index = 0;
    text = '';
  }
};

type();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p id="screen"></p>

【讨论】:

    【解决方案5】:

    如果你想定义它打印出来的文本,如果我正确理解你的问题,你应该通过一个参数传递文本。

    试着搞砸这个:

    var type = function( elem , text , index )
    {
        var index = index||0;
        elem.innerHTML += text.charAt(index);
        index++;
    
        var t = setTimeout(function(){
            type( elem , text , index );
        },100);
    }
    type( document.getElementById('screen') , 'How\'re You?' );
    &lt;p id="screen"&gt;Hello, &lt;/p&gt;

    【讨论】:

      【解决方案6】:

      这是一种使用承诺在按键之间休眠的方法。

      这里有一个link 用于 Github 上的 repo,但代码基本上是这样的:

      class Typer {
      
          constructor(typingSpeed, content, output) {
      
              this.typingSpeed = typingSpeed;
              // Parses a NodeList to a series of chained promises
              this.parseHtml(Array.from(content), output);
          };
      
          makePromise(node, output) {
      
              if (node.nodeType == 1) // element 
              {
                  // When a new html tag is detected, append it to the document
                  return new Promise((resolve) => {
                      var tag = $(node.outerHTML.replace(node.innerHTML, ""));
                      tag.appendTo(output);
                      resolve(tag);
                  });
      
              } else if (node.nodeType == 3) // text
              {
                  // When text is detected, create a promise that appends a character
                  // and sleeps for a while before adding the next one, and so on...
                  return this.type(node, output, 0);
              } else {
                  console.warn("Unknown node type");
              }
          }
      
          parseHtml(nodes, output) {
              return nodes.reduce((previous, current) => previous
                  .then(() => this.makePromise(current, output)
                      .then((output) => this.parseHtml(Array.from(current.childNodes), output))), Promise.resolve());
          }
      
          type(node, output, textPosition) {
              var textIncrement = textPosition + 1;
      
              var substring = node.data.substring(textPosition, textIncrement);
      
              if (substring !== "") {
                  return new Promise(resolve => setTimeout(resolve, this.typingSpeed))
                      .then(() => output.append(substring))
                      .then(() => this.type(node, output, textIncrement));
              }
      
              return Promise.resolve(output);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-01-30
        • 2020-04-02
        • 1970-01-01
        • 1970-01-01
        • 2022-12-03
        • 1970-01-01
        • 2018-03-14
        • 2013-12-16
        • 1970-01-01
        相关资源
        最近更新 更多