This is my first time coding in JQuery. Below is my code:
var div = document.getElementById('fadeletters1'),
letters = div.textContent.split('');
while(div.hasChildNodes()) div.removeChild(div.firstChild);
for(var i = 0; i < letters.length; i++) {
var letter = document.createElement('span'),
style = 'opacity ' + (Math.random() * 5 + 1) + 's linear';
letter.appendChild(document.createTextNode(letters[i]));
letter.style.WebKitTransition = letter.style.transition = style;
letter.style.opacity = 0;
div.appendChild(letter);
}
setTimeout(function() {
for(var i = 0; i < div.childNodes.length; i++) {
div.childNodes[i].style.opacity = 1;
}
}, 0);
<div id=fadeletters1>Helllooo This is a test for the website</div>
So the letters do fade in but then in the starting of the animation, letter are kinda visible and then fades in after couple seconds. I want it to pop up from 0 visibility to 100 visibility as its fades in.
I am trying to acheive something like this site does: http://method.digital/
You're changing the rate at which the transition takes place, instead you want to change the delay before the transition starting:
var div = document.getElementById('fadeletters1'),
letters = div.textContent.split('');
while(div.hasChildNodes()) div.removeChild(div.firstChild);
for(var i = 0; i < letters.length; i++) {
var letter = document.createElement('span'),
style = 'opacity 0.6s linear',
delay = (Math.random() * 4) + 's';
letter.appendChild(document.createTextNode(letters[i]));
letter.style.WebKitTransition = letter.style.transition = style;
letter.style.WebKitTransitionDelay = letter.style.transitionDelay = delay;
letter.style.opacity = 0;
div.appendChild(letter);
}
setTimeout(function() {
for(var i = 0; i < div.childNodes.length; i++) {
div.childNodes[i].style.opacity = 1;
}
}, 0);
<div id=fadeletters1>Helllooo This is a test for the website</div>
If you want to run it for multiple divs you can wait until the first is complete before moving onto the next (this example only appears to work sometimes, make sure to hit refresh before running):
function RunAnimation(target,delay) {
var div = document.getElementById(target),
letters = div.textContent.split('');
while (div.hasChildNodes()) div.removeChild(div.firstChild);
setTimeout(function(){
for (var i = 0; i < letters.length; i++) {
var letter = document.createElement('span'),
style = 'opacity 0.6s linear',
delay = (Math.random() * 4) + 's';
letter.appendChild(document.createTextNode(letters[i]));
letter.style.WebKitTransition = letter.style.transition = style;
letter.style.WebKitTransitionDelay = letter.style.transitionDelay = delay;
letter.style.opacity = 0;
div.appendChild(letter);
}
setTimeout(function() {
for (var i = 0; i < div.childNodes.length; i++) {
div.childNodes[i].style.opacity = 1;
}
}, 0);
}, delay);
}
RunAnimation('fadeletters1')
RunAnimation('fadeletters2', 5000);
RunAnimation('fadeletters3', 10000);
<div id="fadeletters1">Helllooo This is a test for the website</div>
<div id="fadeletters2">This is a second div which also fades in</div>
<div id="fadeletters3">And who knows maybe you want a third</div>
The thing is there is two delays...
One for the animation and one for a timeout. This is the timeout that really gives the effect you are looking for.
// Get the letters from the original string.
var letters = $("#fadeletters1").text().split("");
// Remove the original string.
$("#fadeletters1").text("");
// Create a span for each letters and append them to the document.
letters.forEach(function(item,index){
var span = $("<span class='fade'>").text(item);
$("#fadeletters1").append(span);
});
// Animate each spans
$(document).find(".fade").each(function(){
// Random delay
var delay = Math.random();
var letter = $(this);
// Set a timeout to animate the spans
setTimeout(function(){
letter.animate({"opacity":1},delay*1000);
},delay*3000);
});
.fade{
opacity:0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fadeletters1">Helllooo This is a test for the website</div>
Related
So I currently have some javascript code that creates a "typing" effect. During the typing, there is a caret at the end that mimics the caret type when typing into a console. When the typing has finished, I'd like for the caret to begin blinking, just as it would within a console. Here is the code used for it:
html:
<div id="typedtext"></div>
javascript:
// set up text to print, each item in array is new line
var arrText = new Array(
"This is an example of some,",
"typed text."
);
var speed = 60; // time delay of print out
var index = 0; // start printing array at this posision
var arrLength = arrText[0].length; // the length of the text array
var scrollAt = 20; // start scrolling up at this many lines
var textPos = 0; // initialise text position
var contents = ''; // initialise contents variable
var row; // initialise current row
function typewriter()
{
contents = ' ';
row = Math.max(0, index-scrollAt);
var destination = document.getElementById("typedtext");
while ( row < index ) {
contents += arrText[row++] + '<br />';
}
destination.innerHTML = contents + arrText[index].substring(0, textPos) + "█";
if ( textPos++ == arrLength ) {
textPos = 0;
index++;
if ( index != arrText.length ) {
arrLength = arrText[index].length;
setTimeout("typewriter()", 500);
}
} else {
setTimeout("typewriter()", speed);
}
}
typewriter();
Is this possible?
You can add a few CSS scripts to add blinking effect to the caret. Move the █ inside a <span> and add .blink class to it.
// set up text to print, each item in array is new line
var arrText = new Array(
"This is an example of some,",
"typed text."
);
var speed = 60; // time delay of print out
var index = 0; // start printing array at this posision
var arrLength = arrText[0].length; // the length of the text array
var scrollAt = 20; // start scrolling up at this many lines
var textPos = 0; // initialise text position
var contents = ''; // initialise contents variable
var row; // initialise current row
function typewriter() {
contents = ' ';
row = Math.max(0, index - scrollAt);
var destination = document.getElementById("typedtext");
while (row < index) {
contents += arrText[row++] + '<br />';
}
destination.innerHTML = contents + arrText[index].substring(0, textPos) + "<span class='blink'>█<span>";
if (textPos++ == arrLength) {
textPos = 0;
index++;
if (index != arrText.length) {
arrLength = arrText[index].length;
setTimeout("typewriter()", 500);
}
} else {
setTimeout("typewriter()", speed);
}
}
typewriter();
.blink {
animation: blink-animation 1s steps(5, start) infinite;
-webkit-animation: blink-animation 1s steps(5, start) infinite;
}
#keyframes blink-animation {
to {
visibility: hidden;
}
}
#-webkit-keyframes blink-animation {
to {
visibility: hidden;
}
}
<div id="typedtext"></div>
var i = 0;
var txt = 'UNITING PEOPLE'; /* The text */
var txt2 = ' &';
var txt3 = 'DELIVERING ';
var txt4 = 'INTELLIGENCE';
var txt5 = 'Access your hub for Open Journalism';
var speed = 0;
function typeWriter(fade) {
if (i < txt.length + txt2.length + txt3.length + txt4.length + txt5.length) {
if(i < txt.length-1) {
var element = document.createElement("p");
element.style.display = "inline-block";
element.style.opacity = "0.1";
element.style.fontSize = "38px";
element.style.fontFamily = "Helvetica-Bold";
element.style.whiteSpace = "pre";
element.style.marginTop = "0";
element.textContent += txt.charAt(i);
document.getElementById("words").children[0].children[0].appendChild(element)
unfade(element, fade);
i++;
setTimeout(typeWriter(fade), 10*fade);
} else if(i==txt.length-1) {
var element = document.createElement("p");
element.style.display = "inline-block";
element.style.opacity = "0.1";
element.style.fontSize = "38px";
element.style.fontFamily = "Helvetica-Bold";
element.style.whiteSpace = "pre";
element.style.marginTop = "0";
element.textContent += txt.charAt(i);
document.getElementById("words").children[0].children[0].appendChild(element)
unfade(element, fade);
i++;
setTimeout(typeWriter(fade), 1500);
} else if(i < txt.length + txt2.length-1)
...
}
setTimeout(typeWriter(100), 1500);
function unfade(element, fade) {
var op = 0.1; // initial opacity
element.style.display = 'inline-block';
var timer = setInterval(function () {
if (op >= 1){
clearInterval(timer);
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, fade);
}
I'm not sure what the bug is. Each letter should fade through about 100ms, and it should wait until each letter is done before the next letter begins.
Each element comes in inline and begins with a small opacity in the right font and font size, with spaces making room for text with the whitespace set to pre.
The text content updates with just 1 character at a time, and it's appended to the correct section before being faded in. The fading in is set to be the same as the overall letter fade, before the increment is counted.
Once the set timeout occurs, the delay fade is simply ignored and it all begins at once, so it's like the fade is set to 0 over all.
And yet when the code is cut and one section implemented it does one letter at a time.
i'm trying to make a "console typing effect" with js, and in the next function i take the text of an element, then i use a "for" loop for slicing that text and paste in within with a delay.
After debugging the code in chrome i can see that javascript doesn't run the setTimeout... it just ignores it.
function type() {
var text = document.querySelector('.console-effect').textContent;
for (var i = 0; i <= text.length; i++) {
setTimeout(function() {
document.querySelector('.console-effect').textContent = text.substr(0, i)
}, 50);
}
}
type();
Your setTimeouts are all executing at the same time, because the for loop does not wait for them to execute on each iteration. You have to delay each timeout using a value such as 50*i.
Then, to preserve the value of i in this case, you'll need to use a closure. Otherwise, by the time your timeouts come to an end, the loop will be over, and i will be the final value, for all of them.
var text = document.querySelector('.console-effect').textContent;
for (var i = 0; i <= text.length; i++) {
(function(i) {
setTimeout(function() {
document.querySelector('.console-effect').textContent = text.substr(0, i);
}, 50*i);
})(i);
}
body{background: #333;}
.console-effect{color: #0f0; font-family: monospace; font-size: 2em;}
<div class="console-effect">This is some example text</div>
Is not a good idea to make functions inside a loop in Javascript, I had bad experiences with it.
This code done this way should work correctly:
function type() {
var text = document.querySelector('.console-effect').textContent;
var loopFunc = function(i) {
return function() {
document.querySelector('.console-effect').textContent = text.substr(0, i)
};
};
for (var i = 0; i <= text.length; i++) {
setTimeout(loopFunc(i), 50);
}
}
type();
I didn't want to believe #blex, but he was correct about the scope. He was right on both points he made, but the closure stunned me. How have I never encountered this and been forced to puzzle my way out before?
So the idea here is that instead of scheduling a dozen or so calls to your function at the beginning, you only schedule the next call. After that one is called, it sees if it needs to schedule the next.
function type() {
var text = document.querySelector('.console-effect').textContent;
var i = 0;
var typeNext = function() {
++i;
document.querySelector('.console-effect').textContent = text.substr(0, i);
if(i < text.length) {
setTimeout(typeNext, 50);
}
}
setTimeout(typeNext, 50);
}
type();
<span class="console-effect">This is a test</span>
var text = document.querySelector('.console-effect').textContent;
var index = 0;
setInterval(function(){
document.querySelector('.console-effect').textContent = text.substr(0, index);
if(index == text.lenght){
clearInterval(this);
}
index++;
},1000);
Do something like this.
function type() {
var text = document.querySelector('.console-effect').textContent;
document.querySelector('.console-effect').textContent = '';//clear content
for (var i = 0; i <= text.length; i++) {
setTimeout(function(j) {
document.querySelector('.console-effect').textContent += text[j];// or .charAt(j)
}, 50 * i, i);
// 50 * i sets timeout for each iteration
// i (3rd arg) passes to the inner function
}
}
type();
Better version.
function type(text) {
var textObj = document.querySelector('.console-effect');
for (var i = 0; i <= text.length; i++) {
setTimeout(function(ch) {
textObj.textContent += ch;
}, 50 * i, text[i]);
// 50 * i sets timeout for each iteration
// i (3rd arg) passes to the inner function
}
}
type('.console-effect');
a solution without 50*i, take a look at the css effect too. You problem is setTimeout is executed asynchronously (the 'control flow' doesn't wait for those 50ms), so they are fired all together with value i = text.length (if your text is small enough)
<p class="console-effect">console effects</p>
<script>
function type() {
var i=0;
var t = document.querySelector('.console-effect').textContent;
var fn = setInterval(function() {
print_text(++i,t,fn)
}, 500);
}
function print_text(i,t,fn){
if(i <= t.length){
document.querySelector('.console-effect').textContent = t.substr(0, i)
} else clearInterval(fn)
}
type();
</script>
<style>
#-webkit-keyframes blinker {
from { opacity: 1.0; }
to { opacity: 0.0; }
}
.console-effect:after{
content:'_';
text-decoration: blink;
-webkit-animation-name: blinker;
-webkit-animation-duration: 0.2s;
-webkit-animation-iteration-count:infinite;
-webkit-animation-timing-function:ease-in-out;
-webkit-animation-direction: alternate;
}
</style>
setTimeout run only once(in your case after delay of 50ms).
For this purpose you should use setInterval
Hello i need to display by slide multiple entry by ajax my script work just for one entry
var newTxt = ['hello', 'hi'];
for(var i = 0; i <= newTxt.length; i++) {
$('#txt').prepend('<li class="none">' + newTxt[i] + '</li>');
$('#txt li:first-child').toggleClass("none", 2000);
}
i use css and toggleClass for animation
li { width:100px; }
li.none { width:0px; }
The animation work with 1 entry but with more not work
u have solution for display by slide one by one ?
Thanks you
Edit (now its work but all setTimeout exucute in same time)
var newTxt = ['hello', 'hi'];
for(var i = 0; i <= newTxt.length; i++) {
setTimeout(function(y) {
$('#txt').prepend('<li style="width:0">' + newTxt[i] + '</li>');
$('#txt li:first-child').animate({'width':'100px'}, 1000);
} (i), (i * 2000));
}
Demo https://jsfiddle.net/HHsxc/292/ i need to slide first wait slide seconde wait ...
I'm trying to create a menu of social media icons that slides into and out of the page. The following code works, but it is too fast. It doesn't look like sliding. I think I could adjust the timing using the setInterval() method, but I can't get it to work. This is the code so far:
var socialMedia = document.getElementById("socialmedia");
var stalkMe = document.getElementById("pleasestalkme");
function SM() {
socialMedia.style.position = "fixed";
socialMedia.style.right = "-330px";
}
SM();
stalkMe.addEventListener("click", function(){
if (socialMedia.style.right === "-330px") {
for (i = -330; i <= -30; i++) {
var j = i +"px";
socialMedia.style.right = j;
}
} else if (socialMedia.style.right === "-30px"){
for (i = -30; i >= -330; i--){
var j = i +"px";
socialMedia.style.right = j;
}
}
}, false);
You should have a look at CSS transitions. Basically you just need to change the right style from 300px to 0px and using transition: right 1s; you would see your element being animated
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Otherwise, you could have a look at jQuery.... (I feel bad).
Prior to the solution, a word of warning: you actually should not use this code snippet. Instead heed the advice of floribon and look into css transitions.
However, if you absolutely must do it the outmoded way:
for (i = -330; i <= -30; i++) {
var j = i +"px";
socialMedia.style.right = j;
}
write
var hnd;
i = -330;
hnd = setInterval ( function () {
var j = i +"px";
socialMedia.style.right = j;
i++;
if (i > -30) {
clearInterval(hnd); // end activity
}
}, 50 ); // interval length in ms