Reputation: 7207
I've been looking around the web for like 5 hours by now, and I can't find any solution to my problem which is: I wrote a plugin which makes the typing effect on any given element and it works perfectly ONLY if I use it on one element, but when I want to use it on the second element, it only does the second one and here is why: in my plugin I used some "setInterval"s to do typing with specific speed and checking the letters in order to delay on some certain letters, the problem occurs when I call the plugin twice or more simultaneously which sets the new values to the variables and collides the intervals with the newly set values and messes everything up.
here is the code:
(function ($) {
//typing effect for text
$.fn.typingText = function (options) {
var setting = $.extend({
//the starting point ==> *(it starts typing when the scrollbar hit the starting point)
start: 0,
//the user given delay character ==> *(it delays the typing when it hits this character) ==> *(must be a character not a digit or alphabet)
delayChar: '.',
//the speed of typer ==> *(must be at least 50)
speed: 100,
//the delay duration when it hits delaying characters ==> *(delaying characters are ? ! . and any other given character in delayChar variable)
delay: 500
}, options);
if (setting.speed < 50) {
setting.speed = 50;
}
if (setting.delay < 100) {
setting.delay = 100;
}
setting.delayChar = setting.delayChar.slice(0, 1);
window.that = $(this);
if ($(document).scrollTop() >= setting.start) {
$(this).css('display', 'block');
window.text = $(this).text();
window.textLength = window.text.length;
window.char = 0;
setting.delayChar = '^\\' + setting.delayChar;
$(this).text('');
$(this).html('<span class="textLine"></span>');
$(this).append('<span class="blinkingLine">|</span>');
window.blinking = setInterval(function () {
$('.blinkingLine').animate({
opacity: 0
}, 300);
setTimeout(function () {
$('.blinkingLine').animate({
opacity: 1
}, 300);
}, 300);
}, 600);
function type() {
window.that.children('.textLine').text(window.text.substr(0, window.char));
window.lastChar = window.that.children('.textLine').text().slice(window.that.children('.textLine').text().length - 1);
window.char++;
if (window.char > window.textLength) {
window.that.children('.textLine').text(window.that.children('.textLine').text().substr(0, window.textLength));
$('.blinkingLine').remove();
clearInterval(window.startTyping);
clearInterval(window.blinking);
clearInterval(window.checking);
}
}
window.timer = 0;
window.startTyping = setInterval(type, setting.speed);
window.checking = setInterval(function () {
if (!window.delaying || typeof window.delaying == 'undefined' || window.timer >= setting.delay) {
if (window.lastChar.match('^\\?') || window.lastChar.match('^\\.') || window.lastChar.match('^\\!') || window.lastChar.match(setting.delayChar)) {
if (window.timer >= setting.delay) {
window.timer = 0;
window.char++;
type();
window.startTyping = setInterval(type, setting.speed);
window.delaying = false;
} else {
window.delaying = true;
clearInterval(window.startTyping);
window.startTyping = null;
}
}
} else {
window.timer = window.timer + 50;
}
}, 50);
}
};
})(jQuery);
$(function () {
$('#title').typingText();
$('#title2').typingText();
});
here is the jsFiddle to see the code and the problem.
I know it has to do something with my approach of writing the plugin, but I tried several suggestions on the web such as object oriented plugin writing but still couldn't come up with the solution! any help or suggestion would be appreciated.
Upvotes: 1
Views: 130
Reputation: 7207
found the answer myself, the thing was that I had to define all my variables and intervals as a private variable or function so they wouldn't get overwritten, and then I had to add a little piece of code to make my function repeat itself through all the selected elements.
this is the final code I ended up with which works perfectly.
check out this jsFiddle
(function($){
//typing effect for text
//start of the plugin
var typingTextFunc= function(options, elem){
var setting= $.extend({
//the starting point
//*(it starts typing when the scrollbar hit the starting point)
start:0,
//the user given delay character
//*(it delays the typing when it hits elem character) ==> *(must be a character not a digit or alphabet)
delayChar:'.',
//the speed of typer
//*(must be at least 50)
speed:100,
//the delay duration when it hits delaying characters
//*(delaying characters are ? ! . and any other given character in delayChar variable)
delay:500
},options);
if(setting.speed<50){
setting.speed=50;
}
if(setting.delay<100){
setting.delay=100;
}
setting.delayChar=setting.delayChar.slice(0,1);
var that=$(elem);
if($(document).scrollTop()>=setting.start){
$(elem).css('display','block');
var text=$(elem).text();
var textLength=text.length;
var char=0;
$(elem).text('');
$(elem).html('<span class="textLine"></span>');
$(elem).append('<span class="blinkingLine">|</span>');
var blinking=setInterval(function(){
that.children('.blinkingLine').animate({opacity:0},300);
setTimeout(function(){
that.children('.blinkingLine').animate({opacity:1},300);
},300);
},600);
var lastChar='';
function type(){
that.children('.textLine').text(text.substr(0,char));
lastChar=that.children('.textLine').text().slice(that.children('.textLine').text().length-1);
char++;
if(char>textLength){
that.children('.textLine').text(that.children('.textLine').text().substr(0,textLength));
that.children('.blinkingLine').remove();
clearInterval(startTyping);
clearInterval(blinking);
clearInterval(checking);
}
}
var timer=0;
var delaying=false;
var startTyping=setInterval(type,setting.speed);
var checking= setInterval(function(){
if(typeof delaying=='undefined' || timer>=setting.delay || delaying==false){
if(lastChar=='?' || lastChar=='.' || lastChar=='!' || lastChar==setting.delayChar){
if(timer>=setting.delay){
timer=0;
char++;
type();
startTyping=setInterval(type,setting.speed);
delaying=false;
}
else{
delaying=true;
clearInterval(startTyping);
startTyping=null;
}
}
}
else{
timer=timer+50;
}
},50);
}
};
$.fn.typingText= function(options){
if($(this).data('typed')) return;
return $(this).each(function(){
typingTextFunc(options, this);
$(this).data('typed',true);
});
};
//end of the plugin
}(jQuery));
$(function(){
$('#title1').typingText();
$('#title2').typingText();
});
Upvotes: 2