I wish to create a feature where the letters are typed in between a sentence as it is done in this page .
In the above link there is a sentence inside the banner that says
Create meaningful documents
Create persuasive documents
Create impactful documents
If you notice, the 2nd word is changing while the first and the third word remains the same, can anyone please tell how this animated feature can be achieved
This can be done using javascript. Here is a plugin that i made that types letters using setInterval() function.
Original Demo:
typer = function(e, s, d, t) {
var eI = 0;
var speed = s;
var delay = d;
var eLength = t.length;
var z = 1;
function loop() {
var p = $("<div class='azy-typer-container azy-typer-done'></div>");
var c_t = $("<span class='azy-typer-element'></span>")
var c_b = $("<span class='azy-typer-blinker'>|</span>");
$(".azy-typer-blinker").remove();
p.append(c_t).append(c_b);
$(e).append(p);
interval = setInterval(function() {
c_t.text(t[eI].substring(0, z));
if (z + 1 > t[eI].length) {
clearInterval(interval);
eI = eI + 1;
if (eI + 1 <= t.length) {
z = 0;
setTimeout(loop, d);
}
} else {
z = z + 1;
}
}, s)
}
loop();
}
new typer(".container", 100, 1000, ["Hi there!", "This is a typer demo ", "What do you think about this ?"]);
body {
background: black;
}
span {
font-family: "Courier New";
font-size: 24px;
color: #fff;
font-weight: bold;
}
.azy-typer-blinker {
animation: blink 1s infinite;
}
#keyframes blink {
0% {
color: crimson;
}
50% {
color: transparent;
}
100% {
color: crimson;
}
}
.azy-typer-done {
margin-left: 24px;
}
.azy-typer-done:before {
content: ">>";
color: lightgreen;
font-family: "Courier New";
font-size: 24px;
margin-left: -24px;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container"></div>
You can do some changes to make this code work as you need
typer = function(e, s, d, t) {
var eI = 0;
var speed = s;
var delay = d;
var eLength = t.length;
var z = 1;
function loop() {
var p = $("<div class='azy-typer-container'></div>");
var c_t = $("<span class='azy-typer-element'></span>")
var c_b = $("<span class='azy-typer-blinker'>|</span>");
$(".azy-typer-blinker").remove();
p.append(c_t).append(c_b);
$(e).append(p);
interval = setInterval(function() {
c_t.text(t[eI].substring(0, z));
if (z + 1 > t[eI].length) {
p.addClass("azy-typer-done");
clearInterval(interval);
eI = eI + 1;
if (eI + 1 <= t.length) {
z = 0;
setTimeout(loop, d);
} else {
eI = 0;
z = 0;
setTimeout(loop, d);
}
} else {
z = z + 1;
}
}, s)
}
loop();
}
new typer(".container", 100, 1000, ["Hi there!", "This is a typer demo ", "What do you think about this ?"]);
body {
background: black;
}
span {
font-family: "Courier New";
font-size: 24px;
color: #fff;
font-weight: bold;
}
.azy-typer-blinker {
color: maroon;
}
.azy-typer-container {
display: inline;
}
.azy-typer-done {
display: none;
}
.static {
color: lime;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<span class="static">Static </span>
</div>
The function takes four arguments
The element to which the text is to be appended
The typing speed
The delay for the next item to appear
The text (should be an array)
Related
I am building a terminal like personal website and I want to display a welcome banner + message after one another. I have this cool effect where individual lines appear from top to bottom and characters from left to right (See here for yourself).
My problem is that the welcome banner and the welcome message are mixed up with one another. Thus, I want to wait until the banner is printed before printing the message. However something about my code must be wrong... (I tried using await/async) ...
Here you have a small reproducible example of the issue. All lines with the character "a" should be printed before lines with character "b". Can you please point out what the root of the problem is?
banner = ["aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa"]
welcomeMsg = ["bbbbbbbbbbbb", "bbbbbbbbbbbb", "bbbbbbbbbbbb", "bbbbbbbbbbbb"]
var before = document.getElementById("before");
setTimeout(async function() {
await loopLines(banner, "", 80);
loopLines(welcomeMsg, "", 80);
}, 100);
async function addLine(text, style, time) {
var t = "";
for (let i = 0; i < text.length; i++) {
if (text.charAt(i) == " " && text.charAt(i + 1) == " ") {
t += " ";
i++;
} else {
t += text.charAt(i);
}
}
setTimeout(function() {
var next = document.createElement("p");
next.innerHTML = t;
next.className = style;
before.parentNode.insertBefore(next, before);
window.scrollTo(0, document.body.offsetHeight);
}, time);
return;
}
async function loopLines(name, style, time) {
for (var i = 0; i < name.length; i++) {
await addLine(name[i], style, i * time);
}
return;
}
p {
display: block;
line-height: 1.3em;
margin: 0;
overflow: hidden;
/* white-space: nowrap; */
margin: 0;
letter-spacing: 0.05em;
animation: typing 0.5s steps(30, end);
/* font-size: calc(2vw + 7px); */
font-size: min(20px, calc(1.5vw + 7px));
}
#keyframes typing {
from {
width: 0;
}
to {
width: 100%;
}
}
<a id="before"></a>
In addLine you don't use await. Instead you call setTimeout, but that doesn't return a pending promise. So the promise returned by addLine resolves immediately without waiting for the timeout to complete.
To change that, make use of a promisified version of setTimeout. I have added its definition at the top of the snippet. Then see where addLine uses it instead of setTimeout:
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
banner = ["aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaa"]
welcomeMsg = ["bbbbbbbbbbbb", "bbbbbbbbbbbb", "bbbbbbbbbbbb", "bbbbbbbbbbbb"]
var before = document.getElementById("before");
setTimeout(async function() {
await loopLines(banner, "", 80);
loopLines(welcomeMsg, "", 80);
}, 100);
async function addLine(text, style, time) {
var t = "";
for (let i = 0; i < text.length; i++) {
if (text.charAt(i) == " " && text.charAt(i + 1) == " ") {
t += " ";
i++;
} else {
t += text.charAt(i);
}
}
await delay(time); // <---------------
var next = document.createElement("p");
next.innerHTML = t;
next.className = style;
before.parentNode.insertBefore(next, before);
window.scrollTo(0, document.body.offsetHeight);
}
async function loopLines(name, style, time) {
for (var i = 0; i < name.length; i++) {
await addLine(name[i], style, i * time);
}
}
p {
display: block;
line-height: 1.3em;
margin: 0;
overflow: hidden;
/* white-space: nowrap; */
margin: 0;
letter-spacing: 0.05em;
animation: typing 0.5s steps(30, end);
/* font-size: calc(2vw + 7px); */
font-size: min(20px, calc(1.5vw + 7px));
}
#keyframes typing {
from {
width: 0;
}
to {
width: 100%;
}
}
<a id="before"></a>
I'm trying to create a quiz that tests users awareness of real and fake emails. What I want to do is have the question displayed at the top saying "Real or Fake", then have an image displayed underneath which the user needs to look at to decided if it's real or fake. There are two buttons, real and fake, and regardless of whether they choose the right answer I want to swap the original image with annotated version - showing how users could spot that it was fake or real.
But I'm not sure how to show the annotated version once the answer has been submitted. Could someone help?
function Quiz(questions) {
this.score = 0;
this.questions = questions;
this.questionIndex = 0;
}
Quiz.prototype.getQuestionIndex = function() {
return this.questions[this.questionIndex];
}
Quiz.prototype.guess = function(answer) {
if (this.getQuestionIndex().isCorrectAnswer(answer)) {
this.score++;
}
this.questionIndex++;
}
Quiz.prototype.isEnded = function() {
return this.questionIndex === this.questions.length;
}
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
Question.prototype.isCorrectAnswer = function(choice) {
return this.answer === choice;
}
function populate() {
if (quiz.isEnded()) {
showScores();
} else {
// show question
var element = document.getElementById("question");
element.innerHTML = quiz.getQuestionIndex().text;
// show options
var choices = quiz.getQuestionIndex().choices;
for (var i = 0; i < choices.length; i++) {
var element = document.getElementById("choice" + i);
element.innerHTML = choices[i];
guess("btn" + i, choices[i]);
}
showProgress();
}
};
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populate();
}
};
function showProgress() {
var currentQuestionNumber = quiz.questionIndex + 1;
var element = document.getElementById("progress");
element.innerHTML = "Question " + currentQuestionNumber + " of " + quiz.questions.length;
};
function showScores() {
var gameOverHTML = "<h1>Result</h1>";
gameOverHTML += "<h2 id='score'> Your scores: " + quiz.score + "</h2>";
var element = document.getElementById("quiz");
element.innerHTML = gameOverHTML;
};
// create questions here
var questions = [
new Question("<img src= 'netflix_fake.jpg' />", ["Real", "Fake"], "Fake"),
new Question("<img src= 'dropbox_real.jpg' />", ["Real", "Fake"], "Real"),
new Question("<img src= 'gov_real.jpg' />", ["Real", "Fake"], "Real"),
new Question("<img src= 'paypal_fake.jpg' />", ["Real", "Fake"], "Fake"),
new Question("<img src= 'gmail.jpg' />", ["Real", "Fake"], "Fake")
];
//create quiz
var quiz = new Quiz(questions);
// display
populate();
body {
background-color: #538a70;
}
.grid {
width: 600px;
height: 500px;
margin: 0 auto;
background-color: #fff;
padding: 10px 50px 50px 50px;
border: 2px solid #cbcbcb;
}
.grid h1 {
font-family: "sans-serif";
font-size: 60px;
text-align: center;
color: #000000;
padding: 2px 0px;
}
#score {
color: #000000;
text-align: center;
font-size: 30px;
}
.grid #question {
font-family: "monospace";
font-size: 30px;
color: #000000;
}
.buttons {
margin-top: 30px;
}
#btn0,
#btn1,
#btn2,
#btn3 {
background-color: #a0a0a0;
width: 250px;
font-size: 20px;
color: #fff;
border: 1px solid #1D3C6A;
margin: 10px 40px 10px 0px;
padding: 10px 10px;
}
#btn0:hover,
#btn1:hover,
#btn2:hover,
#btn3:hover {
cursor: pointer;
background-color: #00994d;
}
#btn0:focus,
#btn1:focus,
#btn2:focus,
#btn3:focus {
outline: 0;
}
#progress {
color: #2b2b2b;
font-size: 18px;
}
<div class="grid">
<div id="quiz">
<h1>Can you spot the fake email?</h1>
<hr style="margin-bottom: 20px">
<p id="question"></p>
<div class="buttons">
<button id="btn0"><span id="choice0"></span></button>
<button id="btn1"><span id="choice1"></span></button>
</div>
<hr style="margin-top: 50px">
<footer>
<p id="progress">Question x of y</p>
</footer>
</div>
</div>
When user clicks button I trigger class and I add it second name, on second I have written to get swapped, I wrote you basically full project, and please read the whole comments, to understand logic
//Calling Elements from DOM
const button = document.querySelectorAll(".check");
const images = document.querySelectorAll(".image");
const answer = document.querySelector("h1");
//Declaring variable to randomly insert any object there to insert source in DOM Image sources
let PreparedPhotos;
//Our Images Sources and With them are its fake or not
//fake: true - yes its fake
//fake: false - no its real
const image = [
[
{
src:
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/1200px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg",
fake: true
},
{
src:
"http://graphics8.nytimes.com/images/2012/04/13/world/europe/mona-lisa-like-new-images/mona-lisa-like-new-images-custom4-v3.jpg",
fake: false
}
],
[
{
src:
"https://cdn.shopify.com/s/files/1/0849/4704/files/Creacion_de_Adan__Miguel_Angel_f5adb235-bfa8-4caa-8ffb-c5328cbad953_grande.jpg?12799626327330268216",
fake: false
},
{
src:
"https://cdn.shopify.com/s/files/1/0849/4704/files/First-image_Fb-size_grande.jpg?10773543754915177139",
fake: true
}
]
];
//Genrating Random Photo on HTML
function setRandomPhoto() {
//Random Number which will be length of our array of Object
//if you array includes 20 object it will generate random number
// 0 - 19
const randomNumber = Math.floor(Math.random() * image.length);
//Decalaring our already set variable as Array Object
PreparedPhoto = image[randomNumber];
//Our first DOM Image is Variables first object source
images[0].src = PreparedPhoto[0].src;
//and next image is next object source
images[1].src = PreparedPhoto[1].src;
}
//when windows successfully loads, up function runs
window.addEventListener("load", () => {
setRandomPhoto();
});
//buttons click
//forEach is High Order method, basically this is for Loop but when you want to
//trigger click use forEach - (e) is single button whic will be clicked
button.forEach((e) => {
e.addEventListener("click", () => {
//decalring variable before using it
let filtered;
//finding from our DOM image source if in our long array exists
//same string or not as Image.src
//if it exists filtered variable get declared with that found obect
for (let i = 0; i < image.length; i++) {
for (let k = 0; k < 2; k++) {
if (image[i][k].src === images[0].src) {
filtered = image[i][k];
}
}
}
//basic if else statement, if clicked button is Fake and image is true
//it outputs You are correct
//if clicked button is Real and Image is false it outputs Correct
//Else its false
//Our image checking comes from filtered variable
if (e.innerText === "Fake" && filtered.fake === true) {
answer.innerText = "You Are Correct";
images.forEach((image) => {
image.classList.toggle("hidden");
});
} else if (e.innerText === "Real" && filtered.fake === false) {
answer.innerText = "You Are Correct";
images.forEach((image) => {
image.classList.toggle("hidden");
});
} else {
answer.innerHTML = "You are Wrong";
images.forEach((image) => {
image.classList.toggle("hidden");
});
}
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100%;
min-height: 100vh;
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column;
}
.image-fluid {
display: flex;
}
.image-fluid .image {
width: 200px;
margin: 0 10px;
transition: 0.5s;
}
.image-fluid .image:nth-child(1).hidden {
transform: translateX(110px);
}
.image-fluid .image:nth-child(2).hidden {
transform: translateX(-110px);
}
<div class="container">
<div class="image-fluid">
<img src="" class="image hidden">
<img src="" class="image hidden">
</div>
<div class="button-fluid">
<button class="check">Fake</button>
<button class="check">Real</button>
</div>
</div>
<h1></h1>
I have 2 audiofiles, but when I trigger one function, in this case 'setCurTime37()' I do hear the right audiofile ('myAudios1'), but it also triggers downloading the second audio file ('myAudios2'). These are only 2 files, in reality there are 36, so it causes a lot of MB to download. I can't understand why this happens.
<script>
var x = document.getElementById("mymenub").selectedIndex;
var ya1 = document.getElementById("myAudios1");
var loopLimit = document.getElementsByTagName("option")[x].value;
var loopCounter = 0;
ya1.preload = "none";
function setCurTime37() {
if ((document.getElementById("precountb").checked==false) && ((ya1.currentTime < 0.1) || (document.getElementById("myAudios1").ended==true))) {
ya1.currentTime = 16.20;
loopCounter = 0;
ya1.playbackRate = document.getElementById("pbr2").value;
ya1.play();
}
else if ((document.getElementById("precountb").checked==false) && (ya1.currentTime > 0.1)) {
loopCounter = 0;
ya1.playbackRate = document.getElementById("pbr2").value;
ya1.play();
}
else if ((document.getElementById("precountb").checked==true) && (ya1.currentTime < 0.1)) {
ya1.currentTime = 0;
loopCounter = 0;
ya1.playbackRate = document.getElementById("pbr2").value;
ya1.play();
}
else if ((document.getElementById("precountb").checked==true) && (ya1.currentTime > 0.1)) {
loopCounter = 0;
ya1.playbackRate = document.getElementById("pbr2").value;
ya1.play();
}
}
document.getElementById("Pause_sb").addEventListener("click", xx37);
function xx37() {
ya1.pause();
}
document.getElementById("Stop_sb").addEventListener("click", zz37);
function zz37() {
ya1.load();
}
ya1.onended = function() {
var x = document.getElementById("mymenub"); loopLimit = parseFloat(x.options[x.selectedIndex].value, 10);
if ((loopCounter < loopLimit) &&(document.getElementById("precountb").checked==false)){
this.currentTime = 16.20;
this.play();
loopCounter++;
}
else if ((loopCounter < loopLimit) && (document.getElementById("precountb").checked==true)){
this.currentTime = 16.20;
this.play();
loopCounter++;
}
};
</script>
<script>
var x = document.getElementById("mymenub").selectedIndex;
var ya2 = document.getElementById("myAudios2");
var loopLimit = document.getElementsByTagName("option")[x].value;
var loopCounter = 0;
ya2.preload = "none";
function setCurTime38() {
if ((document.getElementById("precountb").checked==false) && ((ya2.currentTime < 0.1) || (document.getElementById("myAudios2").ended==true))) {
ya2.currentTime = 16.20;
loopCounter = 0;
ya2.playbackRate = document.getElementById("pbr2").value;
ya2.play();
}
else if ((document.getElementById("precountb").checked==false) && (ya2.currentTime > 0.1)) {
loopCounter = 0;
ya2.playbackRate = document.getElementById("pbr2").value;
ya2.play();
}
else if ((document.getElementById("precountb").checked==true) && (ya2.currentTime < 0.1)) {
ya2.currentTime = 0;
loopCounter = 0;
ya2.playbackRate = document.getElementById("pbr2").value;
ya2.play();
}
else if ((document.getElementById("precountb").checked==true) && (ya2.currentTime > 0.1)) {
loopCounter = 0;
ya2.playbackRate = document.getElementById("pbr2").value;
ya2.play();
}
}
document.getElementById("Pause_sb").addEventListener("click", xx38);
function xx38() {
ya2.pause();
}
document.getElementById("Stop_sb").addEventListener("click", zz38);
function zz38() {
ya2.load();
}
ya2.onended = function() {
var x = document.getElementById("mymenub"); loopLimit = parseFloat(x.options[x.selectedIndex].value, 10);
if ((loopCounter < loopLimit) &&(document.getElementById("precountb").checked==false)){
this.currentTime = 16.20;
this.play();
loopCounter++;
}
else if ((loopCounter < loopLimit) && (document.getElementById("precountb").checked==true)){
this.currentTime = 16.20;
this.play();
loopCounter++;
}
};
</script>
Don't load any audio files at all. Use a playlist of links.
// Collect all links into NodeList convert to Array
var linx = Array.from(document.links);
// On each iteration add the click event to each link
for (let i = 0; i < linx.length; i++) {
linx[i].onclick = playlist;
}
// playlist() function -- pass Event Object
function playlist(event) {
// reference Audio tag
var player = document.getElementById('player');
// Get the url of the clicked link href
var file = this.href;
// Set Audio src to url of the clicked link
player.src = file;
// Load the Audio tag
player.load();
// Play the Audio tag
player.play();
}
* {
margin: 0;
padding: 0;
}
:root {
font: 400 16px/1.3 Verdana;
}
html,
body {
width: 100%;
width: 100%;
}
body {
overflow-x: hidden;
overflow-y: scroll;
}
audio {
cursor: pointer;
width: 450px;
}
#playlist {
width: 450px;
background: rgba(111, 111, 111, 0.1);
}
.header {
outline: 0;
cursor: pointer;
padding: 3px 5px;
margin-bottom: -6px;
font-size: 1.25rem;
}
.header:hover {
color: rgba(122, 01, 23, 0.5)
}
dl {
padding: 8px 4px;
}
dt {
margin: 8px;
border-bottom: 3px ridge cyan
}
dt:first-of-type {
margin-top: 2px
}
dd {
text-indent: 18px;
}
a {
color: rgba(0, 11, 111, 0.7)
}
a:hover {
color: rgba(0, 0, 224, 0.4);
}
<audio id='player' src='' controls name='player'></audio>
<details id='playlist'>
<summary class='header'>Playlist</summary>
<dl>
<dt>Sound fX</dt>
<dd>
<a href='http://soundbible.com/mp3/chinese-gong-daniel_simon.mp3' target='player'>Gong</a>
</dd>
<dd>
<a href='http://soundbible.com/mp3/Fake%20Applause-SoundBible.com-1541144825.mp3' target='player'>Applause</a>
</dd>
<dd>
<a href='http://soundbible.com/mp3/thunder_strike_1-Mike_Koenig-739781745.mp3' target='player'>Thunder</a>
</dd>
<dd>
<a href='http://soundbible.com/mp3/Gun_war-MysteryMan229-1208990486.mp3' target='player'>Machine Gun</a>
</dd>
<dd>
<a href='http://soundbible.com/mp3/Heart%20Rate%20Monitor%20Flatline-SoundBible.com-2063567528.mp3' target='player'>Flatline</a>
</dd>
<dt>Songs</dt>
<dd>
<a href='https://gldrv.s3.amazonaws.com/av/Florence_and_the_Machine-Dog_%20Days_are_Over.mp3' target='player'>Dog Days are Over - Florence and the Machine</a>
</dd>
<dt>Monologue</dt>
<dd>
<a href='https://od.lk/s/NzlfOTEwMzM5OV8/righteous.mp3' target='player'>Ezekiel 25:17 - Samuel L. Jackson - Pulp Fiction</a>
</dd>
<dt>Clips</dt>
<dd>
<a href='https://od.lk/s/NzlfOTEyMzgyNF8/jerky.mp3' target='player'>Jerky Boys</a>
</dd>
</dl>
</details>
I want to split the sentence when i click on the space. He has to make 2 parts of the sentence. I want that i click another time on a space and then to make 3 parts of the sentence.
I've tried to search on google, stackoverflow, etc. But i don't see my answer.
So this is my code.
$(function() {
$(document).data("text", $("#editor").text())
.on("mousedown", function() {
$("#editor")
.html($(this)
.data("text"))
})
.on("mouseup", function() {
that = $("#editor");
var sel = window.getSelection ? window.getSelection() : document.selection();
var o = that.text();
var before = sel.baseOffset;
var after = o.length - before;
var a = o.slice(0, before);
var b = after === 0 ? "" : o.slice(-after);
var n = "<data>||</data>";
var html = (after === "" ? a + n : a + n + b);
that.html(html);
});
})
#editor {
font-family: Sans;
font-size: 28px;
letter-spacing: 8px;
white-space: pre;
}
#editor > data {
color: red;
max-width: .1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="editor">Hello! I am a Text!</div>
So i hope i've i have the sentence: Hello this is a test. And then click between 'is' and 'a':
Hello this is a test.
$(function() {
jQuery.fn.reverse = [].reverse;
// Add element around all characters
var text = $("#editor").text();
var newText = "";
for (var i = 0; i < text.length; i++) {
newText += `<span>${text[i]}</span>`;
}
$("#editor").html(newText);
// If you click on a space
$("#editor").on("click", "span", function() {
if ($(this).text() == " ") {
var before = $(this).prevAll().reverse();
var after = $(this).nextAll()
$("#editor").html("");
before.each(function() {
if (!$(this).hasClass("white")) {
$("#editor").append(`<span class="yellow">${$(this).text()}</span>`);
} else {
$("#editor").append(`<span class="white">${$(this).text()}</span>`);
}
});
$("#editor").append(`<span class="white"> </span>`);
after.each(function() {
if (!$(this).hasClass("white")) {
$("#editor").append(`<span class="yellow">${$(this).text()}</span>`);
} else {
$("#editor").append(`<span class="white">${$(this).text()}</span>`);
}
});
}
});
})
#editor {
font-family: Sans;
font-size: 28px;
letter-spacing: 8px;
white-space: pre;
}
#editor .br {
color: red;
max-width: .1em;
}
#editor .yellow {
background-color: yellow;
}
#editor .white {
background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="editor">Hello! I am a Text</div>
--- Old answer below
This should be a good start. You can do whatever you want with the variables before and after - so that is suits your case.
$(function() {
jQuery.fn.reverse = [].reverse;
// Add element around all characters
var text = $("#editor").text();
var newText = "";
for (var i = 0; i < text.length; i++) {
newText += `<span>${text[i]}</span>`;
}
$("#editor").html(newText);
// If you click on a space
$("#editor").on("click", "span", function() {
if ($(this).text() == " ") {
var before = $(this).prevAll().reverse();
var after = $(this).nextAll()
$("#editor").html("");
before.each(function() {
$("#editor").append(`<span>${$(this).text()}</span>`);
});
$("#editor").append(`<span class="br">|</span>`);
after.each(function() {
$("#editor").append(`<span>${$(this).text()}</span>`);
});
}
});
})
#editor {
font-family: Sans;
font-size: 28px;
letter-spacing: 8px;
white-space: pre;
}
#editor .br {
color: red;
max-width: .1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="editor">Hello! I am a Text</div>
I've been wanting to create a timer for my website that countsup, and displays alerts at certain intervals. So like, it starts from 0 and counts upwards when the user pushes a button. From there, it will display a a custom alert at certain intervals... (4 minutes for example)... 45 seconds before that interval, I need the number to change to yellow and 10 seconds before that interval, I need it to change to red... then back to the normal color when it passes that interval.
I've got a basic timer code but I am not sure how to do the rest. I am quite new to this. Any help? Thanks so much in advance.
var pad = function(n) { return (''+n).length<4?pad('0'+n):n; };
jQuery.fn.timer = function() {
var t = this, i = 0;
setInterval(function() {
t.text(pad(i++));
}, 1000);
};
$('#timer').timer();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='timer'></div>
You could do something like this
var pad = function (n) {
return ('' + n).length < 4 ? pad('0' + n) : n;
};
jQuery.fn.timer = function () {
var t = this,
i = 0;
setInterval(function () {
t.text(pad(i++));
checkTime(i, t);
}, 1000);
};
$('#timer').timer();
checkTime = function (time, t) {
switch (time -1) {
case 10:
t.css('color','red');
break;
case 20:
t.css('color','yellow');
break;
case 30:
t.css('color','green');
break;
case 40:
t.css('color','black');
break;
default:
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='timer'></div>
Something like this should work:
Here is a jsFiddle DEMO
jQuery
$.fn.timer = function (complete, warning, danger) {
var $this = $(this);
var total = 0;
$this.text(total);
var intervalComplete = parseInt(complete, 10);
var intervalWarning = parseInt(intervalComplete - warning, 10);
var intervalDanger = parseInt(intervalComplete - danger, 10);
var clock = setInterval(function () {
total += 1;
$this.text(total);
if (intervalWarning === total) {
// set to YELLOW:
$this.addClass('yellow');
}
if (intervalDanger === total) {
// set to RED:
$this.removeClass('yellow').addClass('red');
}
if (intervalComplete === total) {
// reset:
clearInterval(clock);
$this.removeClass();
alert('COMPLETE!');
}
}, 1000);
};
$(function () {
$('#timer').timer(240, 45, 10);
});
CSS
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
An additional point:
You should place some error validation within the function to ensure your counter completion time is greater than both the warning and danger time intervals.
You can try something like this:
JSFiddle
This is a pure JS timer code. Also for popup you can use something like Bootbox.js.
Code
function timer() {
var time = {
sec: 00,
min: 00,
hr: 00
};
var finalLimit = null,
warnLimit = null,
errorLimit = null;
var max = 59;
var interval = null;
function init(_hr, _min, _sec) {
time["hr"] = _hr ? _hr : 0;
time["min"] = _min ? _min : 0;
time["sec"] = _sec ? _sec : 0;
printAll();
}
function setLimit(fLimit, wLimit, eLimit) {
finalLimit = fLimit;
warnLimit = wLimit;
errorLimit = eLimit;
}
function printAll() {
print("sec");
print("min");
print("hr");
}
function update(str) {
time[str] ++;
time[str] = time[str] % 60;
if (time[str] == 0) {
str == "sec" ? update("min") : update("hr");
}
print(str);
}
function print(str) {
var _time = time[str].toString().length == 1 ? "0" + time[str] : time[str];
document.getElementById("lbl" + str).innerHTML = _time;
}
function validateTimer() {
var c = "";
var secs = time.sec + (time.min * 60) + (time.hr * 60 * 60);
console.log(secs, finalLimit)
if (secs >= finalLimit) {
stopTimer();
} else if (secs >= errorLimit) {
c = "error";
} else if (secs >= warnLimit) {
c = "warn";
} else {
c = "";
}
var element = document.getElementsByTagName("span");
console.log(element, c)
document.getElementById("lblsec").className = c;
}
function startTimer() {
init();
if (interval) stopTimer();
interval = setInterval(function() {
update("sec");
validateTimer();
}, 1000);
}
function stopTimer() {
window.clearInterval(interval);
}
function resetInterval() {
stopTimer();
time["sec"] = time["min"] = time["hr"] = 0;
printAll();
startTimer();
}
return {
'start': startTimer,
'stop': stopTimer,
'reset': resetInterval,
'init': init,
'setLimit': setLimit
}
};
var time = new timer();
function initTimer() {
time.init(0, 0, 0);
}
function startTimer() {
time.start();
time.setLimit(10, 5, 8);
}
function endTimer() {
time.stop();
}
function resetTimer() {
time.reset();
}
span {
border: 1px solid gray;
padding: 5px;
border-radius: 4px;
background: #fff;
}
.timer {
padding: 2px;
margin: 10px;
}
.main {
background: #eee;
padding: 5px;
width: 200px;
text-align: center;
}
.btn {
-webkit-border-radius: 6;
-moz-border-radius: 6;
border-radius: 6px;
color: #ffffff;
font-size: 14px;
background: #2980b9;
text-decoration: none;
transition: 0.4s;
}
.btn:hover {
background: #3cb0fd;
text-decoration: none;
transition: 0.4s;
}
.warn {
background: yellow;
}
.error {
background: red;
}
<div class="main">
<div class="timer"> <span id="lblhr">00</span>
: <span id="lblmin">00</span>
: <span id="lblsec">00</span>
</div>
<button class="btn" onclick="startTimer()">Start</button>
<button class="btn" onclick="endTimer()">Stop</button>
<button class="btn" onclick="resetTimer()">Reset</button>
</div>
Hope it helps!