How can I clear the random quotes output field? - javascript

I've made a random quote generator, it works properly with the only drawback - first quote is done, I click for the next one, it begins to appear in the output field, but the previous quote is still here(
I've tried location.reload(), but it simply keeps my output clean.
Please, advice, how can I fix that?
var source,
adress,
source_length,
start = 0,
randNum;
var quotes[some, examples, inside, etc];
function flowText(){
randNum = Math.floor(Math.random()*quotes.length);
source = quotes[randNum];
console.log(source);
adress = document.getElementById('wind');
source_length = source.length;
flow();
//location.reload();
}
function flow(){
adress.innerHTML += source.substr(start, 1);
start+=1;
if(start < source_length){
setTimeout("flow()", 100);
}
}

If you don't want adress to retain the previous quote
adress.innerHTML = '';
Then call flow();

Related

Browser Crashes before Input is Entered

I'm writing a program in javascript that is supposed to be a fast paced typing challenge. The issue is that my script that's checking for input is crashing my browser before I can enter anything. I thought that it'd pause to wait for input but it seems like I might be wrong?
Here is the function that crashes my browser:
var level1 = function () {
var letter;
var ascii;
var ncorrect = 0;
var input = "0";
var timedout = false;
document.getElementById('prompt').text = "Level 1 : Type Here!" // this is supposed to change text on the page... It doesn't work but not that's not my question.
while (ncorrect < 26){
timedout = false;
setTimeout(timedout = true, 5000);
ascii = Math.floor(Math.random() * 122) + 97; // ASCII's of lower case letters
letter = String.fromCharCode(ascii);
document.getElementById('letter').text = letter;
input = document.getElementById('keyinput');
console.log(input);
if(!timedout && input === letter) {
clearTimeout();
ncorrect++;
}
else {
ncorrect = 0;
}
}
return 0;
}
If it's not a simple fix...
What would be a better way of monitoring input and responding to a right answer?
Thanks, I know it's a little broad of a question but I'm struggling to figure out what I'm looking for.
Javascript is already running an event loop in the background, so you don't need your own. This loop runs continuously and checks to see if any events have fired on any of the HTML DOM Elements. For example, if a button has been clicked, the event loop will pick up a click event for that element. You can add event handlers to the element, which are functions that fire when certain events occur to that element. What you want to do is set an event handler for the event that fires whenever the text in your input area (I'm assuming that the user is typing in an input or textarea tag) is fired.
For example, the following simple program will create a typing challenge 100 random characters long
var ncorrect = 0;
var timedout = false;
//select an empty paragraph to fill with text
var challengeText = document.getElementbyId("challengeText");
challengeText.innerHtml = "";
//Append 100 random characters to the paragraph
for (var i=0;i<100;i++) {
challengetText.innerHtml += String.fromCharCode(Math.floor(Math.random() * 122) + 97);
}
//Check the number of characters typed since the last the loop hit the element
var lastCharsTyped = 0;
var charsTyped = 0;
//Grab the user input
var input = document.getElementById("userInput")
//Set the event handler to fire when the user presses a key (technically, when they lift their finger
input.onkeyup = function(keyEvent){
//Ugly ternary to deal with the fact that not all browsers use the same api. If you haven't seen this before it means if which is a key of keyEvent then keyCoe is event.which, otherwise it's event.keyCode
var keyCode = ('which' in keyEvent) ? keyEvent.which : keyEvent.keyCode;
//Check if the key pressed is equal to the character in the text to match at the same position
if (keyCode === challengeText.innerHtml.charCodeAt(input.value.length)) { ncorrect ++} else {ncorrect = 0;}
}
It won't handle deletes or shift very gracefully, but it should give you an idea of the direction to take.
As a stylistic note, its customary to declare and initialize your variables right before you use them, rather than at the start of your program.
You can use setTimeout() and pass in a function that checks the input after whichever time you specify. Here's one way to implement this:
setTimeout( function () {
var textbox = document.getElementById('textbox');
if (textbox.value !== 'The quick brown fox jumps over the lazy dog.') {
alert('You didn\'t pass.');
} else {
alert('Congratulations!');
}
}, 5000);
Type in the phrase "The quick brown fox jumps over the lazy dog."
<input type="textbox" id="textbox"></input>
setTimeout is passed a function expression that checks user input and spits out an alert based on their typing prowess. The second argument 5000 means the function passed into setTimeout will be called at the nearest opportunity after 5000 ms has passed.

