How can I “undo” the programmatic insertion of text into a textarea?

后端 未结 12 652
失恋的感觉
失恋的感觉 2020-12-17 09:27

I have a textarea and a button. Clicking the button causes text to be inserted into the textarea.

Is there a way to allow a user to press Ctrl/Cmd+z to undo the inse

相关标签:
12条回答
  • 2020-12-17 10:02

    Add html first and you can use keypress event for undo

    you can try here also here http://jsfiddle.net/surendra786/1v5jxaa0/

                <input type="text" class="reset actor_input" name="actor" value="add actors"></input>
    
                <input type="text" name="actors"></input>
    
                <div class="found_actors"></div>
    
                <div id="add" class="button_content">ADD</div>
    
                <div id="undo" class="button_content">UNDO</div>
    
                <div class="actors_list"><textarea readonly style="resize: none;" rows="20" cols="20" name="actors-list"></textarea></div>
    
            </div>
    

    **then add jquery **

        var items = [];
    
    $("#add").click(function() {
        // Push the new actor in the array
        items.push($("[name='actor']").val());
        populate();
    });
    
    
    
    $(document).keydown(function(e){
           if( e.which === 90 && e.ctrlKey ){
             console.log('control + z'); 
             if (items.length > 0) {
            // remove last element of the array
            items.splice(-1,1);
            populate();
        }
          }          
    }); 
    
    populate = function() {
        $("[name='actors-list']").text('');
        $("[name='actors-list']").append(items.join('&#13;&#10;'));
        $("[name='actors']").val(items.join(','));   
    }
    

    you can try here http://jsfiddle.net/surendra786/1v5jxaa0/

    this is working for me

    0 讨论(0)
  • 2020-12-17 10:04
    $("#target").keypress(function(event) {
      if ( event.which == 'Z' && first press == 'Cmd' && second press == 'Ctrl') {//check for key press
         event.preventDefault();
        text.value = defaultValueForTextField
       }
    });
    

    That should be what you are looking for. First and Second press will need to be saved as you want combo presses. You will indeed need to save a default text value though.

    0 讨论(0)
  • 2020-12-17 10:07

    The simplest way seems this:

    • save previous textarea contents on button click, in an attribute of DOM textarea itself.
    • intercept keyboard at the BODY level (you don't know where the focus will be when and if Ctrl-Z is hit)
    • (optional) also intercept as many events from different objects as needed: input, keyPress, and so on, also at the BODY level.

    Now:

    • when the user clicks the button, old contents is saved and a custom "dirty" attribute of textarea is set to true
    • if the user hits Ctrl-Z or Cmd-Z, the undo routine is straightforward (in jQuery that would be $('#idOfTextarea').val($('#idOfTextarea').attr('prevContents')); . The undo routine also clears the "dirty" attribute so that undo is not called twice.
    • (optional) if the user alters another field, clicks somewhere else etc., the dirty attribute of the textarea is also cleared, and the change becomes undoable.
    • (optional) objects with an undo function of their own can/must stop the event propagation to avoid other undo's having two effects.

    You may want, or not, to also intercept onChange on the textarea. If onChange fires and dirty is not set, that is the initial button click and may be ignored. Otherwise it might indicate that the user has added some changes of his own to the text clicked in. In that case you may want to disable the undo to preserve those changes, or ask the user for confirmation.

    0 讨论(0)
  • 2020-12-17 10:10

    Save the original value of the textarea in its data:

    var $textarea = $('textarea');
    
    $('button').on('click', function () {
        var val = $textarea.val();
    
        $textarea.data('old-val', val).val(val + ' some text');
    });
    

    If you want an array of data (as @ahren suggested), use this:

    var $textarea = $('textarea');
    
    $('button').on('click', function () {
        var val = $textarea.val();
    
        if ( ! $textarea.data('old-val')) {
            $textarea.data('old-val', []);
        }
    
        $textarea.data('old-val').push(val);
    
        $textarea.val(val + ' some text');
    });
    
    0 讨论(0)
  • 2020-12-17 10:12

    Here is a thought:

    If we can generate the keyborad events just as if the user is typing in the textarea, then browser will automatically be able to handle Undo event. So instead of just appending / changing the value of textarea, we should try to simulate keyboard events for the text that we want to insert.

    As per the documentation at MDN (links given below), we can use KeyboardEvent object to generate the events like:

      var e1 = new KeyboardEvent(<type>, <details>);
      var b1 = <textbox>.dispatchEvent(e1);
    

    Where:

    • <type> represents the event type such as keydown, keypress or keyup
    • <details> represents the object having event details such key, code
    • <textbox> represents the target textbox on which we want to trigger the event

    Here is a JSFiddle where I've tried to simulate keydown, keypress and keyup events for each character in a given string. Though its firing the appropriate event handlers, somehow the chars are not getting displayed / added to textbox.

    What I've noticed is that there are some differences in the event object generated when I type a in the textbox verses when I simulate the 3 events for a using my code. The differences are (when tested in Firefox 50.1.0):

    1. explicitOriginalTarget is different than originalTarget when I simulate the events; and when I type in textbox both have same value
    2. rangeParent and rangeOffset values are null / 0 when I type in textbox; and when I simulate the events they have some values
    3. isTrusted property is true when I type in textbox; and when I simulate the events its false (For any event generated using script it will have false)

    MDN links:

    • Creating and triggering built in events
    • KeyboardEvent
    • KeyboardEvent Constructor
    0 讨论(0)
  • 2020-12-17 10:13

    You need to insert the text in a special way so the user can use the normal undo/redo behaviour.

    var textEvent = document.createEvent('TextEvent');
    
    textEvent.initTextEvent('textInput', true, true, null, "new text");
    
    document.getElementById("your-textarea").dispatchEvent(textEvent);
    
    0 讨论(0)
提交回复
热议问题