Chaining similar elements modification by time interval - javascript

I have a given list of p elements on my html code.
On page load, I try to queuing modifications of each <p> elements's content by a given interval of time (1sec).
Given the html:
<p>I want to change first!</p>
<p>I want too!</p>
<p>Me 3rd !</p>
<p>Hey, don't forget me!</p>
the CSS:
p { padding: 2px 5px 0px 10px; }
.p { color: #999; }
.green { color:green; border-bottom: 1px solid #888; background: #EEE; }
What should be the JS to since I want to chain up modification. Literally: the first p sentence to be CSS / HTML modified first, 1sec later the 2nd line should be replaced, 1sec later the 3rd line, 4sec later the 4th line, etc.
$("p").ready(function(){
setInterval(function () {
$('p').text('aaaahhhhh.... happy!')
}, 1000);
});
That's fail (fiddle).
What I am doing wrong ? should I use a for loop, each(), instead of selector + setInterval ? please forward keywords so I may dig in the relevant docs. Fiddle appreciate~

Try this
$(document).ready(function(){
var st=null;
var i=0;
st=setInterval(function () {
$('p').eq(i).text('aaaahhhhh.... happy!');
if(i==$('p').length-1)// one less because i initialised by 0.
clearTimeout(st);
i++
}, 1000);
});
Check live demo here http://jsfiddle.net/gT3Ue/14/

(function next($set, i) {
setTimeout(function () {
$set.eq(i).text('aaaahhhhh.... happy!');
if (i < $set.length - 1) {
next($set, i + 1);
}
}, 1000);
// /\
// ||------ the delay
}($('p'), 0));
// /\ /\
// || ||-- the starting index
// ||----- -- your set of elements
demo: http://jsbin.com/otevif/1/

function modifyTargetDeferred(target) {
target.first().text('ahhh... happy');
if (target.length > 1) {
setTimeout(function() {
modifyTargetDeferred(target.not(':first'));
}, 1000);
}
}
setTimeout(function() {
modifyTargetDeferred($('p'));
}, 1000);

Your interval is working use append instead of text to see the effect. Use document.ready not $("p").ready
Live Demo
$(document).ready(function(){
setInterval(function () {
$('p').append('aaaahhhhh.... happy!')
}, 1000);
});
Live Demo
i = 0;
$(document).ready(function () {
div1 = $('#div1');
parry = $("p");
setInterval(function () {
div1.append(parry.eq(i++).text() + '<br />')
if (i > 3) i = 0;
}, 400);
});

Related

JS & HTML - place on html on which the JS script will appear

I'm quite new to JS.
I want to have my html page stay the same when JS text will be appearing in one exact place without starting from blank page.
I trigger JS function via button on HTML, function in HTML:
function match () {
setTimeout(function () {
player_hp -= monster_dmg
monster_hp -= player_dmg
if (player_hp<=0) {
document.write("\nPlayer dies!")
menu();
return;
}
if (monster_hp<=0) {
document.write("\nPlayer wins!")
menu();
return;
}
if (fight=1) {
document.write("\nPlayer hp:" + player_hp)
document.write("\nMonster hp:" + monster_hp)
document.write("\n");
match()
}
}, interval)
}
One easy way to handle this is to simply create a <div> or a <span> element that has an ID attribute like this:
<div id="status"> </div>
Now you can access this element by using the Javascript method
document.querySelector("#status") and then use the innerHTML function of that element to change the internal content. You can even place the document.querySelector function into a convenient function which I have named send_status()
Here's the whole thing
/* default values */
var player_hp = 300;
var monster_dmg = 30;
var monster_hp = 200;
var interval = 500;
var player_dmg = 50;
match();
/* heres a function that will replace your document.write() functions */
function send_status(message) {
document.querySelector("#status").innerHTML = message;
}
function match() {
setTimeout(function() {
player_hp -= monster_dmg
monster_hp -= player_dmg
if (player_hp <= 0) {
send_status("\nPlayer dies!") // replaced document.write with send_status
menu();
return;
}
if (monster_hp <= 0) {
send_status("\nPlayer wins!")
menu();
return;
}
if (fight = 1) {
send_status("\nPlayer hp:" + player_hp)
send_status("\nMonster hp:" + monster_hp)
send_status("\n");
match()
}
}, interval)
}
function menu() {}
#game {
width: 100%;
height: 100px;
border: 2px solid black;
}
#status {
width: 100%;
height: 50px;
background-color: grey;
}
<div id="game">Game Goes Here</div>
<!-- here is your status area -->
<div id="status"></div>
You should create a results div, in which will be shown the match result.
Just add <div id="match_results"></div> in your HTML code.
And replace all yours document.write() for
document.getElementById('match_results').innerHTML += "<br>Player wins!"
This command is appending content in the element with ID match_results.
You should use <br> instead of \n because it is the proper way to break line in HTML code.

