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.
Related
I am new to javascript. I am making my first small quiz web application but i am stuck on this query. How can I shuffle the questions array so the questions appears in different order every time.I have used function shuffle(array); and called this function inside render question function but it didn't work
// select all elements
const start = document.getElementById("start");
const quiz = document.getElementById("quiz");
const question = document.getElementById("question");
//const qImg = document.getElementById("qImg");
const choiceB = document.getElementById("B");
const choiceC = document.getElementById("C");
const choiceD = document.getElementById("D");
const counter = document.getElementById("counter");
const timeGauge = document.getElementById("timeGauge");
const progress = document.getElementById("progress");
const scoreDiv = document.getElementById("scoreContainer");
// create our questions
let questions = [{
question: "What does HTML stand for?",
choiceA: "Ā.B̄+ĀB",
choiceB: "AB+BC̄",
choiceC: " \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\] ",
choiceD: "<h4>text</h4>",
correct: "A"
}, {
question: "What does CSS stand for?",
choiceA: "Wrong",
choiceB: "Correct",
choiceC: "Wrong",
choiceD: "Wrong2",
correct: "B"
}, {
question: "c16/52 in R-L series circuit phase angle is given by ?",
choiceA: " =tan<sup>-1</sup> l⁄ wLR",
choiceB: " tan<sup>-1</sup> wLR",
choiceC: " ",
choiceD: "=tan<sup>-1</sup> wL⁄R ",
correct: " A"
}];
// create some variables
const lastQuestion = questions.length - 1;
let runningQuestion = 0;
let count = 0;
const questionTime = 20; // 10s
const gaugeWidth = 150; // 150px
const gaugeUnit = gaugeWidth / questionTime;
let TIMER;
let score = 0;
// render a question
function renderQuestion() {
let q = questions[runningQuestion];
shuffle(q);
question.innerHTML = "<p>" + q.question + "</p>";
choiceA.innerHTML = q.choiceA;
choiceB.innerHTML = q.choiceB;
choiceC.innerHTML = q.choiceC;
choiceD.innerHTML = q.choiceD;
}
function shuffle(array) {
var currentIndex = array.length,
temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
start.addEventListener("click", startQuiz);
// start quiz
function startQuiz() {
start.style.display = "none";
renderQuestion();
quiz.style.display = "block";
renderProgress();
renderCounter();
TIMER = setInterval(renderCounter, 1000); // 1000ms = 1s
}
// render progress
function renderProgress() {
for (let qIndex = 0; qIndex <= lastQuestion; qIndex++) {
progress.innerHTML += "<div class='prog' id=" + qIndex + "></div>";
}
}
// counter render
function renderCounter() {
if (count <= questionTime) {
counter.innerHTML = count;
timeGauge.style.width = count * gaugeUnit + "px";
count++
} else {
count = 0;
// change progress color to red
answerIsWrong();
if (runningQuestion < lastQuestion) {
runningQuestion++;
renderQuestion();
} else {
// end the quiz and show the score
clearInterval(TIMER);
scoreRender();
}
}
}
// checkAnwer
function checkAnswer(answer) {
if (answer == questions[runningQuestion].correct) {
// answer is correct
score++;
// change progress color to green
answerIsCorrect();
} else {
// answer is wrong
// change progress color to red
answerIsWrong();
}
count = 0;
if (runningQuestion < lastQuestion) {
runningQuestion++;
renderQuestion();
} else {
// end the quiz and show the score
clearInterval(TIMER);
scoreRender();
}
}
// answer is correct
function answerIsCorrect() {
document.getElementById(runningQuestion).style.backgroundColor = "#0f0";
}
// answer is Wrong
function answerIsWrong() {
document.getElementById(runningQuestion).style.backgroundColor = "#f00";
}
// score render
function scoreRender() {
scoreDiv.style.display = "block";
// calculate the amount of question percent answered by the user
const scorePerCent = Math.round(100 * score / questions.length);
// choose the image based on the scorePerCent
let img = (scorePerCent >= 80) ? "img/5.png" :
(scorePerCent >= 60) ? "img/4.png" :
(scorePerCent >= 40) ? "img/3.png" :
(scorePerCent >= 20) ? "img/2.png" :
"img/1.png";
scoreDiv.innerHTML = "<img src=" + img + ">";
scoreDiv.innerHTML += "<p>" + scorePerCent + "%</p>";
}
I am trying to build a slideshow that pretty much works by changing the margins in my CSS.
So far it's working well but I want the next and previous button to disappear when the margins have a certain value and I couldn't find a solution.
Here is my js code:
const nextBtn = document.querySelector('#slideNext');
const prevBtn = document.querySelector('#slidePrev');
const slider = document.querySelector('.boxes-container');
const slideWidth = 250;
// Slider initial margin
slider.style.marginLeft = "0";
nextBtn.onclick = function() {
slider.style.marginLeft = (parseInt(slider.style.marginLeft, 0) - slideWidth) + 'px';
}
prevBtn.onclick = function() {
slider.style.marginLeft = (parseInt(slider.style.marginLeft, 0) + slideWidth) + 'px';
}
if (slider.style.marginLeft == "0") {
prevBtn.style.display = "none";
} else if (slider.style.marginLeft == "-1000px") {
nextBtn.style.display = "none";
} else {
nextBtn.style.display = "inline-block";
prevBtn.style.display = "inline-block";
}
My issue is on the last part: I don't know how to deal with an if/else statement that would modify the display of my buttons when the margin reach a certain value.
It would be awesome if anyone could point me in the right direction as I've spent some time trying to solve this on my own but couldn't find the right solution.
Thanks for your help!!
You created the logic correctly. The problem is that you don't check the margin every time the button is clicked (javascript is not reactive by default).
You have to wrap the margin's logic into a function and then check the margin values every time the button is clicked.
const nextBtn = document.querySelector('#slideNext');
const prevBtn = document.querySelector('#slidePrev');
const slider = document.querySelector('.boxes-container');
const slideWidth = 250;
// Slider initial margin
slider.style.marginLeft = "0";
nextBtn.onclick = function() {
slider.style.marginLeft = (parseInt(slider.style.marginLeft, 0) - slideWidth) + 'px';
checkMargin();
}
prevBtn.onclick = function() {
slider.style.marginLeft = (parseInt(slider.style.marginLeft, 0) + slideWidth) + 'px';
checkMargin();
}
function checkMargin() {
if (slider.style.marginLeft == "0") {
prevBtn.style.display = "none";
} else if (slider.style.marginLeft == "-1000px") {
nextBtn.style.display = "none";
} else {
nextBtn.style.display = "inline-block";
prevBtn.style.display = "inline-block";
}
}
There are other methods to make the DOM reactive, like MutationObserver. But it may be an overkill to this task.
The reason why it wasn't working was because I wasn't checking for the margins when the buttons were clicked.
I changed my code as follow:
const nextBtn = document.querySelector('#slideNext');
const prevBtn = document.querySelector('#slidePrev');
const slider = document.querySelector('.boxes-container');
const slideWidth = 250;
// Slider initial margin
slider.style.marginLeft = "0px";
function check() {
if (slider.style.marginLeft == "0px") {
prevBtn.style.display = "none";
} else if (slider.style.marginLeft == "-1000px") {
nextBtn.style.display = "none";
} else {
nextBtn.style.display = "inline-block";
prevBtn.style.display = "inline-block";
}
}
window.onload = check(); // Check the margins when the page is loaded
nextBtn.onclick = function() {
slider.style.marginLeft = (parseInt(slider.style.marginLeft, 0) - slideWidth) + 'px';
check();
}
prevBtn.onclick = function() {
slider.style.marginLeft = (parseInt(slider.style.marginLeft, 0) + slideWidth) + 'px';
check();
}
Wrapped the margin logic inside of a check() function
Check this function on page load and everytime the buttons are clicked
Thanks to Gustavo for his precious help!
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>
I am very new to Javascript, and have a question about one of my functions(checkOrBet). I am trying to make a Texas Hold'em poker game, and the part that doesn't seem to be working is where I test for a regular pair. It doesn't seem to recognize that a pair has been made, when the cards are dealt to the deck.
function game() {
function Playert(name, chips) {
this.name = name;
this.chips = chips;
this.firstCard = [];
this.secondCard = [];
this.blind = {};
// this.turnpos = 0; //1 for current turn
//will be computer's response when prompted during the flop
this.checkOrBet = function checkOrBet() {
var response;
//Ace High
if (this.firstCard.rank == "A") {
response = "call";
console.log("Ace High!");
} else if (this.secondCard.rank == "A") {
response = "call";
console.log("Ace High!");
}
//Tests for a pocket pair
if (this.firstCard.rank == this.secondCard.rank) {
response = "call";
console.log("Pocket pairs!");
}
//Test for a regular pair
if (this.firstCard.rank == communityCards.cards[0].rank || communityCards.cards[1].rank || communityCards.cards[2].rank) {
response = "call";
console.log("pairs");
} else if (this.secondCard.rank == communityCards.cards[
0]) {
response = "call";
console.log("pairs");
}
}
}
function Pot(chipsp) {
this.chipsp = 0;
}
//clears text every time start button is pressed
function clearBox() {
document.getElementById("computer").innerHTML = "";
document.getElementById("flop").innerHTML = "";
document.getElementById("hand1").innerHTML = "";
}
clearBox();
//players start with chips, low blind, big blind.
var computer = new Playert("Computer", 200);
var player = new Playert("Player1", 200);
//Need a deck to deal the cards for the players.
var deck = new Stack();
//player's hand
var phand = new Stack();
//computer's hand
var chand = new Stack();
//game cards
var gamehand = new Stack();
//make pot
var pot1 = new Pot();
//community cards variable
var communityCards = new Stack();
deck.makeDeck(1);
deck.shuffle(1);
//deal 2 cards to player hand
if (phand.cardCount < 2) {
alert("Not enough cards in deck");
} else {
for (i = 0; i < 2; i++) {
phand.addCard(deck.deal());
}
}
//grab player div by the ID
playerhand = document.getElementById("hand1");
//create p element to show cards in player div
var pdoc = document.createElement("p");
//create text node to append to p element
var ptext = document.createTextNode(phand.cards);
//append text node to p element
pdoc.appendChild(ptext);
//append p element with cards to the hand1 div
playerhand.appendChild(pdoc);
//deal cards to computer's hand
if (chand.cardCount < 2) {
alert("Not enough cards in deck");
} else {
for (i = 0; i < 2; i++) {
chand.addCard(deck.deal());
}
}
//tie computer's hand to firstCard/secondCard
computer.firstCard = chand.cards[0];
computer.secondCard = chand.cards[1];
console.log(computer.firstCard.rank);
console.log(computer.secondCard.rank);
//grab computer div by id
d = document.getElementById("computer");
//create p element to show cards in computer div
var cdoc = document.createElement("p");
//create text node to append to p element
var ctext = document.createTextNode(chand.cards.toString());
//append text node to p element
cdoc.appendChild(ctext);
//append p element to computer div
d.appendChild(cdoc);
//grab game cards div
g = document.getElementById("flop");
//create p element for appending
var fdoc = document.createElement("p");
//create text node to append to paragraph element
//choose which player has the blind
function blinds() {
var small = 5;
var big = 10;
var random = Math.floor(Math.random() * 2) + 1;
if (random == 1) {
player.blind = small;
player.chips -= small;
computer.blind = big;
computer.chips -= big;
pot1.chipsp += 15;
} else if (random == 2) {
player.blind = big;
player.chips -= big;
computer.blind = small;
computer.chips -= small;
pot1.chipsp += 15;
}
}
blinds();
//Show chips for player
var chips = document.getElementById("hand1");
var chipsp = document.createElement("p");
var chipsn = document.createTextNode("You have " + player.chips +
" chips");
chipsp.appendChild(chipsn);
chips.appendChild(chipsp);
//Show chips for the computer
var cchips = document.getElementById("computer");
var pchips = document.createElement("p");
var chipsnc = document.createTextNode("You have " + computer.chips +
" chips");
pchips.appendChild(chipsnc);
cchips.appendChild(pchips);
//grab computer hand div for printing out chips
function grab(x) {
d = document.getElementById(x);
return d;
}
//grab computer div
var cblind = grab("computer");
//create p element
var cpblind = document.createElement("p");
//create text node
var ctblind = document.createTextNode("Computer's blind is" + " " +
computer.blind);
//append text to p
cpblind.appendChild(ctblind);
//append p to computer div
cblind.appendChild(cpblind);
//grab hand1 for showing player blind
var ghand1 = grab("hand1");
//create element
var ghand2 = document.createElement("p");
//create text node
var ghand3 = document.createTextNode("Player's blind is" + " " + player
.blind);
//append text to para
ghand2.appendChild(ghand3);
//append p to div
ghand1.appendChild(ghand2);
//if computer gets the blind of 5,call no matter what
if (computer.blind = 5) {
computer.chips -= 5;
}
//if player is low blind, prompt for call, fold, or bet
if (player.blind == 5) {
var cfb = prompt("Would you like to call, fold, or bet?");
switch (cfb) {
case "call":
//do something
//draw 3 cards from the deck and append
for (i = 0; i < 3; i++) {
communityCards.addCard(deck.draw(1));
}
player.chips -= 5;
pot1.chipsp += 5;
chipsn.nodeValue = "You have " + player.chips + " chips";
player.turnpos = 1; //has acted
break;
case "fold":
//do something
computer.chips += pot1.chipsp;
break;
case "bet":
//do something
break;
default:
//do something
}
//start flop round
//draw 3 cards from the deck / switch statement for check,fold, bet?
//prompt computer and player on what they want to do
} else if (player.chips = 10) {
//draw 3 cards from the deck and append
for (i = 0; i < 3; i++) {
communityCards.addCard(deck.draw(1));
}
player.chips -= 5;
pot1.chipsp += 5;
}
//print flop cards to flop div
var flopc = document.getElementById("flop");
var flopcr = document.createElement("p");
var floptn = document.createTextNode(communityCards.cards.toString());
flopcr.appendChild(floptn);
flopc.appendChild(flopcr);
//print pot to flop div
var potf = document.createElement("p");
var pottn = document.createTextNode("The pot is " + pot1.chipsp);
potf.appendChild(pottn);
flopc.appendChild(potf);
//if player has acted, prompt computer to check, bet or fold
// if (player.turnpos == 1) {
//computer evaluates hands
//}
//test function
computer.checkOrBet();
}
Go with this :
//Test for a regular pair
if (this.firstCard.rank == communityCards.cards[0].rank || this.firstCard.rank == communityCards.cards[1].rank || this.firstCard.rank == communityCards.cards[2].rank) {
response = "call";
console.log("pairs");
} else if (this.secondCard.rank == communityCards.cards[
0]) {
response = "call";
console.log("pairs");
}
same for the second card.
I have a fair amount of functions like the ones below, all with some slight changes and querying different ids. Is there some way to concatenate this or will I just have to write them all out? Thanks.
function event() {
var path = document.querySelector('#container #path');
var length = path.getTotalLength();
console.log(path.getTotalLength());
path.style.transition = path.style.WebkitTransition =
'none';
path.style.strokeDasharray = length + ' ' + length;
path.style.strokeDashoffset = length;
path.getBoundingClientRect();
path.style.transition = path.style.WebkitTransition =
'stroke-dashoffset 0.4s linear';
path.style.strokeDashoffset = '0';
document.getElementById("container").style.visibility = "visible";
};
function event2() {
var path2 = document.querySelector('#container2 #path_2');
var length = path2.getTotalLength();
console.log(path2.getTotalLength());
path2.style.transition = path2.style.WebkitTransition =
'none';
path2.style.strokeDasharray = length + ' ' + length;
path2.style.strokeDashoffset = length;
path2.getBoundingClientRect();
path2.style.transition = path2.style.WebkitTransition =
'stroke-dashoffset 0.45s linear';
path2.style.strokeDashoffset = '0';
document.getElementById("container2").style.visibility = "visible";
};
function event3() {
var path3 = document.querySelector('#container3 #path_3');
var length = path3.getTotalLength();
console.log(path3.getTotalLength());
path3.style.transition = path3.style.WebkitTransition =
'none';
path3.style.strokeDasharray = length + ' ' + length;
path3.style.strokeDashoffset = length;
path3.getBoundingClientRect();
path3.style.transition = path3.style.WebkitTransition =
'stroke-dashoffset 0.4s linear';
path3.style.strokeDashoffset = '0';
document.getElementById("container3").style.visibility = "visible";
};
window.setTimeout(function() {
event();
}, 1);
window.setTimeout(function() {
event2();
}, 550);
window.setTimeout(function() {
event3();
}, 1100);
If I have a series of nearly identical functions
function showNumber1() {
window.alert("The number you wish to show is 1");
}
function showNumber2() {
window.alert("The number you wish to show is 2");
window.alert("Okay that's all");
}
function showNumber3() {
window.alert("The number you wish to show is 3");
}
I can usually replace them with a single function, like
function showNumber(n) {
window.alert("The number you wish to show is " + n);
if (n == 2) {
window.alert("Okay that's all");
}
}
So, rewrite your functions into a single function containing the parts that stay the same, and use parameters and if statements to represent the parts that differ.
Also, you seem to be using IDs as if they are classes. Instead of having
<div id="path_1"> ... <div id="path_2"> ...
You could use a class
<div class="path"> ... <div class="path"> ...
and identify them in your javascript using document.getElementsByClassName('path')[0] and document.getElementsByClassName('path')[1] .