Socket
Socket
Sign inDemoInstall

typeit

Package Overview
Dependencies
1
Maintainers
1
Versions
117
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.1 to 2.0.0

src/jquery-2.1.4.min.js

438

dist/typeit.js
/**
* jQuery TypeIt
* @author Alex MacArthur (http://macarthur.me)
* @version 1.1.1
* @version 2.0.0
* @copyright 2015 Alex MacArthur

@@ -23,21 +23,29 @@ * @description Types out a given string or strings.

$.fn.typeIt.typeItClass = function(theElement, options, callback){
// plugin default settings
/* VARIABLES THAT WON'T CHANGE BETWEEN RUNS */
// default settings
this.defaults = {
whatToType:'This is the default string. Please replace this string with your own.',
typeSpeed: 200,
lifeLike: false,
showCursor: true,
breakLines: true,
breakWait: 500,
delayStart: 250
whatToType:'You probably want to use your own string.',
typeSpeed: 100,
lifeLike: true,
showCursor: true,
breakLines: true,
breakDelay: 750,
startDelay: 250,
loop: false,
loopDelay: 750
};
// data-typeit-* settings
this.dataAttDefaults = {
whatToType : theElement.data('typeitWhattotype'),
typeSpeed: theElement.data('typeitSpeed'),
whatToType: theElement.data('typeitWhattotype'),
typeSpeed: theElement.data('typeitTypespeed'),
lifeLike: theElement.data('typeitLifelike'),
showCursor: theElement.data('typeitShowcursor'),
breakLines: theElement.data('typeitBreaklines'),
breakWait: theElement.data('typeitBreakWait'),
delayStart : theElement.data('typeitDelayStart')
breakDelay: theElement.data('typeitBreakdelay'),
startDelay: theElement.data('typeitStartdelay'),
loop: theElement.data('typeitLoop'),
loopDelay: theElement.data('typeitLoopdelay')
};

@@ -47,2 +55,4 @@

this.settings = {};
// merge settings into this.settings object
$.extend(this.settings, this.defaults, options, this.dataAttDefaults);
// the element that holds the text

@@ -52,8 +62,11 @@ this.theElement = theElement;

this.callback = callback;
// the number of types a character has been typed for each pass over a string
this.typeCount = 0;
// the character number of a string that's currently being deleted
this.deleteCount = 0;
// the string number that's currently being typed or deleted
this.stringCount = 0;
// let 'r rip
this.init(options);
};
// create a new prototype
_proto = $.fn.typeIt.typeItClass.prototype;
_proto.init = function(options){
// the place we're at in the big merged string

@@ -65,23 +78,42 @@ this.stringPlaceCount = 0;

this.stringArray = [];
// the index of the string we're handling
this.stringArrayIndex = 0;
// the index of the character we're currently printing
this.stringArrayCharacterIndex = 0;
// hold where we need to replace characters because of HTML tags
this.contentStartEnd = [];
// the index for the string within an HTML tag
this.contentStartEndIndex = 0;
// the span of characters for the string inside an HTML tag
this.contentStartEndSpan = 0;
// holds whether we're currently printing inside HTML tags
this.printingInTag = false;
// the specific character we're currently appending
this.characterToAppend = null;
// the current ti-text-container we're dealing
this.thisTiTextContainer = null;
// the current string we're handling
this.thisString = null;
// the particular HTML tag we're handling
this.thisTag = null;
// array holding the length of each string
this.stringLengths = [];
// the string we're currently deleting
this.stringToDelete = null;
// the timeout responsible for typing/adding characters
this.typeTimeout = null;
// the timeout responsible for deleting characters
this.deleteTimeout = null;
// the timeout responsible for typing/adding characters
this.typeTimeout = null;
// the progressively shorter string as it's being deleted
this.shortenedText = null;
// let 'r rip
this.init(options);
};
// the span of the range a type speed is allowed to be randomized
this.typeSpeedRangeSpan = null;
// the minimum of a randomized type speed
this.typeSpeedMin = null;
// the maximum of a randomized type speed
this.typeSpeedMax = null;
// create a new prototype
_proto = $.fn.typeIt.typeItClass.prototype;
_proto.init = function(options){
// make sure the callback function is all good
if(this.validateCallbackFunction() === false){ return false; }
// merge settings into this.settings object
$.extend(this.settings, this.defaults, options, this.dataAttDefaults);
// string override
this.testForElementStringOverride();
// process the whatToType data to get it so we can use it

@@ -94,7 +126,20 @@ this.processWhatToType();

this.typeLoop();
}.bind(this), this.settings.delayStart);
}.bind(this), this.settings.startDelay);
};
_proto.testForElementStringOverride = function() {
// if there's a string already typed in the element, replace whatToType with it
if(this.theElement.text().length > 0 && !this.theElement.has('.ti-container')) {
this.settings.whatToType = this.theElement.html();
}
};
_proto.setupDOMComponents = function() {
// clear out the element in case we're looping
this.theElement.html('');
// get the string lengths and save to array, set up ti-containers for each string

@@ -123,13 +168,71 @@ for(j=0; j < this.stringArray.length; j++){

_proto.processWhatToType = function() {
this.stringArray = this.settings.whatToType;
// check if the value is an array or just a string
if(Object.prototype.toString.call(this.stringArray) !== '[object Array]'){
// since it's not already an array, turn it into one, since later functionality depends on it being one
this.stringArray = '["' + this.stringArray + '"]';
this.stringArray = JSON.parse(this.stringArray);
// check if the value is an array or just a string
if(Object.prototype.toString.call(this.settings.whatToType) !== '[object Array]'){
// since it's not already an array, turn it into one, since later functionality depends on it being one
this.stringArray = '["' + this.settings.whatToType + '"]';
this.stringArray = JSON.parse(this.stringArray);
// if it is an array, clone it
} else {
// clone what to typed, so we don't modify the original strings in case we loop
this.stringArrayTemp = $.extend( {}, this.settings.whatToType );
// convert cloned object to array
this.stringArrayTemp = $.map(this.stringArrayTemp, function(value, index) {
return [value];
});
// get the right values and put into stringArray so it's formatted correctly for processing
for(var h = 0; h < this.stringArrayTemp.length; h++) {
this.stringArray.push(this.stringArrayTemp[h]);
}
// turn string array into a big string
this.mergedStrings = this.stringArray.join('');
};
}
// turn each string into sub arrays
for(var i = 0; i < this.stringArray.length; i++) {
this.contentStartEnd = [];
this.contentStartEndIndex = 0;
this.contentStartEndSpan = 0;
// turn each string into sub array
this.stringArray[i] = this.stringArray[i].split('');
// find the location of HTML tag
for(var j = 0, subArray = this.stringArray[i]; j < subArray.length; j++) {
if(subArray[j] === '<') {
this.contentStartEnd[this.contentStartEndIndex] = [];
this.contentStartEnd[this.contentStartEndIndex][0] = j;
}
if(subArray[j] === '>') {
this.contentStartEnd[this.contentStartEndIndex][1] = j;
this.contentStartEndIndex++;
}
}
// merge individual tag characters into single array index
for(var positionIndex = 0; positionIndex < this.contentStartEnd.length; positionIndex++) {
// move those tag pieces into a single array item
for (var l = this.contentStartEnd[positionIndex][0]; l < this.contentStartEnd[positionIndex][1]; l++) {
this.stringArray[i][this.contentStartEnd[positionIndex][0]] = this.stringArray[i][this.contentStartEnd[positionIndex][0]] + this.stringArray[i][l+1];
}
}
// cut array items based on the start/end positions we know, but move back the start point each time by the number of items we previously removed
for( var m = 0; m < this.contentStartEnd.length; m++ ) {
var startPos = this.contentStartEnd[m][0]+1;
this.stringArray[i].splice(startPos, this.contentStartEnd[m][1] - this.contentStartEnd[m][0]);
var span = this.contentStartEnd[m][1] - this.contentStartEnd[m][0];
// go through and update the start and positions by the span length we just cut
for(var n = 0; n < this.contentStartEnd.length; n++) {
this.contentStartEnd[n][0] = this.contentStartEnd[n][0] - span;
this.contentStartEnd[n][1] = this.contentStartEnd[n][1] - span;
}
}
}
};
_proto.validateCallbackFunction = function() {

@@ -144,50 +247,92 @@

_proto.typeLoop = function(){
// set the length of the current phrase being typed
this.phraseLength = this.stringLengths[this.stringCount];
// make it human-like if specified in the settings
_proto.randomizeTypeSpeed = function() {
// make it human-like if specified in the settings
if(this.settings.lifeLike === true){
this.delayTime = this.settings.typeSpeed*Math.random();
// set to 50% of the actual type speed, so the randomization goes no further than that ratio
this.typeSpeedRangeSpan = this.settings.typeSpeed/2;
this.typeSpeedMin = this.settings.typeSpeed-this.typeSpeedRangeSpan;
this.typeSpeedMax = this.settings.typeSpeed+this.typeSpeedRangeSpan;
this.delayTime = Math.abs(Math.random() * (this.typeSpeedMax - this.typeSpeedMin) + this.typeSpeedMin);
} else {
this.delayTime = this.settings.typeSpeed;
}
};
_proto.typeLoop = function(){
// get this particular string we're printing
this.thisString = this.stringArray[this.stringArrayIndex];
// set the length of the current phrase being typed
this.phraseLength = this.thisString.length;
// start the typing timeout
this.typeTimeout = setTimeout(function () {
// append the string of letters to the respective .ti-text-container
var characterToAppend = this.mergedStrings[this.typeCount+this.stringPlaceCount];
this.randomizeTypeSpeed();
// if breakLines is set to true, add the 'active-container' class to the next .ti-text-container in the list.
if(this.settings.breakLines === true) {
this.theElement.find('.ti-text-container:eq('+ this.stringCount +')').addClass('active-container').append(characterToAppend);
} else {
this.theElement.find('.ti-text-container').addClass('active-container').append(characterToAppend);
// the the specific character we're printing
this.characterToAppend = this.stringArray[this.stringArrayIndex][this.stringArrayCharacterIndex];
// if it's an HTML tag, do stuff
if(this.characterToAppend.indexOf('<') !== -1 && this.characterToAppend.indexOf('</') === -1){
this.contentStartEndIndex = 0;
// get the start & end positions of the actual string within the HTML tags
this.contentStartEnd[0] = this.stringArrayCharacterIndex + 1;
for(var t = this.stringArrayCharacterIndex; t < this.thisString.length; t++){
if(this.thisString[t].indexOf('</') !== -1) {
// set the ending of the string segment in an HTML tag
this.contentStartEnd[1] = t - 1;
// as soon as we hit a match for a closing character
break;
}
}
this.contentStartEndSpan = this.contentStartEnd[1] - this.contentStartEnd[0];
// create a DOM node from the string we get
this.thisTag = $($.parseHTML(this.characterToAppend));
// set the current character to append to the tag we just created, so that we can create it in the DOM
this.characterToAppend = this.thisTag;
// append the tag
this.appendTheCharacter();
// set this to true so we know we're currently printing inside an HTML tag
this.printingInTag = true;
}
this.typeCount++;
// if there are still characters to be typed, call the same function again
if (this.typeCount < this.phraseLength) {
this.typeLoop(this.stringLengths[this.stringCount]);
// if there are no more characters to print and there is more than one string to be typed, delete the string just printed
this.appendTheCharacter();
this.stringArrayCharacterIndex++;
// there are still characters to be typed, so repeat function
if (this.stringArrayCharacterIndex < this.phraseLength) {
this.typeLoop();
// there are no more characters to print and there is more than one string to be typed, so delete the string just printed
} else if(this.stringArray.length > 1) {
// reset this.stringArrayCharacterIndex since we're done using it for this string
this.stringArrayCharacterIndex = 0;
// update the this.stringPlaceCount so that we're appending starting at the correct spot in the merged string
this.stringPlaceCount = this.stringPlaceCount + this.phraseLength;
// reset this.typeCount in case this function needs to be reused
this.typeCount = 0;
// if the stringCount is the same as the number of strings we started with, we're done, so call the callback function
if(this.stringCount+1 === this.stringArray.length) {
this.callback();
// if the this.stringArrayIndex is the same as the number of strings we started with, we're done, so call the callback function
if(this.stringArrayIndex + 1 === this.stringArray.length) {
// multiple strings ending
this.endOfStringsFork();
// if we're not on the last string, then move on to to delete, unless the user wants to break lines
} else if((this.stringCount+1 < this.stringArray.length) && this.settings.breakLines === false){
} else if((this.stringArrayIndex + 1 < this.stringArray.length) && this.settings.breakLines === false){
setTimeout(function(){
this.deleteLoop();
}.bind(this), this.settings.breakWait);
}.bind(this), this.settings.breakDelay);
// if breakLines is true and we still have strings left to type, break it and continue
} else if (this.stringCount+1 < this.stringArray.length && this.settings.breakLines === true){
this.stringCount++;
// if breakLines is true and we still have strings left to type, break it and continue with the next string
} else if (this.stringArrayIndex + 1 < this.stringArray.length && this.settings.breakLines === true){
// before starting the next string, make sure the index has been bumped up
this.stringArrayIndex++;

@@ -200,3 +345,3 @@ setTimeout(function(){

// give 'active-container' class to next container, so the cursor can start blinking
this.theElement.find('.ti-text-container:eq('+ this.stringCount +')').addClass('active-container');
this.theElement.find('.ti-text-container:eq('+ this.stringArrayIndex +')').addClass('active-container');

@@ -206,5 +351,5 @@ // after another slight delay, continue typing the next string

this.typeLoop();
}.bind(this), this.settings.breakWait);
}.bind(this), this.settings.breakDelay);
}.bind(this), this.settings.breakWait);
}.bind(this), this.settings.breakDelay);

@@ -215,4 +360,6 @@ }

} else {
this.callback();
// single string ending
this.endOfStringsFork();
}
}.bind(this), this.delayTime);

