Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeating JS function

I'm trying to have this function repeat at the end of it's cycle. I tried assigning the function to a variable and calling the variable in the callback, but that failed. I tried wrapping this function in a setInterval function, still couldn't get it to work.

How do I get this function to run an infinite loop and repeat itself?

$("span.text-change").typed({
     strings: ["First sentence.", "Second sentence."],
     typeSpeed: 30, // typing speed
     backDelay: 500, // pause before backspacing
     callback: function () {
         // do stuff
     }
 });

This is the plugin: Typed JS

jsFiddle here

like image 837
Mike Barwick Avatar asked Sep 28 '13 20:09

Mike Barwick


People also ask

How do you repeat a function in JavaScript?

repeat() is an inbuilt function in JavaScript which is used to build a new string containing a specified number of copies of the string on which this function has been called. Syntax: string. repeat(count);

How do you repeat a loop in JavaScript?

A for loop repeats until a specified condition evaluates to false. The JavaScript for loop is similar to the Java and C for loop. When a for loop executes, the following occurs: The initializing expression initialExpression , if any, is executed.

How do you keep a function from repeating in JavaScript?

One of the most common ways to create a loop is by using the for statement to create a for loop. A for loop allows us to repeatedly run some code until an expression we specify returns false.

What is function repeat?

The REPEAT function returns a character string that is composed of the first argument repeated the number of times that are specified by the second argument.


2 Answers

Typed.js author here. I think it's friggin awesome people like my code enough to dig through it and make more features work. I definitely plan to make looping a default function you can set, but for now here's a fix.

http://jsfiddle.net/LSsZr/8/

Main Changes

self.stopArray = self.strings.length;
// instead of self.stopArray = self.strings.length-1;

This makes the stopArray variable allow for it to continue backspacing once the last string is typed. Otherwise, it'll stop once the last one is printed.


// if (self.arrayPos == self.stopArray && curStrPos == curString.length){
// animation that occurs on the last typed string
// place any finishing code here
//  self.options.callback();
//    clearTimeout();
// }

The above has been removed. It checked for the last string being typed, and fired off a function when the condition was met. For a loop we don't want that.


else{
   self.arrayPos = 0;
   self.typewrite(self.string, self.strPos);
}

The above has been added as an else to the following if statement...

