Jump to content

How to convert a program with functions to one with none by making it plain


xcislav

Recommended Posts

Here's a fragment of working code with "functions inside functions". It has a "= function" definition. Here the word function is used too many times. It's a function inside a function and inside the next one. And finally the last function calls the first with all of them inside.Actually, the program has a very simple algorithm of counting typing speed:1 Starts the timer on a key-press2 Iterates every time as every next key is pressed and the stop point is in it's last key-press3 Outputs the delta in milliseconds (even without any conversion).

 

The whole program:

<script type="text/javascript">    var timing = {        st: null,        en: null,        tx: null    }; // start, end, textbox    function initpr() {        timing.tx = document.getElementById('prin');        var tx = timing.tx;        tx.onkeypress = function () {            timing.st = timing.en = new Date();            timing.tx.onkeypress = function (en) {                if (!en) en = event;                timing.en = new Date();            }        }    }    function clc() {        r = document.getElementById('resultpr');        deltams = timing.en.getTime() - timing.st.getTime();        chars = timing.tx.value.length;        cpms = chars / deltams;        snippets = [chars, " chars (in ", deltams, " ms): ", cpms, " cpms"];        r.innerHTML = snippets.join("");        initpr();    }</script><form name="foo" onsubmit="return false;">    <textarea id="prin"></textarea>    <br />    <input id="btnclc" />    <span id="resultpr"></span> </form><script type="text/javascript">    document.getElementById('btnclc').onclick = clc;    initpr();</script>

Function initpr have additional nested functions:

    function initpr() {        timing.tx = document.getElementById('prin');        var tx = timing.tx;        tx.onkeypress = function () {            timing.st = timing.en = new Date();            timing.tx.onkeypress = function (en) {                if (!en) en = event;                timing.en = new Date();            }        }    }

 

Joining elements are:

tx.onkeypress = function

timing.tx.onkeypress = function

 

 

It looks like cycle inside another one. Though it's not. Is there any possible way how to eliminate those that join?

Edited by xcislav
Link to comment
Share on other sites

My version...

<!DOCTYPE html><html><head><meta charset="utf-8"><title>xcislav</title><style>textarea{width:600px;height:200px;background-color:#eee;}</style><script>window.onerror = function(m, u, l){alert('Javascript Error: '+m+'nURL: '+u+'nLine Number: '+l);return true;}</script><script>var t = {};t.start = null;t.last;t.cnt;t.out;t.setint;   window.onload = init;function init(){var txin = document.getElementById('textin');if(t.start != null){clearInterval(t.setint);var len = txin.value.length;if (len != t.cnt){alert('len:'+len+' cnt:'+t.cnt);}}txin.onkeypress = clc;txin.value = '';txin.focus();t.start = null;t.cnt = 0;t.out = document.getElementById('out1');t.out.innerHTML = '';document.getElementById('btn').onclick = init;t.setint = setInterval(disp,3000);}function clc() {var d = new Date();t.cnt++;if (t.start == null){t.start=d.getTime();}else{t.last=d.getTime();   }}function disp(){if (t.cnt>1){var delta = (t.last-t.start)/1000;t.out.innerHTML = t.cnt +' chars (in '+ delta +' s): '+ (t.cnt/delta).toFixed(4) +' cps';} } </script></head><body><textarea id="textin"></textarea><br/><input type="button" id="btn" value="Clear"/><div id="out1"></div></body></html>

...or a global paranoid version...

<!DOCTYPE html><html><head><meta charset="utf-8"><title>xcislav 2</title><style>textarea{width:600px;height:200px;background-color:#eee;}</style><script>if(typeof typx === 'undefined'){var typx = {};typx.start = null;typx.last;typx.cnt;typx.out;typx.setint;}else{alert('Namespace error');throw {name:"error",message:"Namespace error"};}typx.init = function(){var txin = document.getElementById('textin');if(typx.start != null){clearInterval(typx.setint);var len = txin.value.length;if (len != typx.cnt){alert('len:'+len+' cnt:'+typx.cnt);}}txin.onkeypress = typx.clc;txin.value = '';txin.focus();typx.start = null;typx.cnt = 0;typx.out = document.getElementById('out1');typx.out.innerHTML = '';document.getElementById('btn').onclick = typx.init;typx.setint = setInterval(typx.disp,3000);};typx.clc = function() {var d = new Date();typx.cnt++;if (typx.start == null){typx.start=d.getTime();}else{typx.last=d.getTime();   }};typx.disp = function(){if (typx.cnt>1){var delta = (typx.last-typx.start)/1000;typx.out.innerHTML = typx.cnt +' chars (in '+ delta +' s): '+ (typx.cnt/delta).toFixed(4) +' cps';} };window.addEventListener('load', typx.init, false); </script></head><body><textarea id="textin"></textarea><br/><input type="button" id="btn" value="Clear"/><div id="out1"></div></body></html>
  • Like 1
Link to comment
Share on other sites

Here the word function is used too many times.

What does that even mean? Why are you trying to remove anonymous functions and closures? The only change I would make to that would be to wrap the whole thing inside another function to eliminate any naming conflicts with the global variables and functions.
Link to comment
Share on other sites

It's the same (smaller and -"brain pain"):

<textarea id="b" onblur="clc();"></textarea><script>t=0;x=document.getElementById('b');x.onkeypress=function(){t==0 ? s=new Date() : e=new Date();t=1;}function clc(){d = e.getTime() - s.getTime();c = b.value.length;b.value += +c+"s in "+d+"ms: "+c/d+" cpms";}</script>

How the HE does 1st work?

Edited by xcislav
Link to comment
Share on other sites

It seems obvious to me how it works, what don't you understand? Anonymous functions are used all the time in Javascript, especially for event handlers or other single-use functions. If you're only using a function in one place that's the cleanest way to do it.

Link to comment
Share on other sites

I don't like the looks of the original, but maybe Hadien would. But also I don't like the looks of super-minimized code. If you want all your vars to be one digit then run a minifier afterwards. Source code is supposed to have var names that are meaningful and easy to read. For something more in the original direction (minimal globals) I would try to come up with something that looks simpler such as...

<!DOCTYPE html><html><head><meta charset="utf-8"><title>xcislav quiet</title><style>textarea{width:600px;height:200px;background-color:#eee;}</style><script>    window.addEventListener('load', function() {    var start;    var end;    var prna = document.getElementById('printa');    var out = document.getElementById('results');    out.innerHTML = '';    prna.value = '';        prna.onkeypress = function() {       end = new Date();       if (start===undefined){start=end;}    }        document.getElementById('btnclc').addEventListener('click', function() {       if (start!=undefined){          var delta = (end.getTime() - start.getTime())/1000;          var chars = prna.value.length;          var cps = chars/delta;          out.innerHTML = chars +' chars (in '+ delta.toFixed(1) +' sec): '+ cps.toFixed(3) +' cps';       }    });});</script></head><body>    <textarea id="printa"></textarea><br />    <input type="button" id="btnclc" />    <span id="results"></span></body></html>
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...