简体   繁体   English

突出显示单词的超时功能无法正常工作

[英]Timeout function to highlight words does not work correctly

I am using the setTimeout and clearTimeout functions to highlight words in a textarea element at certain specified intervals. 我正在使用setTimeoutclearTimeout函数以特定的指定间隔突出显示textarea元素中的单词。 The steps I am following are: 我遵循的步骤是:

  1. Get text from textarea element. textarea元素获取文本。
  2. Split into words. 分成单词。
  3. Output each word into a separate textarea element every 5 seconds. 每5秒将每个单词输出到一个单独的textarea元素中。

The code is: 代码是:

<html>
<head>
<script type="text/javascript">

    /* this function does the folloeing:
     * 1. takes all the words in the textarea.
     * 2. Separates them into words.
     * 3. Iterate through the list of words.
     * 4. Search and highlight each word for 1 second.
     */

    var highlightBtn = document.getElementById("start");
    var continueHighlight = false;
    var text;
    var highlighter;
    var words;

    function startHighlight(val) {

        continueHighlight = val;
        console.log("Highlight = " + continueHighlight);

        //1. get words within textarea.
        var textarea = document.getElementById("inputText");
        text = textarea.value;
        console.log("text = " + text);

        //2. split text into words.
        var words = text.split(' ');
        console.log("There are " + words.length + " words in the text.");

        //highlight();
        if(continueHighlight) {
            //3. iterate through list of words.
            var i = 0;
            while(i < words.length) {
                highlighter = setTimeout(searchAndHighlight, 5000, words[i]);
                //console.log("Word highlighting = " + words[i]);
                i = i + 1;
            }
        } else {
            console.log("Stopping highlighting.");
            clearTimeout(highlighter);
        }
    }

    function highlight() {
        if(continueHighlight) {
            //3. iterate through list of words.
            var i = 0;
            while(i < words.length) {
                highlighter = setTimeout(searchAndHighlight, 5000, words[i]);
                //console.log("Word highlighting = " + words[i]);
                i = i + 1;
            }
        } else {
            console.log("Stopping highlighting.");
            clearTimeout(highlighter);
        }
    }

    function searchAndHighlight(word) {
        console.log("Highlighting word = " + word);
        var output = document.getElementById("output");
        output.value = word;
    }

</script>
</head>

    <body>
        <textarea id="inputText"></textarea>
        <br/>
        <button id="start" onclick="startHighlight('true')">Start!</button>
        <br/>
        <button id="stop" onclick="startHighlight('false')">Stop!</button>
        <br/>
        <textarea id="output"></textarea>

    </body>

</html>

I expected every word to be displayed in the second textarea every 5 seconds. 我希望每隔5秒钟在第二个textarea显示每个单词。 This is not happening. 这不会发生。 Instead, I get nothing for 5 seconds and then all words in quick succession. 相反,我没有得到任何东西5秒,然后所有的单词连续快速。 This happens even if I press the stop button. 即使按下停止按钮,也会发生这种情况。 My questions: 我的问题:

Where am I going wrong in using the setTimeout function? 我在使用setTimeout函数时出错了?

This piece of code: 这段代码:

        var i = 0;
        while(i < words.length) {
            highlighter = setTimeout(searchAndHighlight, 5000, words[i]);
            //console.log("Word highlighting = " + words[i]);
            i = i + 1;
        }

is rapidly calling setTimeout() a bunch of times in a row and setting them all for the same time. 正在连续多次快速调用setTimeout()并将它们全部设置为同一时间。 That will match your symptoms of waiting 5 seconds and then running them all at once. 这将符合您等待5秒的症状,然后立即运行它们。

You will either have to set each successive timeout for a longer period of time or change the structure of the code to not start the next timer until the first one fires. 您将要么必须将每个连续超时设置更长的时间,要么将代码的结构更改为在第一个计时器触发之前不启动下一个计时器。


Here's how you could solve it by only setting one setTimeout() at a time. 这是你如何通过一次只设置一个setTimeout()来解决它。 This would also solve the stop button problem: 这也可以解决停止按钮问题:

function highlight() {
    if(continueHighlight) {
        var i = 0;

        function next() {
            if (i < words.length) {
                highlighter = setTimeout(function() {
                    searchAndHighlight(words[i]);
                    i++;
                    next();
                }, 5000);
            }
        }

        next();
    } else {
        console.log("Stopping highlighting.");
        clearTimeout(highlighter);
    }
}

When you want to stop the progressive highlighting, I don't understand why you're taking such a circuitous route. 当你想要停止渐进式突出显示时,我不明白为什么你采取这种迂回路线。 You should just call the clearTimeout(highlighter) . 你应该只调用clearTimeout(highlighter) There's no need to go through multiple functions like you're doing just to do that. 没有必要像你这样做那样经历多个功能。

Or, the solution that sets successively longer timers could work like this: 或者,连续设置更长计时器的解决方案可以这样工作:

        var i = 0;
        while(i < words.length) {
            highlighter = setTimeout(searchAndHighlight, 5000 * (i+1), words[i]);
            //console.log("Word highlighting = " + words[i]);
            i = i + 1;
        }

If you want to use this type of solution, then to fix the stop button problem, you will have to keep all the timer ids in an array and cancel all of them. 如果要使用此类型的解决方案,然后要解决停止按钮问题,则必须将所有计时器ID保留在数组中并取消所有这些。 Personally, I'd probably restructure the code and only have one setTimeout() in flight at a time and when each one fires you kick off the next one. 就个人而言,我可能会对代码进行重组,并且每次只有一个setTimeout()在飞行中,当每个代码触发时,您将启动下一个代码。 Then, you only have one setTimeout() going at once so it's simpler to cancel. 然后,你只有一个setTimeout()一次进行,所以取消更简单。

Here is a solution that fixes the stop button problem. 这是解决停止按钮问题的解决方案。 If you keep track of i, you could also have the highlight function resume where it left off. 如果你跟踪我,你也可以在它停止的地方恢复高亮显示功能。

<html>
<head>
<script type="text/javascript">

/* this function does the folloeing:
 * 1. takes all the words in the textarea.
 * 2. Separates them into words.
 * 3. Iterate through the list of words.
 * 4. Search and highlight each word for 1 second.
 */

var highlightBtn = document.getElementById("start");
var continueHighlight = false;
var text;
var highlighter;
var words;

function startHighlight(val) {

    continueHighlight = val;
    console.log("Highlight = " + continueHighlight);

    //1. get words within textarea.
    var textarea = document.getElementById("inputText");
    text = textarea.value;
    console.log("text = " + text);

    //2. split text into words.
    var words = text.split(' ');
    console.log("There are " + words.length + " words in the text.");

    //highlight();
    //3. iterate through list of words.
    var i = 0;

     highlighter = setTimeout( function( ){
                searchAndHighlight( words, 0 );
            }, 5000);

    function searchAndHighlight(words, i ) {
        if(i >= words.length){
            clearTimeout(highlighter);
        }else{
            console.log("Highlighting word = " + words[i]);
            var output = document.getElementById("output");
            output.value = words[i];
            i++;
             highlighter = setTimeout( function( ){
                    searchAndHighlight( words, i );
                }, 5000);
        }
    }
}

function stopHighlight(){
  console.log("Stopping highlighting.");
  clearTimeout(highlighter);
}


</script>
</head>

    <body>
        <textarea id="inputText"></textarea>
        <br/>
        <button id="start" onclick="startHighlight()">Start!</button>
        <br/>
        <button id="stop" onclick="stopHighlight()">Stop!</button>
        <br/>
        <textarea id="output"></textarea>

    </body>

</html>

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

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