I am having trouble making a javascript typewriter effect

Its supposed to type one letter at a time when you open the page, however, it is not showing up at all. I'm a newbie at this javascript stuff.
HTML
<div class="wrap">
<div class="test type" data-text="Hi, my name is John Doe"></div>
</div>
CSS
body {
font: 16px/20px sans-serif;
}
.wrap {
width: 500px;
margin: 30px auto;
text-align: center;
}
.test {
margin-top: 10px;
text-align: left;
}
JS
function typeWriter(text, n) {
if (n < (text.length)) {
$('.test').html(text.substring(0, n+1));
n++;
setTimeout(function() {
typeWriter(text, n)
}, 100);
}
}
$('.type').click(function(e) {
e.stopPropagation();
var text = $('.test').data('text');
typeWriter(text, 0);
});
Use this, I made it worked in less code.
Another thing i did is used some random time to give real world effect..
$(function(){
var txt = $(".type").data("text").split("");
txt.forEach(function(chr, i){
var rand = Math.floor(Math.random() * 100) + 1;
setTimeout(function(){
$(".type").append( chr );
},300*(i+1) + rand)
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test type" data-text="Hi, my name is John Doe"></div>
$(function(){
function typeWriter(text, n) {
if (n < (text.length)) {
$('.test').html(text.substring(0, n+1));
n++;
setTimeout(function() {
typeWriter(text, n)
}, 100);
}
}
$('.type').click(function(e) {
e.stopPropagation();
var text = $('.test').data('text');
typeWriter(text, 0);
});
});
body {
font: 16px/20px sans-serif;
}
.wrap {
width: 500px;
margin: 30px auto;
text-align: center;
}
.test {
margin-top: 10px;
text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="test type" data-text="Hi, my name is John Doe">Click me</div>
</div>
You needed to add something to click. (I added the text 'click me' in the div).
You may miss the CDN.
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
Your codes are good.
Here's another example JavaScript code that types out a string one letter at a time, with a delay of 500 milliseconds between each letter:
const myString = "Hello, world!"; // The string to be typed out
let i = 0; // Index of the current letter to be typed out
function typeString() {
if (i < myString.length) { // Check if there are more letters to type out
document.getElementById("myText").innerHTML += myString.charAt(i); // Add the next letter to the text
i++; // Increment the index for the next letter
setTimeout(typeString, 500); // Call this function again in 2 seconds
}
}
typeString(); // Call the function to start typing out the string
<div id="myText"></div>
This code uses a recursive function called typeString() that checks if there are more letters to type out, adds the next letter to a specified HTML element using the innerHTML property, increments the index for the next letter, and then sets a delay of 2 seconds using the setTimeout() method before calling itself again to type out the next letter. The function is called initially to start typing out the string. Note that you should replace "myText" in the code with the ID of the HTML element where you want the string to be displayed.

Execute jQuery function after first is complete

I have created a page where I have multiple functionality done but stuck with timing of it, if you see the page example here in JSFiddle.
When you open the page, it will first run a loader and when the loader is complete there are multiple boxes, which is showing one by one but in currently its not happening, Loader is loading fine and then in the next step where centered columns has to appear one by one, the first four columns loads by default and then other div loads one by one.
My question is, how can I execute a function and execute another another function once the previous is complete.
For loader I have the following:
//--------- process bar animation
var showText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { showText(target, message, index, interval); }, interval);
}
}
var width = 100,
perfData = window.performance.timing, // The PerformanceTiming interface represents timing-related performance information for the given page.
EstimatedTime = -(perfData.loadEventEnd - perfData.navigationStart),
time = parseInt((EstimatedTime/1000)%60)*100;
showText("#msg", "Welcome to the Company Group", 0, width);
// Loadbar Animation
$(".loadbar").animate({
width: width + "%"
}, time);
// Loadbar Glow Animation
$(".glow").animate({
width: width + "%"
}, time);
// Percentage Increment Animation
var PercentageID = $("#precent"),
start = 0,
end = 100,
durataion = time;
animateValue(PercentageID, start, end, durataion);
function animateValue(id, start, end, duration) {
var range = end - start,
current = start,
increment = end > start? 1 : -1,
stepTime = Math.abs(Math.floor(duration / range)),
obj = $(id);
var timer = setInterval(function() {
current += increment;
$(obj).text(current + "%");
//obj.innerHTML = current;
if (current == end) {
clearInterval(timer);
}
}, stepTime);
}
// Fading Out Loadbar on Finised
setTimeout(function(){
$('.preloader-wrap').fadeOut(300);
$('.loader-wrap').fadeOut(300);
$('.main-wrapper').fadeIn(300);
$('body').addClass('bg');
}, time);
For showing div one by one in next step I have the following code:
$(".column-wrapper").each(function(index) {
var $this = $(this);
setTimeout(function () { $this.addClass("show"); }, index * 1000);
});
I use trigger and on for those kind of things. You had a lot of code, so sorry, I didn't want to read all of that but this is a simplified example.
https://jsfiddle.net/2d6p4L6k/1/
$(document).ready(function(){
var action = function(){
$('div.one').css('background-color', 'green');
/* do whatever you want to do */
/* then trigger(call) another function */
$(document).trigger('hello-action');
};
var hello = function() {
$('div.two').css('background-color', 'fuchsia');
};
/* just listen if anything triggers/calls "hello-action" */
/* if so call function named hello */
$(document).on('hello-action', hello);
setTimeout(action, 1500);
});
div {
width: 50px;
height: 50px;
background-color: orange;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="one">one</div>
<div class="two">two</div>
Note: To keep it simple we trigger and listen on $(document) which is really just to keep it simple. A better approach would be to have a wrapper element, and then you can do exactly the same (trigger and listen) just on that element and not on the entire document. You can find more details on the jQuery API .trigger()

Nested setInterval function on scroll not working

I am trying to set interval to a function that is only called when user scrolls below a certain height. My code return no errors and the function does not run either. However, I tried logging a random number at the end of the function and it doesn't so I think it has to do with my function. Take a look:
var firstString = ["This ", "is ", " me."];
var firstPara = document.querySelector("#firstPara");
var distanceSoFar = (document.body.scrollTop);
window.addEventListener("scroll", function() {
setInterval(slideIn, 450);
});
function slideIn() {
if (distanceSoFar > "130") {
for (var i = 0; i < firstString.length; i++) {
var stringOut = firstString.shift();
firstPara.innerHTML += stringOut;
console.log("5");
}
}
};
firstPara is just a paragraph in a div on the page. So the idea is to place some text in it on interval when a user scrolls into that view like so:
body {
height: 1000px;
}
div {
position: relative;
top: 700px;
}
div #firstPara {
border: 1px solid;
}
Part of your code is working. It handles the scroll event correctly and the slideIn function is called but the condition distanceSoFar > "130" is never met.
I'd suggest two changes to make your code work as you expect:
Use document.documentElement.scrollTop instead of document.body.scrollTop. document.body.scrollTop may return incorrect values (0) on some browsers. Look at this answer, for example.
Declare distanceSofar inside of the slideIn function. You declared the variable on the top of your code, so it stores a static value of the scrollTop property.
I'd avoid using setInterval inside a scroll event handler, you are setting a lot of intervals and not clearing them. I added some console.logs to show you how the slideIn function keeps being called even when the user is not scrolling.
A final tip: the scrollTop property is a number, so you can compare it to 130 instead of "130".
Here is the working fiddle.
I tried your code. I think it is working as you expected. I also added a clearInterval inorder to clear the timer after printing all text and also to avoid repeated calling.
<html>
<head>
<style>
body {
height: 1000px;
}
div {
position: relative;
top: 700px;
}
div #firstPara {
border: 1px solid;
}
</style>
<script>
function start(){
var s =0;
var interval = undefined;
function slideIn() {
console.log(distanceSoFar);
if (distanceSoFar > "130") {
while ( firstString.length > 0) {
var stringOut = firstString.shift();
firstPara.innerHTML += stringOut;
console.log(s++);
}
clearInterval(interval);
interval = undefined;
}
};
var firstString = ["This ", "is ", " me."];
var firstPara = document.querySelector("#firstPara");
var distanceSoFar = (document.body.scrollTop);
window.addEventListener("scroll", function() {
if(!interval)
interval = setInterval(slideIn, 450);
});
};
</script>
</head>
<body onload="start()">
<div id="firstPara"/>
</body>
<html>

Fade in boxes 1 after the other with jQuery

Im trying to make a 'blanket' of divs containing child divs 150px high and 150px wide.
I want each child div to fade in 1 after the other after after a millisecond or so, opacity changing from 0, to 1.
I cant seem to figure out how this works, or how id do it though?
http://jsfiddle.net/CCawh/
JS
$(function(){
var figure = [];
w = 1500;
h = 450;
for(i = 0, i < 30, i++){
$('div').append(figure[].clone()).fadeIn();
}
});
Here is a working solution.
The problems in your code
in for(i = 0, i < 30, i++), you should use ';', not ',' . Use developer tools in your browser to catch such typos
In your code $('div').append(figure[].clone()).fadeIn(); , The fadeIn applies to $('div') as append() returns the calling object itself. You must replace it with $('<figure></figure>').appendTo('div').fadeIn('slow'); and to fadeIn items one by one you could set a timeout with incrementing delays
Add display: none; style to the figure to keep it hidden initially
Here is the full code.
$(function(){
for(i = 0; i < 30; i++){
setTimeout(function(){$('<figure></figure>').appendTo('div').fadeIn('slow');}, i*200);
}
});
Here is a fiddle to see it working http://jsfiddle.net/CCawh/12/
Try using greensock TweenLite http://www.greensock.com/get-started-js/.
It has staggerTo/staggerFrom action that does exactly what you are asking. TweenLite in conjunction with jQuery makes animation very easy.
This would be a possible solution (DEMO).
Use an immediate function and call it again n times in the fadeIn callback.
$(function(){
var figure = $('figure');
var counter = 0;
(function nextFade() {
counter++;
figure.clone().appendTo('div').hide().fadeIn(500, function() {
if(counter < 30) nextFade();
});
})();
});
You can use the following implementation as an example. Using setTimeout() will do the trick.
I've updated your jsfiddle here: http://jsfiddle.net/CCawh/5/
HTML:
<div class="container">
<div class="box"></div>
</div>
CSS:
.box {
display: none;
float: left;
margin: 10px;
width: 150px;
height: 150px;
background-color: #000;
}
JS:
$(function() {
var box = $('.box');
var delay = 100;
for (i = 0; i < 30; i++) {
setTimeout(function() {
var new_box = box.clone();
$('.container').append(new_box);
new_box.fadeIn();
}, delay);
delay += 500; // Delay the next box by an extra 500ms
}
});
Note that in order for the element to actually fade in, it must be hidden in the first place, i.e. display: none; or .hide()
Here's perhaps a more robust solution without counters:
http://jsfiddle.net/CCawh/6/
for(var i = 0; i < 30; i++){
$('div').append($('<figure>figure</figure>'));
}
(function fade(figure, duration) {
if (figure)
figure.fadeIn(duration, function() { fade(figure.next(), duration); });
})($('figure').first(), 400);
By the way, clauses in for loops are separated using semicolons, not commas.

Categories