@@ -222,32 +369,135 @@

_proto.deleteLoop = function() {
_proto.endOfStringsFork = function() {
if(this.settings.loop === true){
// delete the remaining string
setTimeout(function(){
this.deleteLoop();
}.bind(this), this.settings.loopDelay);
} else {
this.callback();
}
};
_proto.appendTheCharacter = function() {
// if breakLines is set to true, add the 'active-container' class to the next .ti-text-container in the list.
if(this.settings.breakLines === true) {
this.thisTiTextContainer = this.theElement.find('.ti-text-container:eq('+ this.stringArrayIndex +')');
this.thisTiTextContainer.addClass('active-container');
} else {
this.thisTiTextContainer = this.theElement.find('.ti-text-container');
this.thisTiTextContainer.addClass('active-container');
}
// append the character to the HTML tag if we're printing in a tag, or else just append the character
this.appendToHTMLTag(function(){
this.thisTiTextContainer.append(this.characterToAppend);
}.bind(this));
};
_proto.appendToHTMLTag = function(notInTagFunction) {
if(this.printingInTag === true) {
// resave the character to append
this.characterToAppend = this.thisString[this.contentStartEnd[0] + this.contentStartEndIndex];
// append to the latest tag (the one we just printed) in the element
$(this.thisTag, this.theElement).last().append(this.characterToAppend);
// if we're at the end of the string segment, turn off printingInTag
this.printingInTag = (this.contentStartEnd[1] === this.contentStartEnd[0] + this.contentStartEndIndex - 1) ? false : true;
this.contentStartEndIndex++;
} else {
notInTagFunction();
}
};
_proto.deleteLoop = function(undefined) {
// set the current ti-text-container
this.thisTiTextContainer = this.theElement.find('.ti-text-container');
this.deleteTimeout = setTimeout(function () {
// get the string from the element and cut it by one character at the end
shortenedText = this.theElement.find('.ti-text-container').text().substring(0, this.theElement.find('.ti-text-container').text().length - 1);
// randomize the delete speed, if applicable
this.randomizeTypeSpeed();
// then, put that shortened text into the element so it looks like it's being deleted
this.theElement.find('.ti-text-container').text(shortenedText);
// get the string
this.stringToDelete = this.thisTiTextContainer.last().html();
this.deleteCount++;
// if there are still characters in the string, run the function again
if (this.deleteCount < this.phraseLength) {
this.deleteLoop();
// convert to array
this.arrayToDelete = this.stringToDelete.split("");
// loop over array
for (var n = this.arrayToDelete.length-1; n > -1; n--) {
// TAG HANDLING
if(this.arrayToDelete[n] === '>') {
// find the beginning tag piece
for(var o = n-1; o > -1; o--) {
// find the opening piece
// o = position of opening piece
if(this.arrayToDelete[o] === '<') {
// if the next piece before it isn't an HTML tag, just delete the text in between
if(this.arrayToDelete[o-1] !== '>') {
// remove character right before HTML tag begins and escape the loop
this.arrayToDelete.splice(o-1, 1);
break;
}
}
}
break;
}
// REGULAR CHARACTER HANDLING
else {
// remove the character and escape the loop
this.arrayToDelete.splice(n, 1);
break;
}
}
// repopulate the element with the shortened string so it looks like it's being deleted
this.thisTiTextContainer.last().html(this.arrayToDelete.join(''));
// if nothing left, clear out the emtpy HTML tags
if(this.thisTiTextContainer.last().text().length === 0){
this.thisTiTextContainer.last().html('');
}
// if characters are still in the string, run the function again
if (this.thisTiTextContainer.last().text().length > 0) {
this.deleteLoop();
// if there are still strings in the array, go back to typing.
} else if(this.stringArray[this.stringCount+1] !== undefined){
this.deleteCount = 0;
this.stringCount++;
this.typeLoop();
}
} else if(this.stringArray[this.stringArrayIndex+1] !== undefined){
this.stringArrayIndex++;
this.typeLoop();
// that was the last string in the array, so now just check if loop is enabled
} else if (this.settings.loop === true){
// if there are multiple strings that have been typed, remove the current one and repeat deleteLoop
if(this.thisTiTextContainer.length > 1) {
// remove the current container so we don't fill it with junk
this.thisTiTextContainer.last().remove();
// make sure the NEW last container has 'active-container' status
// need to use find() again instead of stored selection because that stored selection is now outdated since we just removed a container
this.theElement.find('.ti-text-container').last().addClass('active-container');
this.deleteLoop();
} else {
// otherwise, re-run the whole thing again
this.init();
}
}
// make backspacing much quicker by dividing delayTime (arbitrarily) by three
}.bind(this), this.delayTime/3);
};
}.bind(this), this.delayTime/3);
};
// stop the plugin from typing or deleting stuff whenever it's called
_proto.stopTyping = function() {
// stop the plugin from typing or deleting stuff whenever it's called
_proto.stop = function() {
clearTimeout(this.typeTimeout);
clearTimeout(this.deleteTimeout);
};
};
}(jQuery));

@@ -1,1 +0,492 @@

