Why is the overflow not executed in the textarea? - javascript

In the following example, I try to write horizontally beyond the text box. The lines are very long, so a scrollbar should be created. Something is not working, can someone help me? Thanks.
I have another incomplete code in it that I'm still working on. It's about a line and a time counter.
Regarding the line writer, I've noticed that the computer is getting slower as many lines are written. Is it necessary that here constantly should be deleted the memory?
var btnWrite = document.getElementById("writeElement");
var btnStop = document.getElementById("stopElement");
var btnClear = document.getElementById("clearElement");
btnWrite.addEventListener("click", writeData);
btnStop.addEventListener("click", stopText);
btnClear.addEventListener("click", clearText);
textareaStatus = document.body.appendChild(document.createElement('textarea'));
var timer = null;
function writeData() {
var Text = ("1111111111" + " " + "2222222222" + " " + "3333333333" + " " + "4444444444" + " " + "5555555555" + " " + "6666666666" + " " + "7777777777" + "\n");
timer = setTimeout(writeData, 1000);
textareaStatus.value += Text;
startTimer();
}
function stopText() {
clearTimeout(timer);
//stopTimer();
}
function clearText() {
textareaStatus.value = '';
clearTimer();
}
function count() {
newLines = (this).val().split("\n").length;
linesUsed.text(newLines);
}
function startTimer() {
var sec = 0;
function pad(val) {
return val > 9 ? val : "0" + val;
}
var timer = setInterval(function() {
//document.getElementById("tenthsseconds").innerHTML = pad(parseInt(sec/60,100));
document.getElementById("seconds").innerHTML = pad(++sec % 60);
document.getElementById("minutes").innerHTML = pad(parseInt(sec / 60, 10));
}, 1000);
};
function stopTimer() {}
function clearTimer() {
clearInterval(timer);
//timer = '';
}
textarea {
display: block;
font-size: small;
color: #ffffff;
margin-top: 10px;
margin-left: 0px;
width: 510px;
height: 140px;
overflow-x: scroll;
overflow-x: hidden;
background: black;
}
<button id="writeElement">Write</button>
<button id="stopElement">Stop</button>
<button id="clearElement">Clear</button>
<div class="count">Lines used: <span id="linesUsed">0</span>
<div>
<span id="minutes">00</span>:<span id="seconds">00</span>:<span id="tenthsseconds">00</span>

Use white-space: nowrap; to stop your lines from breaking to the next line
Use overflow: auto; to automatically add the scrollbars where needed.
textarea {
display: block;
font-size: small;
color: #ffffff;
margin-top: 10px;
margin-left: 0px;
width: 510px;
height: 140px;
overflow: auto;
white-space: nowrap;
background: black;
}
Example
var btnWrite = document.getElementById("writeElement");
var btnStop = document.getElementById("stopElement");
var btnClear = document.getElementById("clearElement");
btnWrite.addEventListener("click", writeData);
btnStop.addEventListener("click", stopText);
btnClear.addEventListener("click", clearText);
textareaStatus = document.body.appendChild(document.createElement('textarea'));
var timer = null;
function writeData() {
var Text = ("1111111111" + " " + "2222222222" + " " + "3333333333" + " " + "4444444444" + " " + "5555555555" + " " + "6666666666" + " " + "7777777777" + "\n");
timer = setTimeout(writeData, 1000);
textareaStatus.value += Text;
startTimer();
}
function stopText() {
clearTimeout(timer);
//stopTimer();
}
function clearText() {
textareaStatus.value = '';
clearTimer();
}
function count() {
newLines = (this).val().split("\n").length;
linesUsed.text(newLines);
}
function startTimer() {
var sec = 0;
function pad(val) {
return val > 9 ? val : "0" + val;
}
var timer = setInterval(function() {
//document.getElementById("tenthsseconds").innerHTML = pad(parseInt(sec/60,100));
document.getElementById("seconds").innerHTML = pad(++sec % 60);
document.getElementById("minutes").innerHTML = pad(parseInt(sec / 60, 10));
}, 1000);
};
function stopTimer() {}
function clearTimer() {
clearInterval(timer);
//timer = '';
}
textarea {
display: block;
font-size: small;
color: #ffffff;
margin-top: 10px;
margin-left: 0px;
width: 510px;
height: 140px;
overflow: auto;
white-space: nowrap;
background: black;
}
<button id="writeElement">Write</button>
<button id="stopElement">Stop</button>
<button id="clearElement">Clear</button>
<div class="count">Lines used:
<span id="linesUsed">0</span>
<div>
<span id="minutes">00</span>:
<span id="seconds">00</span>:
<span id="tenthsseconds">00</span>
In regards to your second question:
Regarding the line writer, I've noticed that the computer is getting
slower as many lines are written. Is it necessary that here constantly
should be deleted the memory?
Your browser will get slower as more lines are logged in the textarea because its continually writing to that object in the DOM.
P.S.
As an aside to my answer, I have to agree with charlietfl when he mentions the use of other elements to achieve this functionality. <pre> is definitely a good alternative.
You should also think about clearing down some of the text thats filling up the value of your element in the DOM over time.