if (self.arrayPos < self.strings.length){

So if the array position is less than the amount of strings in the array, type them. Else, reset the position to 0, and run the original function again.

Go ahead and use the code in the jsfiddle as your typed.js file, and then run it normally on the page you want. There's no longer a callback() though!

Let me know your thoughts / questions!

EDIT Looks like someone here added a loop to the plugin, but it only loops the last sentence over and over :p

You've got to reset the string in the array being sent to the typewrite function. That isn't happening in the other solution.

like image 129
mattboldt Avatar answered Sep 20 '22 19:09

mattboldt


Putting your code in an interval is a good idea. However you have to check if the code execution is completed before calling it again. You could do this with a boolean variable used as flag.

var timerId = setInterval(function() {
    flag=true;
 if( flag){
     flag=false;
    $("div").typed({
     strings: ["First sentence.", "Second sentence."],
     typeSpeed: 30, // typing speed
     backDelay: 500, // pause before backspacing
     callback: function () {
         flag=true;
         //destroy typed plugin here. See in the api if 
         //there is a method for doing that.

     }
 });

 }

}, 1000);

when you wan't to stop the loop you could simply destroy the timer

clearInterval(timerId);

edit: I've added an option to the plugin

$("#typed").typed({
    strings: ["Typed.js is a jQuery plugin.", "It types out sentences."],
    typeSpeed: 30,
    backDelay: 500,
    loop:true,
    callback: function(){ alert('end'); }
});

edited plugin file

!function($){

    "use strict";

    var Typed = function(el, options){

        // for variable scope's sake
        self = this;

        // chosen element to manipulate text
        self.el = $(el);
        // options
        self.options = $.extend({}, $.fn.typed.defaults, options);

        // text content of element
        self.text = self.el.text();

        // typing speed
        self.typeSpeed = self.options.typeSpeed;

        // typing speed
        self.loop = self.options.loop;

        // amount of time to wait before backspacing
        self.backDelay = self.options.backDelay;

        // input strings of text
        self.strings = self.options.strings;

        // character number position of current string
        self.strPos = 0;

        // current array position
        self.arrayPos = 0;

        // current string based on current values[] array position 
        self.string = self.strings[self.arrayPos];

        // number to stop backspacing on.
        // default 0, can change depending on how many chars
        // you want to remove at the time
        self.stopNum = 0;

        // number in which to stop going through array
        // set to strings[] array (length - 1) to stop deleting after last string is typed
        self.stopArray = self.strings.length-1;

        // All systems go!
        self.init();
    }

        Typed.prototype =  {

            constructor: Typed

            , init: function(){
                // begin the loop w/ first current string (global self.string)
                // current string will be passed as an argument each time after this
                self.typewrite(self.string, self.strPos);
                self.el.after("<span id=\"typed-cursor\">|</span>");
            }

            // pass current string state to each function
            , typewrite: function(curString, curStrPos){

                // varying values for setTimeout during typing
                // can't be global since number changes each time loop is executed
                var humanize = Math.round(Math.random() * (100 - 30)) + self.typeSpeed;

                // ------ optional ------ //
                // custom backspace delay
                // if (self.arrayPos == 1){
                //  self.backDelay = 50;
                // }
                // else{ self.backDelay = 500; }

                // containg entire typing function in a timeout
                setTimeout(function() {

                    // make sure array position is less than array length
                    if (self.arrayPos < self.strings.length){

                        // start typing each new char into existing string
                        // curString is function arg
                        self.el.text(self.text + curString.substr(0, curStrPos));

                        // check if current character number is the string's length
                        // and if the current array position is less than the stopping point
                        // if so, backspace after backDelay setting
                        if (curStrPos > curString.length && self.arrayPos < self.stopArray){
                            clearTimeout();
                            setTimeout(function(){
                                self.backspace(curString, curStrPos);
                            }, self.backDelay);
                        }

                        // else, keep typing
                        else{
                            // add characters one by one
                            curStrPos++;
                            // loop the function
                            self.typewrite(curString, curStrPos);
                            // if the array position is at the stopping position
                            // finish code, on to next task
                            if (self.arrayPos == self.stopArray && curStrPos == curString.length){
                                // animation that occurs on the last typed string
                                // place any finishing code here

                                if(self.loop){
                                        self.arrayPos=0;
                                        curStrPos=0;
                                }else{
                                self.options.callback();
                                clearTimeout();}
                            }
                        }
                    }

                // humanized value for typing
                }, humanize);

            }

            , backspace: function(curString, curStrPos){

                // varying values for setTimeout during typing
                // can't be global since number changes each time loop is executed
                var humanize = Math.round(Math.random() * (100 - 30)) + self.typeSpeed;

                setTimeout(function() {

                        // ----- this part is optional ----- //
                        // check string array position
                        // on the first string, only delete one word
                        // the stopNum actually represents the amount of chars to
                        // keep in the current string. In my case it's 14.
                        // if (self.arrayPos == 1){
                        //  self.stopNum = 14;
                        // }
                        //every other time, delete the whole typed string
                        // else{
                        //  self.stopNum = 0;
                        // }

                    // ----- continue important stuff ----- //
                        // replace text with current text + typed characters
                        self.el.text(self.text + curString.substr(0, curStrPos));

                        // if the number (id of character in current string) is 
                        // less than the stop number, keep going
                        if (curStrPos > self.stopNum){
                            // subtract characters one by one
                            curStrPos--;
                            // loop the function
                            self.backspace(curString, curStrPos);
                        }
                        // if the stop number has been reached, increase 
                        // array position to next string
                        else if (curStrPos <= self.stopNum){
                            clearTimeout();
                            self.arrayPos = self.arrayPos+1;
                            // must pass new array position in this instance
                            // instead of using global arrayPos
                            self.typewrite(self.strings[self.arrayPos], curStrPos);
                        }

                // humanized value for typing
                }, humanize);   

            }

        }

    $.fn.typed = function (option) {
        return this.each(function () {
          var $this = $(this)
            , data = $this.data('typed')
            , options = typeof option == 'object' && option
          if (!data) $this.data('typed', (data = new Typed(this, options)))
          if (typeof option == 'string') data[option]()
        });
    }

    $.fn.typed.defaults = {
        strings: ["These are the default values...", "You know what you should do?", "Use your own!", "Have a great day!"],
        // typing and backspacing speed
        typeSpeed: 0,
        // time before backspacing
        backDelay: 500,
        loop:false,
        // ending callback function
        callback: function(){ null }
    }


}(window.jQuery);
like image 31
kasper Taeymans Avatar answered Sep 18 '22 19:09

kasper Taeymans