!function(t,e){t.fn.typeIt=function(e,i){return this.each(function(){t(this).data("typeit",new t.fn.typeIt.typeItClass(t(this),e,i))})},t.fn.typeIt.typeItClass=function(t,e,i){this.defaults={whatToType:"This is the default string. Please replace this string with your own.",typeSpeed:200,lifeLike:!1,showCursor:!0,breakLines:!0,breakWait:500,delayStart:250},this.dataAttDefaults={whatToType:t.data("typeitWhattotype"),typeSpeed:t.data("typeitSpeed"),lifeLike:t.data("typeitLifelike"),showCursor:t.data("typeitShowcursor"),breakLines:t.data("typeitBreaklines"),breakWait:t.data("typeitBreakWait"),delayStart:t.data("typeitDelayStart")},this.settings={},this.theElement=t,this.callback=i,this.typeCount=0,this.deleteCount=0,this.stringCount=0,this.stringPlaceCount=0,this.phraseLength=0,this.stringArray=[],this.stringLengths=[],this.deleteTimeout=null,this.typeTimeout=null,this.shortenedText=null,this.init(e)},_proto=t.fn.typeIt.typeItClass.prototype,_proto.init=function(e){return this.validateCallbackFunction()===!1?!1:(t.extend(this.settings,this.defaults,e,this.dataAttDefaults),this.processWhatToType(),this.setupDOMComponents(),void setTimeout(function(){this.typeLoop()}.bind(this),this.settings.delayStart))},_proto.setupDOMComponents=function(){for(j=0;j<this.stringArray.length;j++)this.stringLengths[j]=this.stringArray[j].length,this.theElement.append('<span class="ti-container"><span class="ti-text-container ti-cursor"></span></span>');this.theElement.find(".ti-container:first-child").find(".ti-text-container").addClass("active-container"),this.settings.breakLines===!1&&(this.theElement.find(".ti-container").remove(),this.theElement.append('<span class="ti-container"><span class="ti-text-container ti-cursor"></span></span>')),this.settings.showCursor===!1&&this.theElement.find(".ti-text-container").removeClass("ti-cursor")},_proto.processWhatToType=function(){this.stringArray=this.settings.whatToType,"[object Array]"!==Object.prototype.toString.call(this.stringArray)&&(this.stringArray='["'+this.stringArray+'"]',this.stringArray=JSON.parse(this.stringArray)),this.mergedStrings=this.stringArray.join("")},_proto.validateCallbackFunction=function(){"undefined"==typeof this.callback&&(this.callback=function(){return!0})},_proto.typeLoop=function(){this.phraseLength=this.stringLengths[this.stringCount],this.settings.lifeLike===!0?this.delayTime=this.settings.typeSpeed*Math.random():this.delayTime=this.settings.typeSpeed,this.typeTimeout=setTimeout(function(){var t=this.mergedStrings[this.typeCount+this.stringPlaceCount];this.settings.breakLines===!0?this.theElement.find(".ti-text-container:eq("+this.stringCount+")").addClass("active-container").append(t):this.theElement.find(".ti-text-container").addClass("active-container").append(t),this.typeCount++,this.typeCount<this.phraseLength?this.typeLoop(this.stringLengths[this.stringCount]):this.stringArray.length>1?(this.stringPlaceCount=this.stringPlaceCount+this.phraseLength,this.typeCount=0,this.stringCount+1===this.stringArray.length?this.callback():this.stringCount+1<this.stringArray.length&&this.settings.breakLines===!1?setTimeout(function(){this.deleteLoop()}.bind(this),this.settings.breakWait):this.stringCount+1<this.stringArray.length&&this.settings.breakLines===!0&&(this.stringCount++,setTimeout(function(){this.theElement.find(".ti-text-container").removeClass("active-container"),this.theElement.find(".ti-text-container:eq("+this.stringCount+")").addClass("active-container"),setTimeout(function(){this.typeLoop()}.bind(this),this.settings.breakWait)}.bind(this),this.settings.breakWait))):this.callback()}.bind(this),this.delayTime)},_proto.deleteLoop=function(){this.deleteTimeout=setTimeout(function(){shortenedText=this.theElement.find(".ti-text-container").text().substring(0,this.theElement.find(".ti-text-container").text().length-1),this.theElement.find(".ti-text-container").text(shortenedText),this.deleteCount++,this.deleteCount<this.phraseLength?this.deleteLoop():this.stringArray[this.stringCount+1]!==e&&(this.deleteCount=0,this.stringCount++,this.typeLoop())}.bind(this),this.delayTime/3)},_proto.stopTyping=function(){clearTimeout(this.typeTimeout),clearTimeout(this.deleteTimeout)}}(jQuery);
/**
* jQuery TypeIt
* @author Alex MacArthur (http://macarthur.me)
* @version 2.0.0
* @copyright 2015 Alex MacArthur
* @description Types out a given string or strings.
*/
(function($, undefined){
var proto;
// the actual jQuery function
$.fn.typeIt = function(options, callback){
// now call a callback function
return this.each(function(){
$(this).data("typeit", new $.fn.typeIt.typeItClass($(this), options, callback));
});
};
// create the class
$.fn.typeIt.typeItClass = function(theElement, options, callback){
/* VARIABLES THAT WON'T CHANGE BETWEEN RUNS */
// default settings
this.defaults = {
whatToType:'You probably want to use your own string.',
typeSpeed: 100,
lifeLike: true,
showCursor: true,
breakLines: true,
breakDelay: 750,
startDelay: 250,
loop: false,
loopDelay: 750
};
// data-typeit-* settings
this.dataAttDefaults = {
whatToType: theElement.data('typeitWhattotype'),
typeSpeed: theElement.data('typeitTypespeed'),
lifeLike: theElement.data('typeitLifelike'),
showCursor: theElement.data('typeitShowcursor'),
breakLines: theElement.data('typeitBreaklines'),
breakDelay: theElement.data('typeitBreakdelay'),
startDelay: theElement.data('typeitStartdelay'),
loop: theElement.data('typeitLoop'),
loopDelay: theElement.data('typeitLoopdelay')
};
// the settings for the plugin instance
this.settings = {};
// merge settings into this.settings object
$.extend(this.settings, this.defaults, options, this.dataAttDefaults);
// the element that holds the text
this.theElement = theElement;
// callback function that executes after strings have been printed
this.callback = callback;
// let 'r rip
this.init(options);
};
// create a new prototype
_proto = $.fn.typeIt.typeItClass.prototype;
_proto.init = function(options){
// the place we're at in the big merged string
this.stringPlaceCount = 0;
// the length of the current string being handled
this.phraseLength = 0;
// array that holds whatToType string(s)
this.stringArray = [];
// the index of the string we're handling
this.stringArrayIndex = 0;
// the index of the character we're currently printing
this.stringArrayCharacterIndex = 0;
// hold where we need to replace characters because of HTML tags
this.contentStartEnd = [];
// the index for the string within an HTML tag
this.contentStartEndIndex = 0;
// the span of characters for the string inside an HTML tag
this.contentStartEndSpan = 0;
// holds whether we're currently printing inside HTML tags
this.printingInTag = false;
// the specific character we're currently appending
this.characterToAppend = null;
// the current ti-text-container we're dealing
this.thisTiTextContainer = null;
// the current string we're handling
this.thisString = null;
// the particular HTML tag we're handling
this.thisTag = null;
// array holding the length of each string
this.stringLengths = [];
// the string we're currently deleting
this.stringToDelete = null;
// the timeout responsible for typing/adding characters
this.typeTimeout = null;
// the timeout responsible for deleting characters
this.deleteTimeout = null;
// the span of the range a type speed is allowed to be randomized
this.typeSpeedRangeSpan = null;
// the minimum of a randomized type speed
this.typeSpeedMin = null;
// the maximum of a randomized type speed
this.typeSpeedMax = null;
// make sure the callback function is all good
if(this.validateCallbackFunction() === false){ return false; }
// string override
this.testForElementStringOverride();
// process the whatToType data to get it so we can use it
this.processWhatToType();
// add all the elements & classes we'll be needing
this.setupDOMComponents();
// start to type the string(s) after the specified delay
setTimeout(function() {
this.typeLoop();
}.bind(this), this.settings.startDelay);
};
_proto.testForElementStringOverride = function() {
// if there's a string already typed in the element, replace whatToType with it
if(this.theElement.text().length > 0 && !this.theElement.has('.ti-container')) {
this.settings.whatToType = this.theElement.html();
}
};
_proto.setupDOMComponents = function() {
// clear out the element in case we're looping
this.theElement.html('');
// get the string lengths and save to array, set up ti-containers for each string
for(j=0; j < this.stringArray.length; j++){
this.stringLengths[j] = this.stringArray[j].length;
// set up the number of ti-containers we'll need to hold the strings
this.theElement.append('<span class="ti-container"><span class="ti-text-container ti-cursor"></span></span>');
}
// add .active-container to the first .ti-text-container so the cursor starts blinking before a string is printed
this.theElement.find('.ti-container:first-child').find('.ti-text-container').addClass('active-container');
// if breakLines is false, then we for sure only need ONE ti-container even if there multiple strings, so make sure of that
if(this.settings.breakLines === false) {
this.theElement.find('.ti-container').remove();
this.theElement.append('<span class="ti-container"><span class="ti-text-container ti-cursor"></span></span>');
}
// if showCursor is false, then remove the ti-cursor class
if(this.settings.showCursor === false) {
this.theElement.find('.ti-text-container').removeClass('ti-cursor');
}
};
_proto.processWhatToType = function() {
// check if the value is an array or just a string
if(Object.prototype.toString.call(this.settings.whatToType) !== '[object Array]'){
// since it's not already an array, turn it into one, since later functionality depends on it being one
this.stringArray = '["' + this.settings.whatToType + '"]';
this.stringArray = JSON.parse(this.stringArray);
// if it is an array, clone it
} else {
// clone what to typed, so we don't modify the original strings in case we loop
this.stringArrayTemp = $.extend( {}, this.settings.whatToType );
// convert cloned object to array
this.stringArrayTemp = $.map(this.stringArrayTemp, function(value, index) {
return [value];
});
// get the right values and put into stringArray so it's formatted correctly for processing
for(var h = 0; h < this.stringArrayTemp.length; h++) {
this.stringArray.push(this.stringArrayTemp[h]);
}
}
// turn each string into sub arrays
for(var i = 0; i < this.stringArray.length; i++) {
this.contentStartEnd = [];
this.contentStartEndIndex = 0;
this.contentStartEndSpan = 0;
// turn each string into sub array
this.stringArray[i] = this.stringArray[i].split('');
// find the location of HTML tag
for(var j = 0, subArray = this.stringArray[i]; j < subArray.length; j++) {
if(subArray[j] === '<') {
this.contentStartEnd[this.contentStartEndIndex] = [];
this.contentStartEnd[this.contentStartEndIndex][0] = j;
}
if(subArray[j] === '>') {
this.contentStartEnd[this.contentStartEndIndex][1] = j;
this.contentStartEndIndex++;
}
}
// merge individual tag characters into single array index
for(var positionIndex = 0; positionIndex < this.contentStartEnd.length; positionIndex++) {
// move those tag pieces into a single array item
for (var l = this.contentStartEnd[positionIndex][0]; l < this.contentStartEnd[positionIndex][1]; l++) {
this.stringArray[i][this.contentStartEnd[positionIndex][0]] = this.stringArray[i][this.contentStartEnd[positionIndex][0]] + this.stringArray[i][l+1];
}
}
// cut array items based on the start/end positions we know, but move back the start point each time by the number of items we previously removed
for( var m = 0; m < this.contentStartEnd.length; m++ ) {
var startPos = this.contentStartEnd[m][0]+1;
this.stringArray[i].splice(startPos, this.contentStartEnd[m][1] - this.contentStartEnd[m][0]);
var span = this.contentStartEnd[m][1] - this.contentStartEnd[m][0];
// go through and update the start and positions by the span length we just cut
for(var n = 0; n < this.contentStartEnd.length; n++) {
this.contentStartEnd[n][0] = this.contentStartEnd[n][0] - span;
this.contentStartEnd[n][1] = this.contentStartEnd[n][1] - span;
}
}
}
};
_proto.validateCallbackFunction = function() {
// if undefined, assign blank callback
if(typeof this.callback === 'undefined') {
this.callback = function(){return true;};
}
};
_proto.randomizeTypeSpeed = function() {
// make it human-like if specified in the settings
if(this.settings.lifeLike === true){
// set to 50% of the actual type speed, so the randomization goes no further than that ratio
this.typeSpeedRangeSpan = this.settings.typeSpeed/2;
this.typeSpeedMin = this.settings.typeSpeed-this.typeSpeedRangeSpan;
this.typeSpeedMax = this.settings.typeSpeed+this.typeSpeedRangeSpan;
this.delayTime = Math.abs(Math.random() * (this.typeSpeedMax - this.typeSpeedMin) + this.typeSpeedMin);
} else {
this.delayTime = this.settings.typeSpeed;
}
};
_proto.typeLoop = function(){
// get this particular string we're printing
this.thisString = this.stringArray[this.stringArrayIndex];
// set the length of the current phrase being typed
this.phraseLength = this.thisString.length;
// start the typing timeout
this.typeTimeout = setTimeout(function () {
this.randomizeTypeSpeed();
// the the specific character we're printing
this.characterToAppend = this.stringArray[this.stringArrayIndex][this.stringArrayCharacterIndex];
// if it's an HTML tag, do stuff
if(this.characterToAppend.indexOf('<') !== -1 && this.characterToAppend.indexOf('</') === -1){
this.contentStartEndIndex = 0;
// get the start & end positions of the actual string within the HTML tags
this.contentStartEnd[0] = this.stringArrayCharacterIndex + 1;
for(var t = this.stringArrayCharacterIndex; t < this.thisString.length; t++){
if(this.thisString[t].indexOf('</') !== -1) {
// set the ending of the string segment in an HTML tag
this.contentStartEnd[1] = t - 1;
// as soon as we hit a match for a closing character
break;
}
}
this.contentStartEndSpan = this.contentStartEnd[1] - this.contentStartEnd[0];
// create a DOM node from the string we get
this.thisTag = $($.parseHTML(this.characterToAppend));
// set the current character to append to the tag we just created, so that we can create it in the DOM
this.characterToAppend = this.thisTag;
// append the tag
this.appendTheCharacter();
// set this to true so we know we're currently printing inside an HTML tag
this.printingInTag = true;
}
this.appendTheCharacter();
this.stringArrayCharacterIndex++;
// there are still characters to be typed, so repeat function
if (this.stringArrayCharacterIndex < this.phraseLength) {
this.typeLoop();
// there are no more characters to print and there is more than one string to be typed, so delete the string just printed
} else if(this.stringArray.length > 1) {
// reset this.stringArrayCharacterIndex since we're done using it for this string
this.stringArrayCharacterIndex = 0;
// update the this.stringPlaceCount so that we're appending starting at the correct spot in the merged string
this.stringPlaceCount = this.stringPlaceCount + this.phraseLength;
// if the this.stringArrayIndex is the same as the number of strings we started with, we're done, so call the callback function
if(this.stringArrayIndex + 1 === this.stringArray.length) {
// multiple strings ending
this.endOfStringsFork();
// if we're not on the last string, then move on to to delete, unless the user wants to break lines
} else if((this.stringArrayIndex + 1 < this.stringArray.length) && this.settings.breakLines === false){
setTimeout(function(){
this.deleteLoop();
}.bind(this), this.settings.breakDelay);
// if breakLines is true and we still have strings left to type, break it and continue with the next string
} else if (this.stringArrayIndex + 1 < this.stringArray.length && this.settings.breakLines === true){
// before starting the next string, make sure the index has been bumped up
this.stringArrayIndex++;
setTimeout(function(){
// remove any 'active-container' classes fromt the elements
this.theElement.find('.ti-text-container').removeClass('active-container');
// give 'active-container' class to next container, so the cursor can start blinking
this.theElement.find('.ti-text-container:eq('+ this.stringArrayIndex +')').addClass('active-container');
// after another slight delay, continue typing the next string
setTimeout(function(){
this.typeLoop();
}.bind(this), this.settings.breakDelay);
}.bind(this), this.settings.breakDelay);
}
// since there are no more strings to be typed, we're done and can call the callback function
} else {
// single string ending
this.endOfStringsFork();
}
}.bind(this), this.delayTime);
};
_proto.endOfStringsFork = function() {
if(this.settings.loop === true){
// delete the remaining string
setTimeout(function(){
this.deleteLoop();
}.bind(this), this.settings.loopDelay);
} else {
this.callback();
}
};
_proto.appendTheCharacter = function() {
// if breakLines is set to true, add the 'active-container' class to the next .ti-text-container in the list.
if(this.settings.breakLines === true) {
this.thisTiTextContainer = this.theElement.find('.ti-text-container:eq('+ this.stringArrayIndex +')');
this.thisTiTextContainer.addClass('active-container');
} else {
this.thisTiTextContainer = this.theElement.find('.ti-text-container');
this.thisTiTextContainer.addClass('active-container');
}
// append the character to the HTML tag if we're printing in a tag, or else just append the character
this.appendToHTMLTag(function(){
this.thisTiTextContainer.append(this.characterToAppend);
}.bind(this));
};
_proto.appendToHTMLTag = function(notInTagFunction) {
if(this.printingInTag === true) {
// resave the character to append
this.characterToAppend = this.thisString[this.contentStartEnd[0] + this.contentStartEndIndex];
// append to the latest tag (the one we just printed) in the element
$(this.thisTag, this.theElement).last().append(this.characterToAppend);
// if we're at the end of the string segment, turn off printingInTag
this.printingInTag = (this.contentStartEnd[1] === this.contentStartEnd[0] + this.contentStartEndIndex - 1) ? false : true;
this.contentStartEndIndex++;
} else {
notInTagFunction();
}
};
_proto.deleteLoop = function(undefined) {
// set the current ti-text-container
this.thisTiTextContainer = this.theElement.find('.ti-text-container');
this.deleteTimeout = setTimeout(function () {
// randomize the delete speed, if applicable
this.randomizeTypeSpeed();
// get the string
this.stringToDelete = this.thisTiTextContainer.last().html();
// convert to array
this.arrayToDelete = this.stringToDelete.split("");
// loop over array
for (var n = this.arrayToDelete.length-1; n > -1; n--) {
// TAG HANDLING
if(this.arrayToDelete[n] === '>') {
// find the beginning tag piece
for(var o = n-1; o > -1; o--) {
// find the opening piece
// o = position of opening piece
if(this.arrayToDelete[o] === '<') {
// if the next piece before it isn't an HTML tag, just delete the text in between
if(this.arrayToDelete[o-1] !== '>') {
// remove character right before HTML tag begins and escape the loop
this.arrayToDelete.splice(o-1, 1);
break;
}
}
}
break;
}
// REGULAR CHARACTER HANDLING
else {
// remove the character and escape the loop
this.arrayToDelete.splice(n, 1);
break;
}
}
// repopulate the element with the shortened string so it looks like it's being deleted
this.thisTiTextContainer.last().html(this.arrayToDelete.join(''));
// if nothing left, clear out the emtpy HTML tags
if(this.thisTiTextContainer.last().text().length === 0){
this.thisTiTextContainer.last().html('');
}
// if characters are still in the string, run the function again
if (this.thisTiTextContainer.last().text().length > 0) {
this.deleteLoop();
// if there are still strings in the array, go back to typing.
} else if(this.stringArray[this.stringArrayIndex+1] !== undefined){
this.stringArrayIndex++;
this.typeLoop();
// that was the last string in the array, so now just check if loop is enabled
} else if (this.settings.loop === true){
// if there are multiple strings that have been typed, remove the current one and repeat deleteLoop
if(this.thisTiTextContainer.length > 1) {
// remove the current container so we don't fill it with junk
this.thisTiTextContainer.last().remove();
// make sure the NEW last container has 'active-container' status
// need to use find() again instead of stored selection because that stored selection is now outdated since we just removed a container
this.theElement.find('.ti-text-container').last().addClass('active-container');
this.deleteLoop();
} else {
// otherwise, re-run the whole thing again
this.init();
}
}
// make backspacing much quicker by dividing delayTime (arbitrarily) by three
}.bind(this), this.delayTime/3);
};
// stop the plugin from typing or deleting stuff whenever it's called
_proto.stop = function() {
clearTimeout(this.typeTimeout);
clearTimeout(this.deleteTimeout);
};
}(jQuery));