If you want to show scroll bar on x axis, you should set
overflow-x: scroll;
In your text-area. Currently you have both
overflow-x: scroll;
overflow-x: hidden;
The second one is overriding the first one.

Related

How to animate a number ticking up in HTML

I'm trying to have a number "tick up" when it changes, in a similar fashion to Twitter's like/retweet/comment counters and Discord's reaction counter. I haven't found any information about this on the web (mainly because I don't know what it's formally called).
Here is my code:
The counter element itself:
<span id="counter" class="counter">0</span>
The CSS for the element:
.counter {
display: inline-block;
height: 15px;
font-size: 15px;
overflow-y: hidden;
}
The JavaScript for changing the counter:
function changeCounter(id, num) {
var _x = document.getElementById(id);
_x.innerHTML += _x.innerHTML + "<br>" + num;
_x.style.transition = "0.2s";
setTimeout(function () {
_x.style.marginTop = "-15px";
setTimeout(function () {
_x.innerHTML = num;
_x.style.transition = "0";
_x.style.marginTop = "0";
}, 200);
}, 16);
}
What happens is that it puts the new number next to the original number, goes up, and goes down with just the new number. I want it to have the new number under the old one and just snap to its original position after it stops animating.
function changeCounter(id, num) {
var _x = document.getElementById(id);
_x.innerHTML += _x.innerHTML + "<br>" + num;
_x.style.transition = "0.2s";
setTimeout(function () {
_x.style.marginTop = "-15px";
setTimeout(function () {
_x.innerHTML = num;
_x.style.transition = "0";
_x.style.marginTop = "0";
}, 200);
}, 16);
}
.counter {
display: inline-block;
height: 15px;
font-size: 15px;
overflow-y: hidden;
}
<span id="counter" class="counter">0</span>
<button onclick="changeCounter('counter', Math.floor(Math.random()*100))">Change</button>

How do i get the date counter to stop running in background even while paused? Any and all help is appreciated

I have a date counter with play/pause button that works great, however, during pause the counter continues to run in the background.
To see what I mean, press pause, wait 10 seconds, press play and you will see the date has advanced 1 or 2 months, not to the next day. I am grateful for any help. My code is below.
var virtualOrigin = Date.parse("2020-01-01"),
realOrigin = Date.now(),
factor = 862350;
function getVirtual(time) {
return new Date(virtualOrigin + (time - realOrigin) * factor);
}
function format(time) {
var month = time.getMonth() + 1;
var day = time.getDate();
if (month < 10) {
month = '0' + month;
}
if (day < 10) {
day = '0' + day;
}
return (month) +
"-" + day +
"-" + time.getFullYear();
}
var output = document.getElementById("txt");
var t = 0;
var flagTimer = 'startTime()';
function pause() {
if (flagTimer == 'startTime()') {
clearTimeout(t);
document.getElementById('Pause').value = "Play";
flagTimer = 'pause';
} else {
flagTimer = 'startTime()';
document.getElementById('Pause').value = "Pause";
startTime();
}
}
function startTime() {
var now = new Date();
var display = getVirtual(now);
output.innerText = format(display);
t = setTimeout(startTime, 1000 / factor - (now.getMilliseconds() %
(1000 / factor)));
}
function clickEvent() {
pause();
}
.txt {
color: orange;
margin-left: 46%;
margin-top: 10%;
position: absolute;
z-index: 300;
}
#Pause {
margin-left: 47.6%;
margin-top: 10%;
border: 2px solid orange;
color: blue;
display: block;
width: 55px;
text-align: center;
}
#Pause:hover {
background-color: orange;
color: white;
border: 2px solid lightblue;
}
#toggle-animation {
margin-left: 45.5%;
margin-top: 10%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>timer8</title>
<meta charset=UTF-8>
</head>
<body onload="startTime()">
<input type="button" id="Pause" class="toggle-animation" value="Pause" onclick="clickEvent();" />
<div id="txt" class="txt"></div>
</body>
</html>
Your function to calculate the virtual date:
function getVirtual(time) {
return new Date( virtualOrigin + (time - realOrigin) * factor );
}
... calculates it based on the difference between the current time and page load time, regardless of whether you have paused or not.
You could fix this by:
when pausing, updating virtualOrigin to the current virtual datetime
in your getVirtual(time) function, only adding the difference when your timer is unpaused
when unpausing, updating realOrigin to the current real datetime.