JavaScript Syllable Counter - Counting Per Line

Current
I’ve re-worked this syllable counter script to:
Get the value of textarea 1.
Count the number of syllables in textarea 1.
Display the results in textarea 2.
Update the count every time the value of textarea 1 is edited.
Act as a function (be able to run in multiple instances if wanted).
Example function of current code
Input (Textarea 1)
i would appreciate
any help
at all
Results (Textarea 2)
11
Current code
Here is the existing code as a JSFiddle.
Goal
I would like this script to:
Count the syllables of textarea 1 on a per line basis: presumably by splitting the textarea 1 value where there are line breaks e.g. .split('\n');.
Output the results, showing the total number of syllables counted per line.
Example function of desired code
Input (Textarea 1)
i would appreciate
any help
at all
Results (Textarea 2)
6
3
2
Problem
I’m quite stuck as to how to do this and would really appreciate any help or JSFiddle showing how to work with the existing code to achieve this.
Notes
For anyone who may be interested using in the syllable count function code itself: it’s not 100% accurate and fails on some words but gives a good general idea.
Try this and let me know if it's what you needed.
Callouts:
I created an array that spits the lines up stores them var arrayOfLines = $("[name=set_" + $input + "]").val().match(/[^\r\n]+/g);.
Then loop through that array and do exactly what you did before, but on each array entry. Then store the results in tempArr, and display the tempArr results.
See Fiddle
function $count_how_many_syllables($input) {
$("[name=set_" + $input + "]").keyup(function () {
var arrayOfLines = $("[name=set_" + $input + "]").val().match(/[^\r\n]+/g);
var tempArr = [];
var $content;
var word;
var $syllable_count;
var $result;
for(var i = 0; i < arrayOfLines.length; i++){
$content = arrayOfLines[i];
word = $content;
word = word.toLowerCase();
if (word.length <= 3) {
word = 1;
}
if (word.length === 0) {
return 0;
}
word = word.replace(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, '')
.replace(/^y/, '')
.match(/[aeiouy]{1,2}/g).length;
$syllable_count = word;
$result = $syllable_count;
tempArr.push($result);
}
$("[name=set_" + $input + "_syllable_count]").val(tempArr);
});
}
(function($) {
$count_how_many_syllables("a");
})(jQuery);

Specific textarea behaviour related to setTimeout

what I am trying to do is give the user a textarea (with enabled input) and allow him to write up to 10 chars. Actually, the textarea should ALLOW more chars, not only 10, and the other chars would behave accordingly:
1º There is a setTimeout whenever the user is on the 11ºchar. So, I'm writing something there, I reach the char number 10º (the "maximum" allowed of text) and want that other char to be erased AFTER a given time.
somethinge = 10 chars.
anotherwor = 10 chars.
input: somethingeiefjaiehf
after 5 seconds:
input: somethinge
input: anotherwordtotestthisandseeifitworks
after 5 seconds:
input: anotherwor
2ºTo accomplish this I basically attached a clearTimeout to a global variable:
//Function "countChar(val)" is activated with the keydown event
var timer_to_op = null;
function countChar(val) {
var len = val.value.length; //lenght of input in textarea
clearTimeout(timer_to_op);
//...
//irrelevant code
//...
}else if(len > 140){
$("#status_toOp_num").text(145-len);
timer_to_op = setTimeout(function(){
val.value = val.value.substring(0, 140);
},5000);
}
Actually, for some reason, it won't work. If the user is typing AND he types another char within the 5 seconds then I want the timer to restart.
input: anotherwor
input: anotherword (+d) timer = 1...2...3...
input: anotherworde (+e) timer = 1...2...
input: anotherwordef (+f) timer = 1...2...3...4...5!
input: anotherwor the user took more than 5 seconds so it erased the excedent.
Hope I got my point through. Any ideas on this one? Thank you very much! (I didn't put any html, it's only <textarea onclick="countChar(this)"> )
I didn't really try to understand what you are doing in your code, seems unnecessarily complicated.
Check this fiddle out. http://jsfiddle.net/Q2h5f/
HTML
<textarea id="limitText">0123456789</textarea>
Javascript
var tarea = document.getElementById("limitText");
tarea.onkeypress = checkInputText;
var timer = null;
function checkInputText(e) {
if (timer) clearTimeout(timer);
timer = setTimeout(limitTextLength, 5000);
}
function limitTextLength() {
var tareaVal = document.getElementById("limitText").value.toString();
if (tareaVal.length > 10) {
tarea.value = tareaVal.slice(0, 10);
}
}
Should solve your issue.