@@ -19,3 +19,3 @@ // load our plugins

gulp.src('src/typeit.js')
.pipe(uglify())
//.pipe(uglify())
.pipe(rename('typeit.min.js'))

@@ -26,3 +26,3 @@ .pipe(gulp.dest('dist'));

gulp.src('src/scripts.js')
.pipe(uglify())
//.pipe(uglify())
.pipe(rename('scripts.min.js'))

@@ -29,0 +29,0 @@ .pipe(gulp.dest('src'));

{
"name": "typeit",
"version": "1.1.1",
"version": "2.0.0",
"license": "GPL-2.0",

@@ -5,0 +5,0 @@ "author": "Alex MacArthur <alex@macarthur.me>",

# TypeIt: A jQuery Animated Typing Plugin
## Description
A jQuery plugin that outputs text like it's being typed. It allows you to type single strings, multiple strings that stack, and multiple strings that delete & replace each other. It's lightweight, scalable, responsive, and super easy to implement.
A jQuery plugin that outputs text like it's being typed. It allows you to type single strings, multiple strings that stack, multiple strings that delete & replace each other, and even text wrapped in HTML tags (including custom classes, ID's, etc.). You can also loop strings or sets of strings continuously.
## Some of the Perks
* Responsive
* Multiple easy ways to set up/initialize
* Handles HTML tags (including your custom classes, ID's, etc.) with ease. **Note: only supports HTML tags that aren't nested in other tags in the string.**
## Demo
Checkout several demos and a sandbox where you can try it out at <a href="http://alexmacarthur.github.io/typeit">alexmacarthur.github.io/typeit</a>.
Checkout several demos and a sandbox where you can try it out at <a href="http://macarthur.me/typeit">macarthur.me/typeit</a>.
## Setup
## Getting Started

@@ -15,5 +20,5 @@ ### Download the Plugin

### Initializing on Your Site
### Prepare to Initialize on Your Site
1. Create an empty HTML element to select.
1. Create an empty HTML element to select. (If you want to have a fallback for users without JavaScript, you can put a string right into the element you create. More on that later.)

@@ -31,3 +36,3 @@ ```<span class="type-it"></span>```

You're ready to initialize it!
You're ready to start typing!

@@ -40,6 +45,31 @@ ## Usage

#### About Using Settings Object
* When using a single string, just wrap it in quotation marks.
* When using multiple strings, place them in an array. Ex: `whatToType: ['String #1','String #2']`
Example:
``
<span class="type-it"></span>
``
```
$('.type-it').typeIt({
whatToType: 'Enter your string here!',
typeSpeed: 300,
lifeLike: false,
showCursor: true
});
```
#### About Using Data Attributes
* Make sure the names are all lowercase.
* When using multiple strings, wrap your array of strings inside quotation marks. Ex: `data-typeit-whattotype='["string #1", "string #2"]'`
Example:
```
<span class="type-it"
data-typeit-whattotype="A new string to type."
data-typeit-speed="100"
data-typeit-typespeed="100"
data-typeit-lifelike="true"

@@ -55,28 +85,19 @@ data-typeit-showcursor="true">

or...
You can also define what to type a third way -- by simply filling the element with a string of text. This is convenient because if a user doesn't have JavaScript enabled, they'll still be able to read the text. **Note: by default, the plugin will use the string that's in the element. If strings are defined either in the function call or data attributes, they will be overridden.**
``
<span class="type-it"></span>
``
```
$('.type-it').typeIt({
whatToType:'Enter your string here!',
typeSpeed: 300,
lifeLike: false,
showCursor: true
});
```
<span class="type-it">This is the string that will be typed.</span>
```
### Typing Multiple Strings
Aside from simply typing a single string, you can configure TypeIt to type multiple strings. By default, they stack on top of each other. To use this feature, just enter an array of several strings.
Aside from simply typing a single string, you can configure TypeIt to type multiple strings. **Note: while you can define a single string by just putting it in quotation marks, multiple strings must be defined inside an array, like shown below.** By default, they stack on top of each other. To use this feature, just enter an array of several strings.
```
$('.type-it').typeIt({
whatToType:['Enter your string here!', 'Another string!']
whatToType: ['Enter your string here!', 'Another string!']
});
```
Or, you can have type strings that delete & replace each other. Do this, set the 'breakLines' setting to `false`.
Or, you can have type strings that delete & replace each other. To do this, set the 'breakLines' setting to `false`.

@@ -89,6 +110,22 @@ ```

```
### Handling HTML Tags
TypeIt will handle HTML tags in your strings, as long as they're only one level deep:
```
// GOOD! :)
$('.typeit-box').typeIt({
whatToType: '<h1 class="your-class">This is a string!</h1>',
}
```
```
// BAD! :(
$('.typeit-box').typeIt({
whatToType: '<h1 class="your-class"><span>This is a string!</span></h1>',
}
```
### Using a Callback Function
TypeIt allows you to use a custom callback function when you've completed typing. To use one, simply add it as the second argument when it's initialized.
TypeIt allows you to use a custom callback function when you've completed typing. To use one, simply add it as the second argument when it's initialized. **Note: if you've enabled `loop`, this is useless.**

@@ -101,3 +138,2 @@ ```

});
</script>
```

@@ -111,13 +147,15 @@

| ------------- | ------------- | ------------- |
| whatToType | The string to be typed. | 'This is the default string. Please replace this string with your own.' |
| typeSpeed | The typing speed. | 200 |
| whatToType | The string to be typed. | 'This is the default string. Replace it with your own.' |
| typeSpeed | The typing speed. | 100 |
| lifeLike | Will make the typing pace irregular, as if a real person is doing it. | true |
| showCursor | Show a blinking cursor at the end of the string. | true |
| breakLines | Choose whether you want multiple strings to be printed on top of each other (breakLines = true), or if you want each string to be deleted and replaced by the next one (breakLines = false). | true |
| breakWait | The amount of time between typing multiple strings. | 500 |
| delayStart | The amount of time before the plugin begins typing after initalizing. | 250 |
| breakDelay | The amount of time between typing multiple strings. | 750 |
| startDelay | The amount of time before the plugin begins typing after initalizing. | 250 |
| loop | Have your string or strings continuously loop after completing. | false |
| loopDelay | The amount of time between looping over a string or set of strings again. | 750 |
## Ideas for Improvement?
If you choose to develop it locally, Gulp is configured to check & minify JavaScript and compile & compress SASS. In the root of the repo, use these commands to run these default tasks and watch for file changes (make sure Node.js, npm, and Gulp are installed on your computer):
Let me know! Otherwise, if you choose to develop it locally, Gulp is configured to check & minify JavaScript and compile & compress SASS. In the root of the repo, use these commands to run these default tasks and watch for file changes (make sure Node.js, npm, and Gulp are installed on your computer):

@@ -128,1 +166,8 @@ ```

```
## Donate
If I've made your life eaiser in some way by creating this thing and want to kick a small "thank you" my way, I'd very much appreciate it!
PayPal: <a href="http://paypal.me/alexmacarthur">paypal.me/alexmacarthur</a>
Venmo: <a href="https://venmo.com/amacarthur">venmo.com/amacarthur</a>

@@ -1,56 +0,59 @@

$('.typeit-box').typeIt({
whatToType: ['A jQuery plugin that types stuff for you.'],
typeSpeed: 100
$('#typeit-box').typeIt({
whatToType: ['A jQuery plugin that <span class="emphasized">types</span> stuff for you.', '<span class="emphasized emphasized-duh">(Duh.)</span>'],
typeSpeed: 100,
breakLines: true,
breakDelay: 1000
});
$('.example1').typeIt({
whatToType: "You've just initialized this bad boy.",
typeSpeed: 100
});
var $example1 = $('#example1');
var $example2 = $('#example2');
var $example3 = $('#example3');
var $example4 = $('#example4');
var $example5 = $('#example5');
var $example6 = $('#example6');
$('section').on('click','.btn-example1',function() {
$('.example1').data().typeit.stopTyping();
$('.example1').html('');
$('.example1').typeIt({
whatToType: "You've just initialized this bad boy.",
function example4() {
$example4.typeIt({
whatToType: ["This is a string!", "And here's another one."],
typeSpeed: 100
});
});
}
$('.example2').typeIt();
example4();
$('section').on('click','.btn-example2',function() {
$('.example2').data().typeit.stopTyping();
$('.example2').html('');
$('.example2').typeIt();
$('section').on('click','#btn-example4',function() {
$example4.data('typeit').stop();
$example4.html('');
example4();
});
$('.example3').typeIt({
whatToType: ["This is a string!", "And here's another one."],
typeSpeed: 100
function example5() {
$example5.typeIt({
whatToType: ["This is a great string.","But here is a better one."],
typeSpeed: 100,
breakLines: false
});
}
example5();
$('section').on('click','#btn-example5',function() {
$example5.data('typeit').stop();
$example5.html('');
example5();
});
$('section').on('click','.btn-example3',function() {
$('.example3').data().typeit.stopTyping();
$('.example3').html('');
$('.example3').typeIt({
whatToType: ["This is a string!", "And here's another one."],
function example6() {
$example6.typeIt({
whatToType: ["Here's text <span class='just-a-class'>wrapped in HTML</span>."],
typeSpeed: 100
});
});
}
$('.example4').typeIt({
whatToType: ["This is a great string.", "But here is a better one."],
typeSpeed: 100,
breakLines: false
});
example6();
$('section').on('click','.btn-example4',function() {
$('.example4').data().typeit.stopTyping();
$('.example4').html('');
$('.example4').typeIt({
whatToType: ["This is a great string.", "But here is a better one."],
typeSpeed: 100,
breakLines: false
});
$('section').on('click','#btn-example6', function() {
$example6.data('typeit').stop();
$example6.html('');
example6();
});

@@ -61,4 +64,4 @@

$('#iTypeSpeed').val('250');
$('#iBreakWait').val('500');
$('#iDelayStart').val('250');
$('#ibreakDelay').val('500');
$('#istartDelay').val('250');

@@ -71,3 +74,3 @@ $('#TIInput').on('click','#TISubmit', function(e){

if($.hasData($(this))) {
$(this).data().typeit.stopTyping();
$(this).data('typeit').stop();
}

@@ -111,8 +114,8 @@ $('#TIOutput').html('');

}
var breakWait = $('#iBreakWait').val();
var breakDelay = $('#ibreakDelay').val();
var breakStart = $('#iBreakStart').val();
var delayStart = $('#iDelayStart').val();
var startDelay = $('#istartDelay').val();
// hide the temp text
$('.temp-text').animate({
$('#tempText').animate({
opacity: 0

@@ -122,3 +125,3 @@ });

// expand the container
$('.ti-output-box').animate({
$('#TIOutputBox').animate({
height: newHeight

@@ -128,3 +131,3 @@ }, function() {

$('html, body').animate({
scrollTop: $(".ti-output-box").offset().top - 200
scrollTop: $("#TIOutputBox").offset().top - 200
}, 800);

@@ -139,5 +142,4 @@

breakLines: breakLines,
breakWait: breakWait,
breakStart: breakStart,
delayStart: delayStart
breakDelay: breakDelay,
startDelay: startDelay
});

@@ -144,0 +146,0 @@ }, 800);

@@ -1,1 +0,161 @@

$(".typeit-box").typeIt({whatToType:["A jQuery plugin that types stuff for you."],typeSpeed:100}),$(".example1").typeIt({whatToType:"You've just initialized this bad boy.",typeSpeed:100}),$("section").on("click",".btn-example1",function(){$(".example1").data().typeit.stopTyping(),$(".example1").html(""),$(".example1").typeIt({whatToType:"You've just initialized this bad boy.",typeSpeed:100})}),$(".example2").typeIt(),$("section").on("click",".btn-example2",function(){$(".example2").data().typeit.stopTyping(),$(".example2").html(""),$(".example2").typeIt()}),$(".example3").typeIt({whatToType:["This is a string!","And here's another one."],typeSpeed:100}),$("section").on("click",".btn-example3",function(){$(".example3").data().typeit.stopTyping(),$(".example3").html(""),$(".example3").typeIt({whatToType:["This is a string!","And here's another one."],typeSpeed:100})}),$(".example4").typeIt({whatToType:["This is a great string.","But here is a better one."],typeSpeed:100,breakLines:!1}),$("section").on("click",".btn-example4",function(){$(".example4").data().typeit.stopTyping(),$(".example4").html(""),$(".example4").typeIt({whatToType:["This is a great string.","But here is a better one."],typeSpeed:100,breakLines:!1})}),function(){$("#iTypeSpeed").val("250"),$("#iBreakWait").val("500"),$("#iDelayStart").val("250"),$("#TIInput").on("click","#TISubmit",function(e){e.preventDefault(),$.hasData($(this))&&$(this).data().typeit.stopTyping(),$("#TIOutput").html("");var t,a=[];if(""===$("#stringTI").val())a="You didn't enter a string!";else{t=$("#stringTI").val().split("\n");for(var i=0;i<t.length;i++)void 0!==t[i]&&null!==t[i]&&""!==t[i]&&a.push(t[i])}var p=$("#stringTI").val()?38*a.length+40:75,n=$("#iTypeSpeed").val(),o=$("#iLifeLike").val();o="true"===o?!0:!1;var l=$("#iShowCursor").val();l="true"===l?!0:!1;var s=$("#iBreakLines").val();s="true"===s?!0:!1;var r=$("#iBreakWait").val(),h=$("#iBreakStart").val(),y=$("#iDelayStart").val();$(".temp-text").animate({opacity:0}),$(".ti-output-box").animate({height:p},function(){$("html, body").animate({scrollTop:$(".ti-output-box").offset().top-200},800),setTimeout(function(){$("#TIOutput").typeIt({whatToType:a,typeSpeed:n,lifeLike:o,showCursor:l,breakLines:s,breakWait:r,breakStart:h,delayStart:y})},800)})})}(),$(function(){$("a[href*=#]:not([href=#])").click(function(){if(location.pathname.replace(/^\//,"")==this.pathname.replace(/^\//,"")&&location.hostname==this.hostname){var e=$(this.hash);if(e=e.length?e:$("[name="+this.hash.slice(1)+"]"),e.length)return $("html,body").animate({scrollTop:e.offset().top},1e3),!1}})});
$('#typeit-box').typeIt({
whatToType: ['A jQuery plugin that <span class="emphasized">types</span> stuff for you.', '<span class="emphasized emphasized-duh">(Duh.)</span>'],
typeSpeed: 100,
breakLines: true,
breakDelay: 1000
});
var $example1 = $('#example1');
var $example2 = $('#example2');
var $example3 = $('#example3');
var $example4 = $('#example4');
var $example5 = $('#example5');
var $example6 = $('#example6');
function example4() {
$example4.typeIt({
whatToType: ["This is a string!", "And here's another one."],
typeSpeed: 100
});
}
example4();
$('section').on('click','#btn-example4',function() {
$example4.data('typeit').stop();
$example4.html('');
example4();
});
function example5() {
$example5.typeIt({
whatToType: ["This is a great string.","But here is a better one."],
typeSpeed: 100,
breakLines: false
});
}
example5();
$('section').on('click','#btn-example5',function() {
$example5.data('typeit').stop();
$example5.html('');
example5();
});
function example6() {
$example6.typeIt({
whatToType: ["Here's text <span class='just-a-class'>wrapped in HTML</span>."],
typeSpeed: 100
});
}
example6();
$('section').on('click','#btn-example6', function() {
$example6.data('typeit').stop();
$example6.html('');
example6();
});
(function() {
$('#iTypeSpeed').val('250');
$('#ibreakDelay').val('500');
$('#istartDelay').val('250');
$('#TIInput').on('click','#TISubmit', function(e){
e.preventDefault();
// if there's another process going on, stop it and wipe the output box
if($.hasData($(this))) {
$(this).data('typeit').stop();
}
$('#TIOutput').html('');
// get variables figured out
var whatToType;
var cleanedWhatToType = [];
if($('#stringTI').val() === '') {
cleanedWhatToType = 'You didn\'t enter a string!';
} else {
whatToType = $('#stringTI').val().split('\n');
// remove empty array item
for (var i = 0; i < whatToType.length; i++) {
if (whatToType[i] !== undefined && whatToType[i] !== null && whatToType[i] !== "") {
cleanedWhatToType.push(whatToType[i]);
}
}
}
var newHeight = ($('#stringTI').val()) ? (cleanedWhatToType.length * 38) + 40 : 75;
var typeSpeed = $('#iTypeSpeed').val();
var lifeLike = $('#iLifeLike').val();
if(lifeLike === 'true'){
lifeLike = true;
} else {
lifeLike = false;
}
var showCursor = $('#iShowCursor').val();
if(showCursor === 'true'){
showCursor = true;
} else {
showCursor = false;
}
var breakLines = $('#iBreakLines').val();
if(breakLines === 'true'){
breakLines = true;
} else {
breakLines = false;
}
var breakDelay = $('#ibreakDelay').val();
var breakStart = $('#iBreakStart').val();
var startDelay = $('#istartDelay').val();
// hide the temp text
$('#tempText').animate({
opacity: 0
});
// expand the container
$('#TIOutputBox').animate({
height: newHeight
}, function() {
$('html, body').animate({
scrollTop: $("#TIOutputBox").offset().top - 200
}, 800);
setTimeout(function() {
$('#TIOutput').typeIt({
whatToType: cleanedWhatToType,
typeSpeed: typeSpeed,
lifeLike: lifeLike,
showCursor: showCursor,
breakLines: breakLines,
breakDelay: breakDelay,
startDelay: startDelay
});
}, 800);
});
});
})();
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
/**
* jQuery TypeIt
* @author Alex MacArthur (http://macarthur.me)
* @version 1.1.1
* @version 2.0.0
* @copyright 2015 Alex MacArthur

@@ -23,21 +23,29 @@ * @description Types out a given string or strings.

$.fn.typeIt.typeItClass = function(theElement, options, callback){
// plugin default settings
/* VARIABLES THAT WON'T CHANGE BETWEEN RUNS */
// default settings
this.defaults = {
whatToType:'This is the default string. Please replace this string with your own.',
typeSpeed: 200,
lifeLike: false,
showCursor: true,
breakLines: true,
breakWait: 500,
delayStart: 250
whatToType:'You probably want to use your own string.',
typeSpeed: 100,
lifeLike: true,
showCursor: true,
breakLines: true,
breakDelay: 750,
startDelay: 250,
loop: false,
loopDelay: 750
};
// data-typeit-* settings
this.dataAttDefaults = {
whatToType : theElement.data('typeitWhattotype'),
typeSpeed: theElement.data('typeitSpeed'),
whatToType: theElement.data('typeitWhattotype'),
typeSpeed: theElement.data('typeitTypespeed'),
lifeLike: theElement.data('typeitLifelike'),
showCursor: theElement.data('typeitShowcursor'),
breakLines: theElement.data('typeitBreaklines'),
breakWait: theElement.data('typeitBreakWait'),
delayStart : theElement.data('typeitDelayStart')
breakDelay: theElement.data('typeitBreakdelay'),
startDelay: theElement.data('typeitStartdelay'),
loop: theElement.data('typeitLoop'),
loopDelay: theElement.data('typeitLoopdelay')
};

@@ -47,2 +55,4 @@

this.settings = {};
// merge settings into this.settings object
$.extend(this.settings, this.defaults, options, this.dataAttDefaults);
// the element that holds the text

@@ -52,8 +62,11 @@ this.theElement = theElement;

this.callback = callback;
// the number of types a character has been typed for each pass over a string
this.typeCount = 0;
// the character number of a string that's currently being deleted
this.deleteCount = 0;
// the string number that's currently being typed or deleted
this.stringCount = 0;
// let 'r rip
this.init(options);
};
// create a new prototype
_proto = $.fn.typeIt.typeItClass.prototype;
_proto.init = function(options){
// the place we're at in the big merged string

@@ -65,23 +78,42 @@ this.stringPlaceCount = 0;

this.stringArray = [];
// the index of the string we're handling
this.stringArrayIndex = 0;
// the index of the character we're currently printing
this.stringArrayCharacterIndex = 0;
// hold where we need to replace characters because of HTML tags
this.contentStartEnd = [];
// the index for the string within an HTML tag
this.contentStartEndIndex = 0;
// the span of characters for the string inside an HTML tag
this.contentStartEndSpan = 0;
// holds whether we're currently printing inside HTML tags
this.printingInTag = false;
// the specific character we're currently appending
this.characterToAppend = null;
// the current ti-text-container we're dealing
this.thisTiTextContainer = null;
// the current string we're handling
this.thisString = null;
// the particular HTML tag we're handling
this.thisTag = null;
// array holding the length of each string
this.stringLengths = [];
// the string we're currently deleting
this.stringToDelete = null;
// the timeout responsible for typing/adding characters
this.typeTimeout = null;
// the timeout responsible for deleting characters
this.deleteTimeout = null;
// the timeout responsible for typing/adding characters
this.typeTimeout = null;
// the progressively shorter string as it's being deleted
this.shortenedText = null;
// let 'r rip
this.init(options);
};
// the span of the range a type speed is allowed to be randomized
this.typeSpeedRangeSpan = null;
// the minimum of a randomized type speed
this.typeSpeedMin = null;
// the maximum of a randomized type speed
this.typeSpeedMax = null;
// create a new prototype
_proto = $.fn.typeIt.typeItClass.prototype;
_proto.init = function(options){
// make sure the callback function is all good
if(this.validateCallbackFunction() === false){ return false; }
// merge settings into this.settings object
$.extend(this.settings, this.defaults, options, this.dataAttDefaults);
// string override
this.testForElementStringOverride();
// process the whatToType data to get it so we can use it

@@ -94,7 +126,20 @@ this.processWhatToType();

this.typeLoop();
}.bind(this), this.settings.delayStart);
}.bind(this), this.settings.startDelay);
};
_proto.testForElementStringOverride = function() {
// if there's a string already typed in the element, replace whatToType with it
if(this.theElement.text().length > 0 && !this.theElement.has('.ti-container')) {
this.settings.whatToType = this.theElement.html();
}
};
_proto.setupDOMComponents = function() {
// clear out the element in case we're looping
this.theElement.html('');
// get the string lengths and save to array, set up ti-containers for each string

@@ -123,13 +168,71 @@ for(j=0; j < this.stringArray.length; j++){

_proto.processWhatToType = function() {
this.stringArray = this.settings.whatToType;
// check if the value is an array or just a string
if(Object.prototype.toString.call(this.stringArray) !== '[object Array]'){
// since it's not already an array, turn it into one, since later functionality depends on it being one
this.stringArray = '["' + this.stringArray + '"]';
this.stringArray = JSON.parse(this.stringArray);
// check if the value is an array or just a string
if(Object.prototype.toString.call(this.settings.whatToType) !== '[object Array]'){
// since it's not already an array, turn it into one, since later functionality depends on it being one
this.stringArray = '["' + this.settings.whatToType + '"]';
this.stringArray = JSON.parse(this.stringArray);
// if it is an array, clone it
} else {
// clone what to typed, so we don't modify the original strings in case we loop
this.stringArrayTemp = $.extend( {}, this.settings.whatToType );
// convert cloned object to array
this.stringArrayTemp = $.map(this.stringArrayTemp, function(value, index) {
return [value];
});
// get the right values and put into stringArray so it's formatted correctly for processing
for(var h = 0; h < this.stringArrayTemp.length; h++) {
this.stringArray.push(this.stringArrayTemp[h]);
}
// turn string array into a big string
this.mergedStrings = this.stringArray.join('');
};
}
// turn each string into sub arrays
for(var i = 0; i < this.stringArray.length; i++) {
this.contentStartEnd = [];
this.contentStartEndIndex = 0;
this.contentStartEndSpan = 0;
// turn each string into sub array
this.stringArray[i] = this.stringArray[i].split('');
// find the location of HTML tag
for(var j = 0, subArray = this.stringArray[i]; j < subArray.length; j++) {
if(subArray[j] === '<') {
this.contentStartEnd[this.contentStartEndIndex] = [];
this.contentStartEnd[this.contentStartEndIndex][0] = j;
}
if(subArray[j] === '>') {
this.contentStartEnd[this.contentStartEndIndex][1] = j;
this.contentStartEndIndex++;
}
}
// merge individual tag characters into single array index
for(var positionIndex = 0; positionIndex < this.contentStartEnd.length; positionIndex++) {
// move those tag pieces into a single array item
for (var l = this.contentStartEnd[positionIndex][0]; l < this.contentStartEnd[positionIndex][1]; l++) {
this.stringArray[i][this.contentStartEnd[positionIndex][0]] = this.stringArray[i][this.contentStartEnd[positionIndex][0]] + this.stringArray[i][l+1];
}
}
// cut array items based on the start/end positions we know, but move back the start point each time by the number of items we previously removed
for( var m = 0; m < this.contentStartEnd.length; m++ ) {
var startPos = this.contentStartEnd[m][0]+1;
this.stringArray[i].splice(startPos, this.contentStartEnd[m][1] - this.contentStartEnd[m][0]);
var span = this.contentStartEnd[m][1] - this.contentStartEnd[m][0];
// go through and update the start and positions by the span length we just cut
for(var n = 0; n < this.contentStartEnd.length; n++) {
this.contentStartEnd[n][0] = this.contentStartEnd[n][0] - span;
this.contentStartEnd[n][1] = this.contentStartEnd[n][1] - span;
}
}
}
};
_proto.validateCallbackFunction = function() {

@@ -144,50 +247,92 @@

_proto.typeLoop = function(){
// set the length of the current phrase being typed
this.phraseLength = this.stringLengths[this.stringCount];
// make it human-like if specified in the settings
_proto.randomizeTypeSpeed = function() {
// make it human-like if specified in the settings
if(this.settings.lifeLike === true){
this.delayTime = this.settings.typeSpeed*Math.random();
// set to 50% of the actual type speed, so the randomization goes no further than that ratio
this.typeSpeedRangeSpan = this.settings.typeSpeed/2;
this.typeSpeedMin = this.settings.typeSpeed-this.typeSpeedRangeSpan;
this.typeSpeedMax = this.settings.typeSpeed+this.typeSpeedRangeSpan;
this.delayTime = Math.abs(Math.random() * (this.typeSpeedMax - this.typeSpeedMin) + this.typeSpeedMin);
} else {
this.delayTime = this.settings.typeSpeed;
}
};
_proto.typeLoop = function(){
// get this particular string we're printing
this.thisString = this.stringArray[this.stringArrayIndex];
// set the length of the current phrase being typed
this.phraseLength = this.thisString.length;
// start the typing timeout
this.typeTimeout = setTimeout(function () {
// append the string of letters to the respective .ti-text-container
var characterToAppend = this.mergedStrings[this.typeCount+this.stringPlaceCount];
this.randomizeTypeSpeed();
// if breakLines is set to true, add the 'active-container' class to the next .ti-text-container in the list.
if(this.settings.breakLines === true) {
this.theElement.find('.ti-text-container:eq('+ this.stringCount +')').addClass('active-container').append(characterToAppend);
} else {
this.theElement.find('.ti-text-container').addClass('active-container').append(characterToAppend);
// the the specific character we're printing
this.characterToAppend = this.stringArray[this.stringArrayIndex][this.stringArrayCharacterIndex];
// if it's an HTML tag, do stuff
if(this.characterToAppend.indexOf('<') !== -1 && this.characterToAppend.indexOf('</') === -1){
this.contentStartEndIndex = 0;
// get the start & end positions of the actual string within the HTML tags
this.contentStartEnd[0] = this.stringArrayCharacterIndex + 1;
for(var t = this.stringArrayCharacterIndex; t < this.thisString.length; t++){
if(this.thisString[t].indexOf('</') !== -1) {
// set the ending of the string segment in an HTML tag
this.contentStartEnd[1] = t - 1;
// as soon as we hit a match for a closing character
break;
}
}
this.contentStartEndSpan = this.contentStartEnd[1] - this.contentStartEnd[0];
// create a DOM node from the string we get
this.thisTag = $($.parseHTML(this.characterToAppend));
// set the current character to append to the tag we just created, so that we can create it in the DOM
this.characterToAppend = this.thisTag;
// append the tag
this.appendTheCharacter();
// set this to true so we know we're currently printing inside an HTML tag
this.printingInTag = true;
}
this.typeCount++;
// if there are still characters to be typed, call the same function again
if (this.typeCount < this.phraseLength) {
this.typeLoop(this.stringLengths[this.stringCount]);
// if there are no more characters to print and there is more than one string to be typed, delete the string just printed
this.appendTheCharacter();
this.stringArrayCharacterIndex++;
// there are still characters to be typed, so repeat function
if (this.stringArrayCharacterIndex < this.phraseLength) {
this.typeLoop();
// there are no more characters to print and there is more than one string to be typed, so delete the string just printed
} else if(this.stringArray.length > 1) {
// reset this.stringArrayCharacterIndex since we're done using it for this string
this.stringArrayCharacterIndex = 0;
// update the this.stringPlaceCount so that we're appending starting at the correct spot in the merged string
this.stringPlaceCount = this.stringPlaceCount + this.phraseLength;
// reset this.typeCount in case this function needs to be reused
this.typeCount = 0;
// if the stringCount is the same as the number of strings we started with, we're done, so call the callback function
if(this.stringCount+1 === this.stringArray.length) {
this.callback();
// if the this.stringArrayIndex is the same as the number of strings we started with, we're done, so call the callback function
if(this.stringArrayIndex + 1 === this.stringArray.length) {
// multiple strings ending
this.endOfStringsFork();
// if we're not on the last string, then move on to to delete, unless the user wants to break lines
} else if((this.stringCount+1 < this.stringArray.length) && this.settings.breakLines === false){
} else if((this.stringArrayIndex + 1 < this.stringArray.length) && this.settings.breakLines === false){
setTimeout(function(){
this.deleteLoop();
}.bind(this), this.settings.breakWait);
}.bind(this), this.settings.breakDelay);
// if breakLines is true and we still have strings left to type, break it and continue
} else if (this.stringCount+1 < this.stringArray.length && this.settings.breakLines === true){
this.stringCount++;
// if breakLines is true and we still have strings left to type, break it and continue with the next string
} else if (this.stringArrayIndex + 1 < this.stringArray.length && this.settings.breakLines === true){
// before starting the next string, make sure the index has been bumped up
this.stringArrayIndex++;

@@ -200,3 +345,3 @@ setTimeout(function(){

// give 'active-container' class to next container, so the cursor can start blinking
this.theElement.find('.ti-text-container:eq('+ this.stringCount +')').addClass('active-container');
this.theElement.find('.ti-text-container:eq('+ this.stringArrayIndex +')').addClass('active-container');

@@ -206,5 +351,5 @@ // after another slight delay, continue typing the next string

this.typeLoop();
}.bind(this), this.settings.breakWait);
}.bind(this), this.settings.breakDelay);
}.bind(this), this.settings.breakWait);
}.bind(this), this.settings.breakDelay);

@@ -215,4 +360,6 @@ }

} else {
this.callback();
// single string ending
this.endOfStringsFork();
}
}.bind(this), this.delayTime);

@@ -222,32 +369,135 @@

_proto.deleteLoop = function() {
_proto.endOfStringsFork = function() {
if(this.settings.loop === true){
// delete the remaining string
setTimeout(function(){
this.deleteLoop();
}.bind(this), this.settings.loopDelay);
} else {
this.callback();
}
};
_proto.appendTheCharacter = function() {
// if breakLines is set to true, add the 'active-container' class to the next .ti-text-container in the list.
if(this.settings.breakLines === true) {
this.thisTiTextContainer = this.theElement.find('.ti-text-container:eq('+ this.stringArrayIndex +')');
this.thisTiTextContainer.addClass('active-container');
} else {
this.thisTiTextContainer = this.theElement.find('.ti-text-container');
this.thisTiTextContainer.addClass('active-container');
}
// append the character to the HTML tag if we're printing in a tag, or else just append the character
this.appendToHTMLTag(function(){
this.thisTiTextContainer.append(this.characterToAppend);
}.bind(this));
};
_proto.appendToHTMLTag = function(notInTagFunction) {
if(this.printingInTag === true) {
// resave the character to append
this.characterToAppend = this.thisString[this.contentStartEnd[0] + this.contentStartEndIndex];
// append to the latest tag (the one we just printed) in the element
$(this.thisTag, this.theElement).last().append(this.characterToAppend);
// if we're at the end of the string segment, turn off printingInTag
this.printingInTag = (this.contentStartEnd[1] === this.contentStartEnd[0] + this.contentStartEndIndex - 1) ? false : true;
this.contentStartEndIndex++;
} else {
notInTagFunction();
}
};
_proto.deleteLoop = function(undefined) {
// set the current ti-text-container
this.thisTiTextContainer = this.theElement.find('.ti-text-container');
this.deleteTimeout = setTimeout(function () {
// get the string from the element and cut it by one character at the end
shortenedText = this.theElement.find('.ti-text-container').text().substring(0, this.theElement.find('.ti-text-container').text().length - 1);
// randomize the delete speed, if applicable
this.randomizeTypeSpeed();
// then, put that shortened text into the element so it looks like it's being deleted
this.theElement.find('.ti-text-container').text(shortenedText);
// get the string
this.stringToDelete = this.thisTiTextContainer.last().html();
this.deleteCount++;
// if there are still characters in the string, run the function again
if (this.deleteCount < this.phraseLength) {
this.deleteLoop();
// convert to array
this.arrayToDelete = this.stringToDelete.split("");
// loop over array
for (var n = this.arrayToDelete.length-1; n > -1; n--) {
// TAG HANDLING
if(this.arrayToDelete[n] === '>') {
// find the beginning tag piece
for(var o = n-1; o > -1; o--) {
// find the opening piece
// o = position of opening piece
if(this.arrayToDelete[o] === '<') {
// if the next piece before it isn't an HTML tag, just delete the text in between
if(this.arrayToDelete[o-1] !== '>') {
// remove character right before HTML tag begins and escape the loop
this.arrayToDelete.splice(o-1, 1);
break;
}
}
}
break;
}
// REGULAR CHARACTER HANDLING
else {
// remove the character and escape the loop
this.arrayToDelete.splice(n, 1);
break;
}
}
// repopulate the element with the shortened string so it looks like it's being deleted
this.thisTiTextContainer.last().html(this.arrayToDelete.join(''));
// if nothing left, clear out the emtpy HTML tags
if(this.thisTiTextContainer.last().text().length === 0){
this.thisTiTextContainer.last().html('');
}
// if characters are still in the string, run the function again
if (this.thisTiTextContainer.last().text().length > 0) {
this.deleteLoop();
// if there are still strings in the array, go back to typing.
} else if(this.stringArray[this.stringCount+1] !== undefined){
this.deleteCount = 0;
this.stringCount++;
this.typeLoop();
}
} else if(this.stringArray[this.stringArrayIndex+1] !== undefined){
this.stringArrayIndex++;
this.typeLoop();
// that was the last string in the array, so now just check if loop is enabled
} else if (this.settings.loop === true){
// if there are multiple strings that have been typed, remove the current one and repeat deleteLoop
if(this.thisTiTextContainer.length > 1) {
// remove the current container so we don't fill it with junk
this.thisTiTextContainer.last().remove();
// make sure the NEW last container has 'active-container' status
// need to use find() again instead of stored selection because that stored selection is now outdated since we just removed a container
this.theElement.find('.ti-text-container').last().addClass('active-container');
this.deleteLoop();
} else {
// otherwise, re-run the whole thing again
this.init();
}
}
// make backspacing much quicker by dividing delayTime (arbitrarily) by three
}.bind(this), this.delayTime/3);
};
}.bind(this), this.delayTime/3);
};
// stop the plugin from typing or deleting stuff whenever it's called
_proto.stopTyping = function() {
// stop the plugin from typing or deleting stuff whenever it's called
_proto.stop = function() {
clearTimeout(this.typeTimeout);
clearTimeout(this.deleteTimeout);
};
};
}(jQuery));

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc