I'm making a webpage and I want to make "type" effect on form. After user waits for a while, it starts typing some text as an example, if possible - with cursor. I don't really know where to start though. I'm using jQuery.
Thanks in advance!
Animate the Placeholder
You might use the placeholder attribute to display example input. Static text is usually enough for most users. Yet, you could add an animation loop to simulate typing. Using the placeholder also allows you to display text without altering the form input value.
The example below uses a loop to simulate typing and stops with the user enters information. No jQuery required.
Run the snippet to demo
var timerId, placeholder = fullname.placeholder, n =0;
id = setInterval(function() {
if (fullname.value) {
// stop as user has typed something
clearInterval(id);
fullname.placeholder = placeholder;
}
else {
// show next character
fullname.placeholder = placeholder.substr(0,n);
n = (n+1) % (placeholder.length+1);
}
}, 400);
input {font-family: 'Special Elite', cursive; font-size:36px; border:1px solid steelblue;color:black; font-weight:bold;}
<link href='https://fonts.googleapis.com/css?family=Special+Elite' rel='stylesheet' type='text/css'>
<input id="fullname" placeholder="Berlin, Germany">
You can register a timeout function at form load using settimeout function.
If user presses a key you can cancel it.
The timeout function callback could set the placeholder of your input using jQuery.
Consider the inserted snippet to have an idea on how to start a proper implementation.
(function() {
"use strict";
var exampleText = "my example text";
var inactivityDelay = 2000;
var typeDelay = 200;
var interval;
var appendExample = function() {
var index = 0;
interval = setInterval(function() {
if (index >= exampleText.length) {
clearInterval(interval);
return;
}
var myinput = $("#myinput");
myinput.attr("placeholder", myinput.attr("placeholder") + exampleText.charAt(index++));
}, typeDelay);
};
var timeout = setTimeout(appendExample, inactivityDelay);
$("#myinput").on("change paste keyup focus", function() {
clearTimeout(timeout);
clearInterval(interval);
$("#myinput").attr("placeholder", "");
});
}());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input type="text" id="myinput" maxlength="100" placeholder="" />
</form>
Related
I am writing a simple spelling test app using the HTML5 SpeechSynthesis API. The text I would like my app to say is something like the following: "The spelling word is Cat. The cat chased the dog.".
The API tends to race without much of a pause from the first sentence to the second. I wonder if there is a way to insert a bit of a pause between the 2 sentences. I realize I could create 2 separate utterances and use the pause() call. However the code would be simpler and less brittle if I could simply insert grammatical hints.
Normally in spoken English, one tends to pause a little longer between paragraphs. So I inserted a newline character in my text, but there was no noticeable impact.
I also tried using an ellipsis.
Is there any way to do this or am I stuck breaking everything into separate utterances?
Using an exclamation point "!" adds a nice delay for some reason.
You can chain them together with periods to extend the pause.
"Example text! . ! . ! . !"
Split your text using comma (or custom delimiter) and add your own space using a timeout.
Here is a simple example as a proof-of-concept. Extending it, you can customize your text to include hints as to how long to pause.
function speakMessage(message, PAUSE_MS = 500) {
try {
const messageParts = message.split(',')
let currentIndex = 0
const speak = (textToSpeak) => {
const msg = new SpeechSynthesisUtterance();
const voices = window.speechSynthesis.getVoices();
msg.voice = voices[0];
msg.volume = 1; // 0 to 1
msg.rate = 1; // 0.1 to 10
msg.pitch = .1; // 0 to 2
msg.text = textToSpeak;
msg.lang = 'en-US';
msg.onend = function() {
currentIndex++;
if (currentIndex < messageParts.length) {
setTimeout(() => {
speak(messageParts[currentIndex])
}, PAUSE_MS)
}
};
speechSynthesis.speak(msg);
}
speak(messageParts[0])
} catch (e) {
console.error(e)
}
}
function run(pause) {
speakMessage('Testing 1,2,3', pause)
}
<button onclick='run(0)'>Speak No Pause</button>
<button onclick='run(500)'>Speak Pause</button>
<button onclick='run(1000)'>Speak Pause Longer</button>
Just insert
<silence msec="5000" />
in the text for 5 sec waiting (Source).
Disclaimer: This code works only in an appropriate user agent.
// code taken from https://richjenks.com/dev/speechsynthesis/
var utterance = new SpeechSynthesisUtterance(),
speak = document.getElementById("speak"),
text = document.getElementById("text");
// Delay links and events because speechSynthesis is funny
speechSynthesis.getVoices();
setTimeout(function () {
// Add event listeners
var voiceLinks = document.querySelectorAll(".voice");
for (var i = 0; i < voiceLinks.length; i++) {
voiceLinks[i].addEventListener("click", function (event) {
utterance.voice = speechSynthesis.getVoices()[this.dataset.voice];
});
}
}, 100);
// Say text when button is clicked
speak.addEventListener("click", function (event) {
utterance.text = text.value;
speechSynthesis.speak(utterance);
});
<textarea id="text" rows="5" cols="50">Hi <silence msec="2000" /> Flash!</textarea>
<br>
<button id="speak">Speak</button>
I’ve found inserting synthetic pauses using commas to be quite useful (as an making other manipulations). Here’s a little excerpt:
var speech = new SpeechSynthesisUtterance(),
$content = document.querySelector('main').cloneNode(true),
$space = $content.querySelectorAll('pre'),
$pause_before = $content.querySelectorAll('h2, h3, h4, h5, h6, p, li, dt, blockquote, pre, figure, footer'),
$skip = $content.querySelectorAll('aside, .dont_read');
// Don’t read
$skip.forEach(function( $el ){
$el.innerHTML = '';
});
// spacing out content
$space.forEach(function($el){
$el.innerHTML = ' ' + $el.innerHTML.replace(/[\r\n\t]/g, ' ') + ' ';
});
// Synthetic Pauses
$pause_before.forEach(function( $el ){
$el.innerHTML = ' , ' + $el.innerHTML;
});
speech.text = $content.textContent;
The key is to clone the content node first so you can work with it in memory rather than manipulating the actual content. It seems to work pretty well for me and I can control it in the JavaScript code rather than having to modify the page source.
I'm trying to create a game with dialogue, and I want my text to change as the player clicks on a next image to progress the story.
For example:
Page loads - "Hi, I'm Joe."
Clicks sliced Image once - "Nice to meet you."
Clicks 2nd time - "How are you?"
I have tried onClick but that only allows me to change it once, I've tried using var counter as well but to no avail, it overrides my previous commands, which part of this am I doing wrong here?
var clicks = 0;
function changeText() {
{
clicks = 1;
document.getElementById('text').innerHTML = "Ughh... my head... What
happened...?";
}
}
function changeText() {
{
clicks = 2;
document.getElementById('text').innerHTML = "Testing 1 2 3";
}
}
function play() {
var audio = document.getElementById("audio");
audio.play();
}
<img onClick="changeText(); audio.play()" value=Change Text src="images/awaken/images/awaken_03.jpg" alt="" width="164" height="77" id="clicks" />
<p id="text">Where... am I...?</p>
First off all - your changeText() system is flawed - you're overwriting the same function multiple times at the same time, so the only one of those that will ever get called is the last one you declare. JavaScript doesn't wait until a function gets called to continue with the program.
The audio.play() also won't work - but I'm assuming that's a work in progress.
I changed your code so that instead of setting count to a specific value, it increments every time the function gets called, and it updates the text to the correct value in an array. Here's the updated changeText function:
var count = 0;
var text = [
"Where... am I...?", /* note that this will never get called, it's simply here for filling up the array*/
"This is the first text!",
"And this is the second!"
]
var changeText = function() {
count++;
document.getElementById('text').innerHTML = text[count];
}
In the future, you'll probably also want to check if(text[count] != 'undefined'), and if so write something like "Bye!" instead.
Issues in your code
Multiple function declaration of changeText()
Extra {} in changeText()
You are not updating value of clicks.
In your html, you have written audo.play() but no audio object is available. It should be play(). I have called play() function in changeText() function. This keeps HTML clean.
Following is updated code:
var clicks = 0;
function changeText() {
var text = ""
clicks++;
switch(clicks){
case 1: text = "Ughh... my head... What happened...?";
break;
case 2: text = "Testing 1 2 3";
break;
}
document.getElementById('text').innerHTML = text;
play();
}
function play() {
var audio = document.getElementById("audio");
audio.play();
}
<img onClick="changeText()" value=Change Text src="images/awaken/images/awaken_03.jpg" alt="" width="164" height="77" id="clicks" />
<p id="text">Where... am I...?</p>
I have the following JavaScript configuration. It works well when it loads and keeps working well the first time I click on the button with id buttonKernel. This should run the function onPageLoad, which resets a grid presented on screen and reload the event handlers. The second time I click the button thought, after clicking OK on the prompt, it keeps prompting again. If I insist, it will eventually work.
I'm new to JavaScript, so that I don't know if this self calling function can be at the root of the problem.
$(document).ready(function(){
onPageLoad(16);
});
function onPageLoad(size){
genDiv(size);
$('.gridSquare').hover(function(){
$(this).css('background-color', 'red');
});
$('#buttonKernel').click(function(){
$(".gridSquare").css('background-color', 'yellow');
var input = prompt ("Enter a size for the grid", "16");
size = checkInp(input);
var list = document.getElementsByClassName("row");
for (var i = list.length - 1; 0 <= i; i--)
{
if (list[i] && list[i].parentElement)
list[i].parentElement.removeChild(list[i]);
};
onPageLoad(size);
});
}
every time you click, you add another click event handler.
Seems to be working fine for me?
http://jsfiddle.net/8atqub5k/1/
There are two unknown functions... genDiv(size) and checkInp(input) I have no clue what those do. Note: if there is a javascript error in either of those functions, generally javascript won't function at all on the rest of the site.
Are you aware of the Chrome browser Developer Tools? Way awesome tool for troubleshooting javascript (or html and CSS ) errors...
<style>
.gridSquare{
width: 100px;
height: 100px;
background-color: blue;
}
</style>
<button id="buttonKernel">Click here</button>
<div class="gridSquare">Test</div>
<script>
$(document).ready(function(){
onPageLoad(16);
});
function onPageLoad(size){
//genDiv(size);
$('.gridSquare').hover(function(){
$(this).css('background-color', 'red');
});
$('#buttonKernel').click(function(){
$(".gridSquare").css('background-color', 'yellow');
var input = prompt ("Enter a size for the grid", "16");
size = checkInp(input); // what is this function?
var list = document.getElementsByClassName("row");
for (var i = list.length - 1; 0 <= i; i--)
{
if (list[i] && list[i].parentElement)
list[i].parentElement.removeChild(list[i]);
};
// onPageLoad(size); // don't need this!
});
}
</script>
I would like to let there automatically appear text inside an input type=text element.
I would like to accomplish that the different kind of texts are stored inside an array and that every 5 seconds or so, a text is 'typed' by javascript into this field. Then I also like that when I focus on the field (to input text in it by keyboard) that it stops auto-typing and shows an empty input element.
Anybody know how to go about this?
I'm a back-end programmer, but need to do some frontend programming and just haven't had the time to thoroughly learn Javascript. At the moment I only know PHP thoroughly, but would expand my knowledge to css, html and javascript too.
Hope somebody is able to help me out :)
EDIT: This is the solution I came up with and it works. The input field has as ID: searchBar. The code is not very elegant, but I'm still learning :) Thanks for the answers. It helped me a lot.
var searchBar = document.getElementById('searchBar');
var keywords = ['Auto typed text number 1',
'This is number 2 auto typed',
'Yet another auto typed line',
'The last line before it loops again'];
var index = 0;
var arrCounter = 0;
var focus = false;
var timer1, timer2;
function resetBox() {
searchBar.value = '';
index = 0;
autoType();
}
var autoType = function() {
if (focus) {
return;
}
if (index <= keywords[arrCounter].length) {
searchBar.value = keywords[arrCounter].substr(0, index++);
timer1 = setTimeout("autoType()", 50);
} else {
arrCounter++;
if(arrCounter === keywords.length){
arrCounter = 0;
}
timer2 = setTimeout(resetBox, 5000);
}
};
autoType();
$("#searchBar").on("focus", function(){
focus = true;
searchBar.value = '';
clearTimeout(timer1);
clearTimeout(timer2);
}).on("blur", function(){
setTimeout(function() {
focus = false;
resetBox();
}, 1000);
});
Try like this:
html
<input id='demo_input' size='100'/>
javascript:
var demo_input = document.getElementById('demo_input');
var type_this = "try this example";
var index = 0;
window.next_letter = function() {
if (index <= type_this.length) {
demo_input.value = type_this.substr(0, index++);
setTimeout("next_letter()", 50);
}
}
next_letter();
I have been ripping my hair off a couple of nights now with this problem:
I'm trying to create an expanding div with JavaScript. Here's the part of the HTML file:
<div id="bbc_div" class="bbc_div" style="display:none; height:200px;">
<input type="button" value="Show BBC" id="bbc_button" onclick="onclickBBC('bbc_div')" />
And here's the magical non-working JavaScript file:
var maxHeight = 100;
var curHeight = 1;
var wait = 5;
var timerID = new Array();
function onclickBBC(obj) {
if (document.getElementById(obj).style.display == "none") {
slideDown(obj);
}
else {
document.getElementById(obj).style.display="none"
}
}
function slideDown(obj) {
document.getElementById(obj).style.height="1px";
document.getElementById(obj).style.display="block";
timerID[obj] = setInterval("slideDownExec(\"" + obj + "\")", wait);
return;
}
function slideDownExec(obj) {
if (curHeight <= maxHeight) {
curHeight++;
document.getElementById(obj).style.height=curHeight + "px";
}
else {
endSlide(obj);
}
return;
}
function endSlide(obj) {
clearInterval(timerID[obj]);
return;
}
When I reload the page, div expands once to its right height. But, if I push the button without reloading page again after it has hided again, it doesn't work. display:block; works, but setInterval() isn't starting. So this happens after clearInterval() has executed. Why is clearInterval() killing my setInterval() permanently?
The timer is running, you just need to reset a variable:
function slideDown(obj)
{
document.getElementById(obj).style.height = "1px";
curHeight = 1;
I would use jQuery for this, it's a LOT easier.
You have an issue with curHeight not being set to 1 at the top of slideDown. If this doesn't happen, the if statement at the top of slideDownExec will only work the first time.
Additionally, does JavaScript allow non-integer array indexes?
> a['i'] = 4
4
> a
[]
> a['i']
4
What you're actually doing is adding a property called i to the array object. You might as well use an empty object rather than an array.