简体   繁体   English

Javascript 打字效果

[英]Javascript typing effect

The issue arises from the same issue as last time .问题与上次相同。 My websites run off a static domain, so I want to be able to use this script on each site without making duplicate copies.我的网站在 static 域上运行,因此我希望能够在每个站点上使用此脚本而无需制作重复副本。

It functions as a typing text effect, I want to be able to define the text it prints out from the webpage itself and not the script.它起到打字文本效果的作用,我希望能够定义它从网页本身而不是脚本打印出来的文本。

Javascript Javascript

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

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

I've tried fiddling with the code and using them same method as my previous post, but I can't seem to get it to work.我试过摆弄代码并使用与我上一篇文章相同的方法,但我似乎无法让它工作。

Okay, I don't like any of the above code. 好的,我不喜欢上面的任何代码。 Your original code also doesn't stop running once it reaches the end of the input text, and I don't believe any of the other suggested solutions stop either. 一旦原始代码到达输入文本的末尾,它也不会停止运行,我也不相信任何其他建议的解决方案也会停止。

Here's a rewritten function in pure JS: 这是纯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);
}

Which you can call like so: 您可以这样打电话:

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

The parameters are: beginning index , speed , input element , output element 参数是: beginning indexspeedinput elementoutput element

Your HTML will look something like this: 你的HTML看起来像这样:

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

You can rename the divs to whatever you like, as long as you update the parameters accordingly. 您可以将div重命名为您喜欢的任何内容,只要您相应地更新参数即可。 I'm sure there's an easier way to write this as well, but I like this method the most. 我确信有一种更简单的方式来写这个,但我最喜欢这种方法。


Demo 演示

 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> 

Nice question, LMGTFY has often given me a giggle in the past. 不错的问题,LMGTFY过去常常让我傻笑。 I think you may find the following to be pretty easy to throw around anywhere. 我想你可能会发现以下内容非常容易随处扔掉。 It's just a few attributes added to your target container, along with a call to get the typewriter started. 它只是添加到目标容器的一些属性,以及启动打字机的调用。

Here, I run 4 of them simultaneously just for kicks. 在这里,我同时运行其中的4个只是为了踢。 It's probably worth junking forEachNode in this example, instead using the few commented lines. 在这个例子中,使用少数注释行可能值得使用theEachNode。 If the result of getElementsByClassName was a true array, you could just call the .forEach method that arrays have. 如果getElementsByClassName的结果是一个真正的数组,你可以只调用数组所具有的.forEach方法。 Unfortunately, a nodeList is similar but not the same - hence the need for such a function. 不幸的是,nodeList类似但不相同 - 因此需要这样的功能。 I used it before realizing it probably clearer to do without it. 我在使用它之前就已经意识到它没有它可能更清楚。 In any case, it's a function I've found handy many times. 无论如何,这是我多次找到的功能。 I'll leave that in there as a thanks for such a fun question to consider. 我会留在那里,感谢您考虑这样一个有趣的问题。

 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> 

You can embed the text in the webpage itself in a hidden element like this: 您可以将文本嵌入网页本身的隐藏元素中,如下所示:

HTML HTML

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

and then you can get the text from the webpage itself like this: 然后你可以像这样从网页本身获取文本:

Javascript 使用Javascript

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

Here is the jsfiddle you can see: http://jsfiddle.net/FMq6d/ . 这是你可以看到的jsfiddle: http//jsfiddle.net/FMq6d/ This makes minimal changes to your code. 这会对您的代码进行最少的更改。

If you want to define what text it prints out, you should pass the text through an argument, if I understand your question correctly. 如果你想定义它打印出来的文本,你应该通过参数传递文本,如果我正确理解你的问题。

Try and mess with this: 试试这个:

 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?' ); 
 <p id="screen">Hello, </p> 

2 Years Later: 2年后:

Check out this awesome Typing & erasing effect plus a blinking cursor - CodePen 看看这个令人敬畏的打字和擦除效果加上一个闪烁的光标 - CodePen

In a Nutshell : 在果壳中

 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> 

Here is an approach using promises for sleeping between key presses. 这是一种使用承诺在按键之间休眠的方法。

Here is a link for the repo at Github, but the code is basically this: 这是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);
    }
}

 let typeSpeed = 300; let deleteSpeed = 200; let wordDelay = 1000; // utility function that returns a promise that resolves after t milliseconds const delay = (t) => { return new Promise(resolve => { setTimeout(resolve, t); }); } //Change Current Job const changeCurrentJob = async (wordsJson) => { //Get Current Job let currentJob = document.getElementById('wrap'); for (let wordFromJson of wordsJson) { //Deleting //Previous word letters count let prevLetters = currentJob.innerHTML.split(''); //Loop letters with for of to remove them for(let letterFromWordPrev of currentJob.innerHTML){ //Remove Last letter prevLetters.pop(); //Join Letters Array currentJob.innerHTML = prevLetters.join(''); await delay(deleteSpeed); } //Typing for(let letterFromWord of wordFromJson){ currentJob.innerHTML = currentJob.innerHTML+letterFromWord; //Type Speed await delay(typeSpeed); } //After finishing word Wait await delay(wordDelay); } //ReDO Typing - Declare Variables then Redo - let words = document.getElementsByClassName('typewrite'); let wordsData = words[0]; let wordsJson2 = JSON.parse(wordsData.getAttribute('data-type')); changeCurrentJob(wordsJson2); } // On window load Loop data-type And convert from json to txt and type window.onload = function() { let words = document.getElementsByClassName('typewrite'); let wordsData = words[0]; let wordsJson = JSON.parse(wordsData.getAttribute('data-type')); setTimeout(changeCurrentJob,wordDelay,wordsJson); };
 <div class="typewrite" data-type='[ "Full Stack", "PHP", "JS" ]'> <div class="styledWarp" id="wrap"></div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM