The code is meant to animated some text in a typing fashion. I want it to run once, but it keeps looping through the area of sentences. How would i go about stopping it looping through. The top of the code gathers the value of a input and puts into the array, this all works fine. It is just the looping i am having issues with.
var yourWord = document.getElementById("myText").value;
var yourtext = "I took the word " + yourWord + "...";
var infomation = [yourtext,
'I looked at the most relevant news article relating to it...',
'And created this piece of art from the words in the article! '
],
part,
i = 0,
offset = 0,
pollyLen = Polly.length,
forwards = true,
skip_count = 0,
skip_delay = 5,
speed = 100;
var wordflick = function () {
setInterval(function () {
if (forwards) {
if (offset >= infomation[i].length) {
++skip_count;
if (skip_count == skip_delay) {
forwards = false;
skip_count = 0;
}
}
} else {
if (offset == 0) {
forwards = true;
i++;
offset = 0;
if (i >= pollyLen) {
i = 0;
}
}
}
part = infomation[i].substr(0, offset);
if (skip_count == 0) {
if (forwards) {
offset++;
} else {
offset--;
}
}
$('#pollyInfo').text(part);
}, speed);
};
$(document).ready(function () {
wordflick();
});
Modify the line:
setInterval(function () {
into:
var interval = setInterval(function () {
and then clear the interval where you are setting i=0;
if (i >= pollyLen) {
i = 0;
}
to:
if (i >= pollyLen) {
i = 0;
clearInterval(interval);
}
This should do the job!
Related
This is a simple quiz/questionnaire, that'll display results of the quiz on submission. It shows the results, but only for about half a second before resetting the page. I would also like for the page to show an alert if the user says they're under 18 when the quiz is submitted; it wouldn't keep them from seeing the answers, but just giving them a message.
function checkAge() {
if(age<18) {
alert("Always make sure you have adult supervision while caring for and handling any venomous arachnid.");
} }
function generateAnswers() {
var choice1score = 0;
var choice2score = 0;
var choice3score = 0;
var choice4score = 0;
}
var chosenAnswers = document.getElementsByTagName('result');
for (i=0; i<chosenAnswers.length; i++) {
if (chosenAnswers[i].checked) {
// add 1 to that choice's score
if (chosenAnswers[i].value == 'choice1') {
choice1score = choice1score + 1;
}
if (chosenAnswers[i].value == 'choice2') {
choice2score = choice2score + 1;
}
if (chosenAnswers[i].value == 'choice3') {
choice3score = choice3score + 1;
}
if (chosenAnswers[i].value == 'choice4') {
choice4score = choice4score + 1;
}
}
}
var maxscore = Math.max(choice1score,choice2score,choice3score,choice4score);
var resultBox = document.getElementById('result');
if (choice1score == maxscore) {
resultBox.innerHTML = "Asian Forest Scorpion"
}
if (choice2score == maxscore) {
resultBox.innerHTML = "Deathstalker Scorpion"
}
if (choice3score == maxscore) {
resultBox.innerHTML = "Desert Hairy Scorpion"
}
if (choice4score == maxscore) {
resultBox.innerHTML = "Emperor Scorpion"
}
}
This is where I put the code:
https://codepen.io/cryceks/pen/vjgzOZ
Use:
event.preventDefault();
This prevents the webpage from reloading and therefore clearing form data
I have a function that checking board is there a searching element.
First script creating a board with different elements. Element in the square next to board is element that user has to find on the board and click them.
User has to click (as quick as possible) all searching elements. After click on element function checking a board, is there more elements. If yes then nothing happen and user has to click another one. If on board there isn’t searching elements then function display a time and new board create.
But some reason function works correct only first time after page load. Latter function ignore more then one element on board or see element that doesn’t exist on board any more.
Can you tell me what is wrong.
Part of code bellow and there is a link to testing page.
http://doomini2.linuxpl.info/font/
Thank you
function secondStage() {
createBoxes(59);
var usingSet = [];
var i = 0;
var boxList = document.querySelectorAll("#board > div");
createSet(usingSet, 20, shapes);
(function paint() {
if (i <= 59) {
var curentBox = boxList[i];
curentBox.className = usingSet[draw(20)];
curentBox.style.color = colors[draw(colors.length - 5)];
timeStop = setTimeout(paint, 50);
i++;
} else {
var findShape = boxList[draw(59)];
toFind.className = findShape.className;
toFind.style.color = findShape.style.color;
findBoxes(boxList);
clearTimeout(timeStop);
}
})();
}
//function checks boxes to find a proper shape
function findBoxes(boxList) {
startTime = Date.now();
board.addEventListener("mousedown", function (e) {
if ((e.target.className === toFind.className)) {
e.target.className = "correct";
e.target.innerHTML = "OK";
checkBoard();
} else if (e.target.id === "board" || e.target.className === "correct") {
} else {
e.target.className = "false";
e.target.innerHTML = "NO";
}
}, false);
function checkBoard() {
var condition = false;
console.log(condition);
for (var x = 0; x < boxList.length; x++) {
if ((boxList[x].className === toFind.className)) {
condition = true;
console.log(condition);
}
}
if (condition === false) {
var clickTime = Date.now();
var timeResult = parseFloat(((clickTime - startTime) / 1000).toFixed(3));
lastResult.innerHTML = timeResult + "s";
secondResult[secondResult.length] = timeResult;
console.log(secondResult);
displayResult(secondStage);
}
}
}
//function displaig results after every single round
function displayResult(stage) {
cover.className = "";
TweenMax.to("#lastResultDiv", 1, {ease: Back.easeOut, right: (winWidth / 4), });
TweenMax.to("#go", 1, {ease: Back.easeOut, top: (winWidth / 3), onComplete: function () {
goButton.addEventListener("click", function () {
clear();
}, false);
}});
//clear board and return to play
function clear() {
TweenMax.to("#lastResultDiv", 1, {ease: Back.easeIn, right: winWidth, });
TweenMax.to("#go", 1, {ease: Back.easeOut, top: -100, onComplete: function () {
cover.className = "hide";
lastResultDiv.style.right = "-592px";
toFind.className = "";
board.innerHTML = "";
if (firstStageRound === 10) {
secondStage();
} else if (secondStageRound === 5) {
thirdStage();
} else {
stage();
}
}});
}
}
Not Load this File http://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenMax.min.js
try to local path
I'm making a flipping counter which is supposed to change color when reaching the target number (1000 in the example). But the thing is the different parts of the counter doesn't change color at the same time, we can clearly see a delay between the tiles that make up the counter...
I'm using a simple jQuery addClass to trigger the color change:
$("#rhcounter .count").addClass("red");
Any ideas what could be causing that ?
Here is the fiddle: http://jsfiddle.net/ka6ke28m/6/
Thanks for your help !
First issue:
There was a huge amount of wasted processing going on. jQuery selectors have an overhead so reduce them to a minimum and complex selectors more-so. I have reduced that considerably.
Second issue:
There is a nasty visual glitch on some browsers that looked like this:
Which you can eliminate by using background-color: instead of background: (which tries to completely re-render the area instead of just fill the background colour).
Third issue:
The color blue left behind was down to slow repainting of the screen. The above two fixes had a huge impact and I also tried adding specific CSS animations that worked only with the red class. This can probably be improved now you know the causes of the slow painting (e.g. have blue and red CSS animation?):
http://jsfiddle.net/TrueBlueAussie/ka6ke28m/10/
$(function () {
var total = 1000,
current = 950,
timeout = 150,
inc = 7,
prevTiles = ["0", "0", "0", "0"],
interval = setInterval(function () {
increase()
}, timeout),
increase = function () {
current += inc;
if (current >= total) {
clearInterval(interval);
current = total;
}
if (current === total) {
$("#rhcounter .count").addClass("red");
}
// instant timer to delay css
setTimeout(function () {
var tiles = [false, false, false, false],
currStr = (current + "").split("").reverse().join("");
for (var i = 0; i < currStr.length; i++) {
if (currStr[i] !== prevTiles[i]) {
tiles[i] = true;
prevTiles[i] = currStr[i];
}
}
tiles.forEach(function (tile, index) {
if (!tile) {
return;
}
// Get the current tile
var $tile = $("#rhcounter div.tile" + index);
$tile.children('span.curr').each(function () {
$(this).text($tile.text());
});
$tile.removeClass("flip");
setTimeout(function () {
$tile.addClass("flip");
}, 5);
var top = $tile.find("span.count.next.top"),
bottom = $tile.find("span.count.next.bottom"),
delay = (index === 0 ? timeout : 250);
setTimeout(function () {
top.text(prevTiles[index]);
}, delay / 2);
setTimeout(function () {
bottom.text(prevTiles[index]);
}, delay / 2);
});
}, 1);
};
});
that was happening because you were changing color before changing text. i just shifted if condition and i think that is what you wanted DEMO
$(window).load(function() {
var total = 1000, current = 950, timeout = 150, inc = 7,
prevTiles = ["0","0","0","0"],
interval = setInterval(function(){increase()}, timeout),
increase = function () {
current += inc;
if (current >= total) {
clearInterval(interval);
current = total;
}
var tiles = [false, false, false, false],
currStr = (current+"").split("").reverse().join("");
for (var i = 0; i < currStr.length; i++) {
if (currStr[i] !== prevTiles[i]) {
tiles[i] = true;
prevTiles[i] = currStr[i];
}
}
tiles.forEach(function (tile, index) {
if (!tile) { return; }
$("#rhcounter > div[class~='tile"+index+"'] > span[class~='curr']").each(function() {
$(this).text($("#rhcounter > div[class~='tile"+index+"'] > span.count.next.top").text());
});
$("#rhcounter > div[class~='tile"+index+"']").removeClass("flip");
setTimeout(function(){$("#rhcounter > div[class~='tile"+index+"']").addClass("flip");}, 5);
var top = $("#rhcounter > div[class~='tile"+index+"'] > span.count.next.top"),
bottom = $("#rhcounter > div[class~='tile"+index+"'] > span.count.next.bottom"),
delay = (index === 0 ? timeout : 250);
setTimeout(function(){ top.text(prevTiles[index]); }, delay/2);
setTimeout(function(){ bottom.text(prevTiles[index]); }, delay/2);
});
if (current === total) {
$("#rhcounter .count").addClass("red");
}};
});
Looking at Secrets of the JavaScript Ninja, I took this code for a "Central Timer":
var timers = {
timerID: 0,
timers: [],
add: function(fn) {
this.timers.push(fn);
},
start: function() {
if(this.timerID) return;
(function runNext() {
if(timers.timers.length > 0) {
for (var i = 0; i < timers.length; i++) {
if(timers.timers[i]() === false) {
timers.timers.splice(i,1);
i--;
}
}
console.log("setting timeout.");
timers.timerID = setTimeout(runNext, 0);
}
})();
},
stop: function() {
clearTimeout(this.timerID);
this.timerID = 0;
}
};
Then, test it out.
var box = document.getElementById("box"), x = 0, y = 20;
timers.add(function() {
box.style.left = x + "px";
log.console("x:", x);
if(++x > 50) return false;
});
timers.add(function() {
box.style.top = y + "px";
y += 2;
log.console("y:", y);
if (++y > 120) return false;
});
console.log("starting timer.");
But, looking at my console, I see setting timeout scrolling endlessly without any increment to x or y.
What's going on here?
JsFiddle
EDIT Page # - 210/394.
Note - it's possible I made a copy/paste mistake - not blaming.
timers.length is undefined in the for loop in runNext, so the code does not actually iterate over the intended array. Either you transcribed it incorrectly or the code in the book has a bug. Regardless, this is the correct loop:
// ↓↓↓↓↓↓↓
for (var i = 0; i < timers.timers.length; i++) {
if(timers.timers[i]() === false) {
timers.timers.splice(i,1);
i--;
}
}
Fiddle
I want to do a count down and want to show like format as Minutes:Seconds:Milliseconds. I made a count down with jquery plug-in countdown but it shows just Minutes:Seconds format.
Is there any way to make it right?
Many Thanks!
Hi guys I have developed a code for my self use the following code
counter for 20 seconds
var _STOP =0;
var value=1999;
function settimer()
{
var svalue = value.toString();
if(svalue.length == 3)
svalue = '0'+svalue;
else if(svalue.length == 2)
svalue = '00'+svalue;
else if(svalue.length == 1)
svalue = '000'+svalue;
else if(value == 0)
svalue = '0000';
document.getElementById('cn1').innerHTML = svalue[0];
document.getElementById('cn2').innerHTML = svalue[1];
document.getElementById('cn3').innerHTML = svalue[2];
document.getElementById('cn4').innerHTML = svalue[3];
value--;
if (_STOP==0 && value>=0) setTimeout("settimer();", 10);
}
setTimeout("settimer()", 10);
Try this: http://jsfiddle.net/aamir/TaHtz/76/
HTML:
<div id="timer"></div>
JS:
var el = document.getElementById('timer');
var milliSecondsTime = 10000;
var timer;
el.innerHTML = milliSecondsTime/1000;
timer = setInterval(function(){
milliSecondsTime = milliSecondsTime - 1000;
if(milliSecondsTime/1000 == 0) {
clearTimeout(timer);
el.innerHTML = 'BOOOOM';
}
else {
el.innerHTML = milliSecondsTime/1000;
}
},1000);
If you want to make your own timer.
read this earlier question
How to create a JQuery Clock / Timer
Try setting the format parameter - http://keith-wood.name/countdownRef.html#format
On further reading, this plugin doesn't do milliseconds. At this point, you either have to edit the actual plugin code or find a new plugin.
I completely agree with #Matt Ball's comment.It may also cause the browser to crash.
Why don't you try this solution instead
jQuery 1 minute countdown with milliseconds and callback
I did it like this (generic counter from N to X (X > N)):
var dynamicCounterAddNewValue = 20;
var currentDynamicUpdater;
function dynamicCounterForValueForControlUpdater(_updaterData) {
_updaterData.from += dynamicCounterAddNewValue;
if (_updaterData.from > _updaterData.to) {
_updaterData.from = _updaterData.to;
}
_updaterData.c.html(_updaterData.from.toString());
if (_updaterData.from < _updaterData.to) {
currentDynamicUpdater = setTimeout(
dynamicCounterForValueForControlUpdater,
10,
{
c: _updaterData.c,
from: _updaterData.from,
to: _updaterData.to
}
);
}
else {
clearTimeout(currentDynamicUpdater);
}
return;
}
// _c -> jQuery object (div,span)
// _from -> starting number
// _to -> ending number
function dynamicCounterForValueForControl(_c, _from, _to) {
clearTimeout(currentDynamicUpdater);
dynamicCounterForValueForControlUpdater(
{
c: _c,
from: _from,
to: _to
}
);
return;
}
EDIT: Updated version (more flexible - for N elements one after another):
(input element is Array of elements for making them dynamic-counts)
var dynamicCounterTimeout = 10;
var currentDynamicUpdater;
function odcArray(_odca) {
this.odca = _odca;
return;
}
function odc(_c, _from, _to) {
this.c = _c; // $('#control_id')
this.from = _from; // e.g. N
this.to = _to; // e.g. M => (M >= N)
var di = parseInt(_to / 45, 10);
if (di < 1) {
di = 1;
}
this.dynamicInc = di;
return;
}
function dynamicCounterForValueForControlUpdater(_odca) {
if (
_odca.odca === null
||
!_odca.odca.length
) {
clearTimeout(currentDynamicUpdater);
return;
}
var o = _odca.odca[0];
o.from += o.dynamicInc;
if (o.from > o.to) {
o.from = o.to;
_odca.odca.shift(); // Remove first element
}
o.c.html(o.from.toString());
currentDynamicUpdater = setTimeout(
dynamicCounterForValueForControlUpdater,
dynamicCounterTimeout,
_odca
);
return;
}
function dynamicCounterForValueForControl(_odca) {
clearTimeout(currentDynamicUpdater);
// SETUP all counters to default
for (var i = 0; i < _odca.odca.length; i++) {
_odca.odca[i].c.html(_odca.odca[i].from.toString());
}
dynamicCounterForValueForControlUpdater(
_odca
);
return;
}