How do I start this javascript code on click

EDITED: Ok, I didn't explain well. I have added a button in the HTML. When you click that, it alerts and asks for user to enter questions and answers. BUT...it doesn't push that array into the cards themselves.
I have hacked together a simple javascript flash card program. But it starts immediately on page load. How do I make it start on click of a single <button>? I've tried enclosing the entire code in a function but then the user inputs that create the array don't get passed to the flashcards -- I assume because they are separate functions. I'm probably not explaining this well. But I want the entire program to run on click of one button. I appreciate any help.
#flashcardFront {
margin-top: 100px;
margin-left: 400px;
width: 300px;
height: 50px;
background-color: black;
color: white;
font-family: arial;
font-size: 22px;
text-align: center;
padding: 50px 0;
display: block;
}
a:link {
text-decoration: none;
}
#number {
color: red;
position: relative;
left: -120px;
top: 30px;
}
<div>
<button onclick='cards();'>button</button>
<a id="flashcardFront" href="#" onclick="flashCards();"></a>
</div>
var myArray = [];
for (var i = 0; i < 2; i++) { // # of loops
myArray.push(prompt('Enter question ' + (i+1))); // push the value into the array
myArray.push(prompt('Enter answer ' + (i+1))); // push the value into the array
}
/*var myArray = [
"Q: What's my name?", 'A: Heck no.',
'Q: My age?', "A: Cool kids don't say.",
'Q: Fave rocker?', 'A: Paul Gilbert'
];*/
var myIndex = 0;
function renderQuestion(index) {
// render number if index is even
var str = myArray[index]
if (index % 2 == 0) {
str += '<br><span class="question-number">' + (index / 2 + 1) + '</span>'
}
return str
}
function flashCards() {
var flashcardFront = document.getElementById('flashcardFront');
flashcardFront.innerHTML = renderQuestion(myIndex);
myIndex = (myIndex + 1) % (myArray.length);
}
flashCards()
I think the issue here is that myIndex is a global. The first time flashcards runs, it increments the index to the length of the array, so the next time it runs (in the click handler) it's already at the end of the array. Set it to 0 at the beginning of flashcards.
At the end of the code, you call flashCard() javascript function which cause your page to load the first question immediately after user entered all prompted inputs. Remove it and your application is good to go.
var questionsAndAnswers = [];
var myIndex = 0;
function showAllQuestionsAndAnswers() {
for (var i = 0; i < questionsAndAnswers.length; i++) {
if(i % 2 == 0) {
alert("Question: " + questionsAndAnswers[i]);
}
else {
alert("Answer: " + questionsAndAnswers[i]);
}
}
}
/*var myArray = [
"Q: What's my name?", 'A: Heck no.',
'Q: My age?', "A: Cool kids don't say.",
'Q: Fave rocker?', 'A: Paul Gilbert'
];*/
function renderQuestion(index) {
// render number if index is even
var str = questionsAndAnswers[index]
if (index % 2 == 0) {
str += '<br><span class="question-number">' + (index / 2 + 1) + '</span>'
}
return str
}
function flashCards() {
for (var i = 0; i < 2; i++) { // # of flash cards
questionsAndAnswers.push(prompt('Enter question ' + (i+1))); // push the value into the array
questionsAndAnswers.push(prompt('Enter answer ' + (i+1))); // push the value into the array
}
var flashcardFront = document.getElementById('flashcardFront');
flashcardFront.innerHTML = renderQuestion(myIndex);
myIndex = (myIndex + 1) % (questionsAndAnswers.length);
}
function startGame() {
flashCards();
}
document.getElementById("start_game").onclick = function() {startGame()};
#flashcardFront {
margin-top: 100px;
margin-left: 400px;
width: 300px;
height: 50px;
background-color: black;
color: white;
font-family: arial;
font-size: 22px;
text-align: center;
padding: 50px 0;
display: block;
}
a:link {
text-decoration: none;
}
#number {
color: red;
position: relative;
left: -120px;
top: 30px;
}
<div>
<button onclick='cards();'>button</button>
<button id="start_game">
Start Game
</button>
<a id="flashcardFront" href="#" onclick="flashCards();"></a>
</div>

Javascript syntax highlighter infinite loop

