2

I was trying to write a script to 'play' some keys on this online keyboard by using JavaScript to 'click' the keys for me.

The code

//sample array to iterate over
var keys_ = ['et', 'dst', 'et', 'dst', 'et', 'b', 'dt', 'ct', 'a', ...];

//handles the clicking only
function playKey(id_) {
    key_ = document.getElementById(id_);
    key_.click(); }

//iterates over the array
function playKeys(keys_) {
    delay = 1000;
    for (i = 0; i < keys_.length; i++) {
        console.log(delay);
        key_ = keys_[i];
        console.log(key_);
        window.setTimeout('playKey(key_)', delay);
        delay += 1000; 
        } 
    }

The output

The console throws the following error:

1000
et
2000
dst
...
9000
a
undefined
Uncaught TypeError: Cannot read property 'style' of null p-ano.html:142
8 Uncaught TypeError: Cannot call method 'click' of null

As you can see, the delay and key_ values are perfectly correct. But still when I execute this, after a second (i.e., the 1st timeout), all the keys seem to play at once and then nothing happens.

What am I doing wrong?

P.S.: I've seen other questions like this one and searched Google and other forums, to no avail

Community
  • 1
  • 1
Yatharth Agarwal
  • 4,385
  • 2
  • 24
  • 53

3 Answers3

2

Learn about closures.

window.setTimeout(function(){ playKey(key_); }, delay);

and you have a problem with globals and locals. Use var!

The way I would write it would be

( function() {
    var keys_ = ['et', 'dst', 'et', 'dst', 'et', 'b', 'dt', 'ct', 'a'],
        delay = 250,
        currentIndex = 0,
        playKeys = function () {
            document.getElementById(keys_[currentIndex]).click();        
            currentIndex++;
            if (currentIndex<keys_.length) {
                window.setTimeout(playKeys,delay);
            }    
        };    
    playKeys();
})();
epascarello
  • 204,599
  • 20
  • 195
  • 236
1

Huh? There's already a built-in function called playstr().

function playstr(instr) {
    keystr = instr;
    time = 0;
    k = 0;
    for (i = 0; i < keystr.length; i++) {
        setTimeout("playkbd(keystr[k])", time += 50);
        setTimeout("k++", time + 50);
        setTimeout("cb()", time += 200);
    }
}​

Try pressing 'z', 'x', or 'm' to run them.

if (key=="z")
  playstr("wetyuyuju     ujo..juyyuj..uyttfy..yuytft     ujp..o;poko     opoj..uy\
  uju     ujo..juyyuj..uyttfy..yuytft     w e t y u y uoj u ")

if (key=="x")
  playstr("tgtdtgtdtgghhgtdd              tgtdtgtdtgghhgtdd              djjjkjhh\
  jhghjhg djjjkjhhjhghjhg djjjkjhhjhghjhg djjjkjhhjh     tgtdtgtdtgghhgtdd")

if (key=="m")
  playstr("         k j y j k j y f e f e a e f y j k j y j k j y f e f e a e f y\
   j k j y j k j y f e f e a e f y j k j y j k j y f e f e a e f y j ")

I am running a mirror and want to know how to auto-play chords.

// F F 1 F A N F A R E 

if (key==".") {
  setTimeout("playstr('u y u yo ok ok ku y g yf   u y u yo ok ok ku y u op ')",100)
}
Tina CG Hoehr
  • 6,721
  • 6
  • 44
  • 57
  • @TinaCGHeehr I don't understand. What is `playstr` and if it's a built-in, what are you showing here? – Yatharth Agarwal Sep 07 '12 at 14:36
  • Does `playkbd` simulate key presses? – Yatharth Agarwal Sep 07 '12 at 14:36
  • What's `cb`? What's `keystr` and how does the var `k` relate to it? – Yatharth Agarwal Sep 07 '12 at 14:38
  • Sorry, I'm so dense, but could you just explain a wee bit more? (Or maybe I'll be able to clear my head and grok the code or Google stuff myself after a proper night's sleep (I live in UTC +3:30) – Yatharth Agarwal Sep 07 '12 at 14:38
  • OK, view the source code for p-ano.js, there's a built-in function called `playstr`. Find it with Ctrl+F. That's how the original author decided to implement what you want. – Tina CG Hoehr Sep 07 '12 at 14:40
  • yes, please come back later when you have rested. The author has already done what you want. If you want, send me a youtube link of your song and i'll try to auto-play it :D – Tina CG Hoehr Sep 07 '12 at 14:41
  • @TinaCGHeehr I get it, so by built-in, you meant as in the source code for the Piano app. Thanks for clearing that up. Can you explain the rest of the code to me as I'm still a newbie to JS? – Yatharth Agarwal Sep 07 '12 at 14:48
  • I was trying to play this song: [Fur Elise](http://www.youtube.com/watch?v=_mVW8tgGY_w), though the real point of this was to test my scripting abilities. I always seem to learn more stuff like that... – Yatharth Agarwal Sep 07 '12 at 14:50
  • No prob. One last thing, this solution will probably work fine all right but can you explain why _my_ code isn't working? – Yatharth Agarwal Sep 07 '12 at 14:53
  • Go to my page and press "Z" http://tinabama.com/p-ano/p-ano.html `playstr(";p;p;jlkh adhj dhjk d ;p;p;jlkh adhj d kjh jkl;");` – Tina CG Hoehr Sep 07 '12 at 14:53
  • Continued discussion over [chat](http://chat.stackoverflow.com/rooms/16422/discussion-between-yatharthrock-and-tina-cg-hoehr) – Yatharth Agarwal Sep 07 '12 at 14:55
0

I am assuming the code you have posted is exactly what you are running. In this case the three dots are illegal.

keys_ = ['et', 'dst', 'et', 'dst', 'et', 'b', 'dt', 'ct', 'a', ...]

Try removing them like

keys_ = ['et', 'dst', 'et', 'dst', 'et', 'b', 'dt', 'ct', 'a']

Also, as a tip, try writing cleaner javascript. Use var before declaring variables. End your statements with ; semi-colons.

Kevin Brydon
  • 12,524
  • 8
  • 46
  • 76