Output string length and classical Fibonacci sequence in a web page I wrote a JavaScript and XHTML webpage. I think the format of the output is not better or the validation process is not as it is supposed to be. How can I improve the code? How can I make it more efficient?

There are two text boxes. First, it takes a sentence and returns the length. Second, it takes an integer and returns that number of classical Fibonacci numbers.

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;titile&gt;&lt;/title&gt;

&lt;/head&gt;
&lt;body&gt;
&lt;script type="text/javascript"&gt;
function getStrLen(){
        var msgDiv = document.getElementById('textbox1');
    document.getElementById('msg').textContent = msgDiv.value.split('').length;

}
var a = 0;
var b = 0;
var c = 1;
var ONE = 1;
function genFibonacci(times){
    if(times &lt;=0){return;}
     a = b;
    b = c;
    c = a + b;





        document.getElementById('fibseq').textContent += a.toString() + (times &gt; ONE ? ", " : " ");

        genFibonacci(times - 1, false); 
}

function outFib(){

genFibonacci(document.getElementById('fibText').value);
}

&lt;/script&gt;

&lt;button id="lenClick" onclick="getStrLen()"&gt;String Length&lt;/button&gt;
Enter a sentence or multiple ones: &lt;input type="text" id="textbox1"&gt;&lt;/input&gt;
&lt;br/&gt;

Number of characters in this sentence is: &lt;span id="msg"&gt;
&lt;/span&gt;
&lt;br/&gt;

&lt;input type="text" id="fibText"&gt;&lt;/input&gt;
&lt;button id="fibClick" onclick="outFib()"&gt;Generate Fibonacci Sequence&lt;/button&gt;&lt;div id="fibseq"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;html&gt;
Getting the length of a string

You split the string into characters and then you count the array's length. While this works, there's an even simpler way of doing it, using the length property of a String:

const length = msgDiv.value.length;


Changing getStrLen

You can cache the DOM elements. Then you don't need to re-query them, each time the function is called:

const strlenInput = document.getElementById('textbox1');
const strlenDisplay = document.getElementById('msg');

const getStrLen = () =&gt; {
    strlenDisplay.textContent = strlenInput.value.length;
}


Now this alone won't work in the head-element of your document, as both elements are not available yet. You can either:


wait until the DOM is ready to run that script, like document.addEventListener('DOMContentLoaded', function(event) { […] }, or
place the Javascript at the end of your page instead


This is explained in detail here: $(document).ready(function(){}); vs script at the bottom of page.

Creating the Fibonacci sequence

genFibonacci() takes one parameter, so you pass an unused parameter, when calling the function recursively:

genFibonacci(times - 1, false);




There's a flaw in your logic: You don't reset the values each time the button is clicked. If the user's input is 1 and they hit the generate button 5 times, the result is not 0 but:

 0 1 1 2 3




With this in mind, let's try to change your algorithm, that it won't rely on external variables. We also don't necessarily need recursion here:

const getFibonacciValues = (n) =&gt; {
    const values = [];

    if (n &gt;= 1) {
        values.push(0);
    }

    if (n &gt;= 2) {
        values.push(1);
    }

    for (let i = 2; i &lt; n; ++i) {
        values.push(values[i - 2] + values[i -1]);
    }

    return values;
}


Now we have a function, which purpose is solely to create the values. It doesn't have a clue, how you're going to output them. outFib() is doing this for us now:

const outFib = () =&gt; {
    const n = fibInput.value;
    const values = getFibonacciValues(n);
    fibDisplay.textContent = values.join(', ');
}


Now, this still has flaws, so we add a little bit of validation at least:


use parseInt to parse the value
check whether the input is at least 1
check whether the input is a number


The final result could look like this:



const fibButton = document.getElementById('fibClick');
const fibInput = document.getElementById('fibText');
const fibDisplay = document.getElementById('fibseq');

const getFibonacciValues = (n) =&gt; {
    const values = [];

    if (n &gt;= 1) {
        values.push(0);
    }
    
    if (n &gt;= 2) {
        values.push(1);
    }
    
    for (let i = 2; i &lt; n; ++i) {
        values.push(values[i - 2] + values[i -1]);
    }

    return values;
};

const outFib = () =&gt; {
    const n = parseInt(fibInput.value);

    if (n &lt; 1 || isNaN(n)) {
        fibDisplay.textContent = 'Please insert a number greater than 0';
        return;
    }
    
    const values = getFibonacciValues(n);
    fibDisplay.textContent = values.join(', ');
};

fibClick.addEventListener('click', outFib);
&lt;input type="text" id="fibText"&gt;
&lt;button id="fibClick"&gt;Generate Fibonacci Sequence&lt;/button&gt;
&lt;div id="fibseq"&gt;&lt;/div&gt;




Further improvements

This will fail for large inputs – try 2000 for example. You'll get a lot of Infinity.

You can take a look into bigNumber.js or you can set an upper limit, like if (n &gt; 1000) { fibDisplay.textContent = 'Too large'; return; } or you could store all values for your maximum n.



Calculating all numbers over and over again is some overhead you could avoid. You could cache already calculated values, and only add new values if n &gt; values.length. Alternatively you can store all numbers beforehand, which is an increase in memory usage, but your runtime becomes incredibly fast, as all you have left is:

const values = [0, 1, 1, 2, 3, …];
const output = values.splice(0, n);