I'm making a syntax highlighter in Javascript and HTML. It works fine at the moment but I think it's really inefficient because I have an interval with a time of 0 which runs a function that loops through all of the characters in the text area and then inserts them into a div behind the text area to provide the syntax highlighting.
I think my lexer is really bad too, but at the moment I'm more concerned with the function running like a million times a second that loops through every character in the text area each time.
Can anyone please think of a more efficient way to do this?
There doesn't seem to be any performance problems but I'm not sure if it will work on a lower-powered machine because I don't want it to crash the browser tab because I want to have several on a page so I need it to be as efficient as possible.
I understand that its annoying to be given loads of code and asked to help, but I thought for the problem to be easiest to debug you'd need the entire code.
Here you code:
<html>
<head>
<title>My Syntax Highlighter</title>
<style type="text/css">
#container {
width: 100%;
height: 100%;
position: relative;
padding: 0px;
}
#code {
width: 100%;
height: 100%;
outline:none;
position: absolute;
background-color: transparent;
border: none;
font-family: Courier;
font-size: 22px;
color: rgba(0,0,0,.2) !important;
}
#codeb {
width: 100%;
height: 100%;
position: absolute;
font-family: Courier;
font-size: 22px;
padding: 2px 2px;
color: #000;
}
.keyword {
/*font-weight: bold;*/
color: #E42D82;
}
.string {
/*font-weight: bold;*/
color: #0086b3;
}
</style>
<script type="text/javascript">
function u() {
var code = document.getElementById("code");
var codeb = document.getElementById("codeb");
var c = "";
var tok = "";
var cc = 0;
var t = "";
var takeaway = 0;
var stringStarted = false;
var string = "";
for (var i = 0; i < code.value.length; i++) {
tok += code.value[i];
c += code.value[i];
cc++;
if (tok == "print") {
t = "<span class=\"keyword\">print</span>";
takeaway += 5;
c = c.substring(0, cc - takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
} else if (tok == "var") {
t = "<span class=\"keyword\">var</span>";
takeaway += 3;
c = c.substring(0, cc-takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
} else if (tok == "\"") {
tok = "";
if (stringStarted == false) {
stringStarted = true;
string += "\"";
} else {
stringStarted = false;
string += "\"";
t = "<span class=\"string\">" + string + "</span>";
takeaway += string.length;
c = c.substring(0, cc-takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
string = "";
}
tok = "";
} else if (tok == " ") {
if (stringStarted == true) {
string += " ";
}
c+= "";
tok = "";
} else {
if (stringStarted == true) {
string += code.value[i];
tok = "";
}
}
codeb.innerHTML = c;
//console.log("test");
};
//alert(string);
if (code.value == "") {
codeb.innerHTML = "";
}
clearI(setInterval(function(){ u(); }, 0));
}
function clearI(interval) {
clearInterval(interval);
}
var interval = setInterval(function(){ u(); }, 0);
</script>
</head>
<body>
<div id="container">
<div id="codeb"></div>
<textarea id="code" autofocus></textarea>
</div>
</body>
</html>

Delay until fully loaded

There's a clock in my page that loads pretty fast but there's an instant when it loads where you can see it stopped. I want to make it appear only when it's fully loaded.
This is the code of the clock:
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#clock {
position: relative;
width: 500px;
height: 480px;
background: url(images/clockface.png);
list-style: none;
}
#sec, #min, #hour {
position: absolute;
width: 30px;
height: 600px;
top: 0px;
left: 225px;
}
#sec {
background: url(images/sechand.png);
z-index: 3;
}
#min {
background: url(images/minhand.png);
z-index: 2;
}
#hour {
background: url(images/hourhand.png);
z-index: 1;
}
p {
text-align: center;
padding: 10px 0 0 0;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
setInterval( function() {
var seconds = new Date().getSeconds();
var sdegree = seconds * 6;
var srotate = "rotate(" + sdegree + "deg)";
$("#sec").css({"-moz-transform" : srotate, "-webkit-transform" : srotate});
}, 1000 );
setInterval( function() {
var hours = new Date().getHours();
var mins = new Date().getMinutes();
var hdegree = hours * 30 + (mins / 2);
var hrotate = "rotate(" + hdegree + "deg)";
$("#hour").css({"-moz-transform" : hrotate, "-webkit-transform" : hrotate});
}, 1000 );
setInterval( function() {
var mins = new Date().getMinutes();
var mdegree = mins * 6;
var mrotate = "rotate(" + mdegree + "deg)";
$("#min").css({"-moz-transform" : mrotate, "-webkit-transform" : mrotate});
}, 1000 );
});
</script>
Thanks
<ul id="clock" style="visibility: hidden"> <!-- this is so the browser computes the position of the element but doesn't show it just yet -->
<li id="sec"></li>
<li id="hour"></li>
<li id="min"></li>
</ul>
Then:
<script type="text/javascript">
window.onload = function() { // this will be run when the whole page is loaded
document.getElementById("clock").style.visibility = "display";
};
</script>
A div does not have a load event.
On DOM ready, I would hide the clock...
document.getElementById("clock").style.display = 'none';
...and then at the end of the code of the clock, when it is finished, I would set its display to block...
document.getElementById("clock").style.display = 'block';
...or inline if that is more appropriate in your situation.

Categories

Resources