Fast JS Pagination for long texts

I'm trying to create a pagination system with JavaScript.
Basic situation: I have a database, which holds fairly long texts (story chapters, 5000 words+). I want to display these chapters on a website...however not the entire text at once, because that would pretty much kill the readability, but in pages.
I have no problem displaying the text, but rather with getting the pages right.
I've been looking around, and came across a JQuery code, which does about what I want it to do...however there's a major caveat for this method. It takes about 10 seconds to finish paginating the text, which is far too long a wait.
What the code basically does:
It splits the text into words (separated by spaces).
It then tries adding one word after the other to a innerHTML, checking back if the text is now bigger than the container it's supposed to fit in.
Each time it breaks the boundary, it reverts back to the previous string and creates a new page. (By encapsulating the text into a span, which can then be hidden/shown at a moments notice) This works, however it is too slow, because it has to run these checks 5000+ times.
I have tried creating an approximation system, which basically takes the amount of words, divides it by the factor 0.5, checks if the buffer is larger than the required size, and repeats this process, until the buffer is 'smaller' than the required size for the first time, and from that position on, it fills the buffer, until it's full.
However it just doesn't seem to work right (double words, lines, which aren't completely full, and it's still too slow.)
This is the code I'm currently using, I'd be grateful for any fixes and suggestions how to make it easier, and especially: Faster.
Oh and: No, paging it serverside is not an option, since it's supposed to fit into variable browser formats...in a fullscreen browser at 1280x768 resolution it will be less pages, than in a small browser at a 1024x768 resolution.
function CreateChild(contentBox, Len, pageText, words) {
var Child = document.createElement("span");
Child.innerHTML = pageText;
contentBox.appendChild(Child);
if(Len == 0) ++Len;
words.splice(0, Len);
return words.length;
}
$(document).ready(function(){
var src = document.getElementById('Source');
var contentBox = document.getElementById('content');
var inner = document.getElementById('inner');
//get the text as an array of word-like things
var words = src.innerHTML.replace(/ +/g, " ").split(' '), wCount = words.length;
//start off with no page text
var pageText = null, cHeight = contentBox.offsetHeight;
while(words.length > 0) {
var Found = false;
pageText = words[0]; //Prevents constant checking for empty
wCount *= 0.5; //Searches, until the words fit in.
for(var i = 1; i < wCount; ++i) pageText += ' ' + words[i];
inner.innerHTML = pageText;
Distance = inner.offsetHeight - cHeight;
if(Distance < 40) { //Less than two lines
wCount = Math.floor(wCount);
if(Distance < 0) { //Already shorter than required. Fill.
for(var i = wCount; i < words.length; ++i) {
//add the next word to the pageText
var betterPageText = pageText + ' ' + words[i];
inner.innerHTML = betterPageText;
//Checks, whether the new words makes the buffer too big.
if(inner.offsetHeight > cHeight) {
wCount = CreateChild(contentBox, i, pageText, words);
Found = true;
break;
} else {
//this longer text still fits
pageText = betterPageText;
}
}
} else {
for(var i = wCount; i >= 0; --i) {
//Removes the last word from the text
var betterPageText = pageText.slice(0, pageText.length - words[i].length - 1);
inner.innerHTML = betterPageText;
//Is the text now short enough?
if(inner.offsetHeight <= cHeight) {
wCount = CreateChild(contentBox, i, pageText, words);
Found = true;
break;
} else {
pageText = betterPageText;
}
}
}
if(!Found) CreateChild(contentBox, i, pageText, words);
}
}
//Creates the final block with the remaining text.
Child = document.createElement("span");
Child.innerHTML = pageText;
contentBox.appendChild(Child);
//Removes the source and the temporary buffer, only the result remains.
contentBox.removeChild(inner);
src.parentNode.removeChild(src);
//The rest is the actual pagination code, but not the issue
});
I managed to solve my problem, also thanks to Rich's suggestion.
What I'm doing: First off, I'm getting the text from the 'Source' (alternatively, I could write the entire text straight into the JS, the effect is the same).
Next I'm getting references to my target any my temporary buffer, the temporary buffer is located inside the target buffer, so it will retain the width information.
After that, I split the entire text into words (standard RegEx, after replacing multiple spaces with a single one). After this, I create some variables, which are meant to buffer function results, so the function calls won't have to be repeated unnecessarily.
Now the main difference: I take chunks of 20 words, checking whether the current chunk exceeds the boundary (again, buffering the results in variables, so they don't get called multiple times, function calls equal valuable microseconds).
Once the boundary is crossed (or the total number of characters is reached), the loop is stopped, and (assuming the boundary caused the 'stop'), the text is shortened by one word per run, until the text fits in again.
Finally, the new text gets added to a new span-element, which is added to the content box (but made invisible, I'll explain why in a bit), the words I just 'used' get removed from the word array and the wCount variable gets decremented by the number of words.
Rinse and repeat, until all pages are rendered.
You can exchange the '20' with any other value, the script will work with any arbitrary number, however please remember, that a too low number will cause a lot of runs in the 'adding segment', and a too big number will cause a lot of runs in the 'backtracking segment'.
As for the invisible: If the span is left visible, sooner or later it WILL cause scrollbars to appear, effectively narrowing the width of the browser window.
In turn, this will allow less words to fit in, and all following pages will be distorted (because they will be matched to the window with scrollbars, while the 'paged result' will not have scrollbars).
Below is the code I used, I hope it will help someone in the future.
var src = document.getElementById('Source');
var contentBox = document.getElementById('content');
var inner = document.getElementById('inner');
//get the text as an array of word-like things
var words = src.innerHTML.replace(/ +/g, " ").split(' ');
//start off with no page text
var cHeight = contentBox.offsetHeight, wCount = words.length;
while(wCount > 0) {
var Len = 1, Overflow = false;
var pageText = words[0]; //Prevents the continued check on 'is pageText set'.
while(!Overflow && Len < wCount) { //Adds to the text, until the boundary is breached.
//20 words per run, but never more than the total amount of words.
for(var j = 0; j < 20 && Len < wCount; ++Len, ++j) pageText += ' ' + words[Len];
inner.innerHTML = pageText;
Overflow = (inner.offsetHeight > cHeight); //Determines, whether the boundary has been crossed.
}
if(Overflow) { //Will only be executed, if the boundary has been broken.
for(--Len; Len >= 0; --Len) { //Removes the last word of the text, until it fits again.
var pageText = pageText.slice(0, -(words[Len].length + 1)); //Shortens the text in question.
inner.innerHTML = pageText;
//Checks, whether the text still is too long.
if(inner.offsetHeight <= cHeight) break;//Breaks the loop
}
}
var Child = document.createElement("span");
Child.style.display = "none"; //Prevents the sidebars from showing (and distorting the following pages)
Child.innerHTML = pageText;
contentBox.appendChild(Child);
words.splice(0, Len);
wCount -= Len;
}
Create an absolutely-positioned container that is the width of a single page. Give it height of 'auto'. Position the container somewhere off screen, like left: -10000px so users can't see it. Split the original text into 20-word chunks. (Look up the regex that accomplishes this.) Append one chunk at a time to the string in the container until the height of the container reaches the max height of a single page. Once it reaches the max height, the string in the container is basically one page of text. Push the string in the container onto an array called 'pages'. Empty the container and start creating page 2 by appending the 20-word chunks again, continuing to iterate through the array from where you left off on the previous page. Continue this process until you reach the end of the 20-word array, pushing each new page onto the array of pages whenever the container's string reaches the max height. You should now have an array of pages, each item of which contains the text of each page.
Having not searched in advance, I worked out an alternative solution with getClientRects (https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects). If someone's interested in the details, I'll post more.

parse a textarea in substrings based on line breaks in Javascript

I have a text area that I need to parse. Each new line needs to be pulled out and an operation needs to be performed on it. After the operation is done the operation needs to be run on the next line. This is what I have at the moment. I know the indexOf search won't work because it's searching character by character.
function convertLines()
{
trueinput = document.getElementById(8).value; //get users input
length = trueinput.length; //getting the length of the user input
newinput=trueinput; //I know this looks silly but I'm using all of this later
userinput=newinput;
multiplelines=false; //this is a check to see if I should use the if statement later
for (var i = 0; i < length; i++) //loop threw each char in user input
{
teste=newinput.charAt(i); //gets the char at position i
if (teste.indexOf("<br />") != -1) //checks if the char is the same
{
//line break is found parse it out and run operation on it
userinput = newinput.substring(0,i+1);
submitinput(userinput);
newinput=newinput.substring(i+1);
multiplelines=true;
}
}
if (multiplelines==false)
submitinput(userinput);
}
So for the most part it is taking the userinput. If it has multiply lines it will run threw each line and seperatly and run submitinput. If you guys can help me I'd be eternally thankful. If you have any questions please ask
Line breaks within the value of a textarea are represented by line break characters (\r\n in most browsers, \n in IE and Opera) rather than an HTML <br> element, so you can get the individual lines by normalizing the line breaks to \n and then calling the split() method on the textarea's value. Here is a utility function that calls a function for every line of a textarea value:
function actOnEachLine(textarea, func) {
var lines = textarea.value.replace(/\r\n/g, "\n").split("\n");
var newLines, i;
// Use the map() method of Array where available
if (typeof lines.map != "undefined") {
newLines = lines.map(func);
} else {
newLines = [];
i = lines.length;
while (i--) {
newLines[i] = func(lines[i]);
}
}
textarea.value = newLines.join("\r\n");
}
var textarea = document.getElementById("your_textarea");
actOnEachLine(textarea, function(line) {
return "[START]" + line + "[END]";
});
If user is using enter key to go to next line in your text-area you can write,
var textAreaString = textarea.value;
textAreaString = textAreaString.replace(/\n\r/g,"<br />");
textAreaString = textAreaString.replace(/\n/g,"<br />");
textarea.value = textAreaString;
to simplify the answers, here is another approach..
var texta = document.getElementById('w3review');
function conv (el_id, dest_id){
var dest = document.getElementById(dest_id),
texta = document.getElementById(el_id),
val = texta.value.replace(/\n\r/g,"<br />").replace(/\n/g,"<br />");
dest.innerHTML = val;
}
<textarea id="targetted_textarea" rows="6" cols="50">
At https://www.a2z-eco-sys.com you will get more than what you need for your website, with less cost:
1) Advanced CMS (built on top of Wagtail-cms).
2) Multi-site management made easy.
3) Collectionized Media and file assets.
4) ...etc, to know more, visit: https://www.a2z-eco-sys.com
</textarea>
<button onclick="conv('targetted_textarea','destination')" id="convert">Convert</button>
<div id="destination">Had not been fetched yet click convert to fetch ..!</div>

Categories

Resources