How to efficiently record user typing using javascript?

后端 未结 3 2179
悲&欢浪女
悲&欢浪女 2020-12-25 10:36

I\'d like to be able to record then playback whatever happened in a textarea.

I\'ve came across some solutions but they\'re not reliable, Like sending each keystroke

相关标签:
3条回答
  • 2020-12-25 10:58

    Databases are made to handle millions of records, so that's not really a problem.

    If you still don't want to do that you could encode all the data related to a session as JSON and store it in a text field in the database or as a file on the server. In this case if the data is really large it may take a while to load the data and send it to the browser, causing a delay for the user.

    0 讨论(0)
  • 2020-12-25 11:00

    Luckily JavaScript events already take care of all the encoding issues for you. You can just toss the whole event object that a keyup/keydown/keypress/whatever was directly into an array.

    Each object contains:

    • Type of event
    • Timestamp
    • What key was used (or combination of keys)
    • What was in focus
    • Some other stuff that might end up being useful.

    You can then just encode the array and send it off with your favourite ajax method to the server for storage.

    So your code only needs a function that can store data. Don't use this exact function it's just for demonstration purposes.

    var handler = function (e) { 
        handler.data.push(e);
        console.log(handler.data);
    }
    handler.data = [];
    
    window.addEventListener("keyup",    handler); 
    window.addEventListener("keydown",  handler); 
    window.addEventListener("keypress", handler);
    

    Since it's an array, they should all be in order, but in the odd event it goofs, you have timestamp data on each event (which also lets you find out the delay between events, which is AWESOME if you have mixed keypresses.).

    You can then replay events however you wish to design them -- but now you don't have to invent your own spec because the lovely fokes at w3c did all the hard work for you when they designed the DOM event spec.

    0 讨论(0)
  • 2020-12-25 11:03

    Store the time of each action and the result of that action and when you are finished serialise the log and store that.
    It is over-complicated to replay each action individually. Say a user moves back a few characters and adds new ones there. You will need to keep track of the cursor position.
    Just remember the entire value of the textarea for each keystroke. There is no need to remember how that occurred is there?

    Here's an implementation. fiddle

    <textarea id="recorder"></textarea>
    <textarea id="playback"></textarea>
    
    <script type="text/javascript">
    
    var Playback = {
        //store the time an action occured and the resulting state in an object
        //don't use an array because they are not sparce - interstitial keys
        //will have to be iterated over
        record: {},
        init: function( recorderId, playbackId ) {
            this.recorder = document.getElementById( recorderId );
            this.playback = document.getElementById( playbackId );
    
            this.recorder.addEventListener( 'focus', function() {
                Playback.record = {};
                this.value = '';
            }, false );
    
            this.recorder.addEventListener( 'keyup', function( e ) {
                Playback.record[ (new Date()).getTime() ] = this.value;
            }, false );
    
            this.recorder.addEventListener( 'blur', function( e ) {
                Playback.playback.value = '';
                //store the time the sequence started
                //so that we can subtract it from subsequent actions
                var mark = null;
                for( var t in  Playback.record ) {
                    if( mark ) {
                        var timeout = t - mark;
                    } else {
                        var timeout = 0;
                        mark = t;
                    }
                    // We need to create a callback which closes over the value of t
                    // because t would have changed by the time this is run
                    setTimeout( Playback.changeValueCallback( Playback.record[t] ), timeout );
                }
            }, false );
    
        },
    
        changeValueCallback: function( val ) {
            return function() { Playback.playback.value = val }
        }
    }
    
    Playback.init( 'recorder', 'playback' );
    
    </script>
    

    Caveat: The event handling is for compliant browsers only, you'd need to accommodate internet explorer yourself

    0 讨论(0)
提交回复
热议问题