3

タブを含むユーザー入力を処理するテキストエリアで一種のテキストエディターを作成しています。ユーザーが何かを入力するたびpaginate()に、ページ上のテキストを正しく改ページする関数を実行します。この関数には約 20 ミリ秒かかります。ここで、テキストエリアのページネーション中に 2 番目の入力を処理したくないので、条件を追加しましたが、そのようにするとctrl-V</kbdI 機能が失われます。したがって、この投稿での @Gabriel Gartz の提案に従います: textarea on input issue

最初にコンテキストとイベントを保存して、関数を再度呼び出します。関数は再度呼び出されますが、貼り付けはまだ行われません!

html:

<textarea id="taEditor"></textarea>

Javascript:

$("#taEditor").on('click keydown cut paste', processUserInput);

var IsProcessingEvent = false;

function processUserInput(e) {
    if(!IsProcessingEvent) {
        IsProcessingEvent = true;
        //do various stuff before the textarea changes like: get value, get   cursor pos etc
        var taValueBefore = document.getElementById("taEditor").value;
        if (e.keyCode === 9) {
          e.preventDefault();
          e.stopPropagation();
          document.getElementById("taEditor").value += "\t";
        }
        getcursorpos();
 
        //do various stuff after the textarea changes like: get value, get   cursor pos etc  
        setTimeout(function() {
            var taValueAfter = document.getElementById("taEditor").value;
            getcursorpos();
          if (taValueAfter !== taValueBefore) {
            paginate(); //this function paginates the text in the textarea and sets the cursor
            //paginate() takes about 20 milliseconds
          }
          if (doAgain.repeat) {
            var lastEvent = doAgain;
            doAgain.repeat = false;
            document.getElementById("debug").innerHTML += "rerun: " + lastEvent.ctx.id + ":" + lastEvent.e.type + "<br>";
            setTimeout(processUserInput.bind(lastEvent.ctx), 0, lastEvent.e);
          }
          document.getElementById("debug").innerHTML += e.type + "<br>";
          IsProcessingEvent = false;
        }, 0);
    } else {
      //save context and event
      document.getElementById("debug").innerHTML += "isprocessing: " + e.type + "<br>";
          doAgain = {
            ctx: this,
            e: e,
                  repeat: true
      };
      //i need to preventdefault here, because processUerInput also processes the TAB key and if i don't use preventdefault then the cursor will move focus to other elements during the pagination
          e.preventDefault();
          e.stopPropagation();
      return false;
    }
}

var doAgain = {
    ctx: "",
    e: "",
    repeat: false
};

function getcursorpos() {
  //for simplicity reasons it's empty
}

function paginate() {
  var i = 0;
  var k = 0;
  //simulate 20-30 milliseconds of delay for pagination
  for (i=0;i<100000000;i++) {
    k++;
  }
  //for simplicity reasons it's empty
}

jsfiddle:

http://jsfiddle.net/63pkE/1/

問題を再現するには、テキストエリアで ctrl-v を試してください。

私が間違っていることを理解していません。

編集

ここに私が置き換えた新しいjsfiddleがあります

        setTimeout(processUserInput.bind(lastEvent.ctx), 0, lastEvent.e);

ライン

        setTimeout(function() {
          processUserInput.call(lastEvent.ctx, lastEvent.e);
        }, 0);

クロスブラウザではないため.bind、それでも機能しません。

http://jsfiddle.net/63pkE/2/

4

1 に答える 1

0

これを試して、動作するかどうかを確認してください。元のコードの動作と現在のコピー ペーストの動作との違いに気付きませんでした。

function processUserInput(e) {
    if(!IsProcessingEvent) {
        if(!e.ctrlKey){
            IsProcessingEvent = true;
        }
    //Rest of the code

e.ctrlKey は、Ctrl キーが押された場合に true を返します。

于 2013-01-25T23:56:19.510 に答える