1

我有以下情况:

当用户停止在文本区域中输入时,我想等待 2 秒,如果用户在这 2 秒内没有更改 textarea 中的任何内容,我想将 textarea 的内容保存到服务器。如果用户在这 2 秒内更改了 textarea 中的某些内容,我想重新启动等待超时。

在 JavaScript 中,我会像这样实现它

http://codepen.io/ondrejsevcik/pen/LRxWQP

// Html
<textarea id="textarea"></textarea>
<pre id="server"></pre>

// JavaScript
var textarea = document.querySelector('#textarea');

var textValue = "";
textarea.oninput = function (e) {
  textValue = e.target.value;
  setSaveTimeout();
}

let saveTimeout;
function setSaveTimeout() {
  if (saveTimeout) {
    clearTimeout(saveTimeout);
  }
  saveTimeout = setTimeout(saveToServer, 2000);
}

function saveToServer() {
  document.querySelector('#server').innerText =
    'Value saved to server: ' + textValue;
}
4

1 回答 1

0

实现该行为的一种方法是...

  1. 挂钩onInput事件
  2. onInput处理程序中,创建一个在 2 秒后触发的任务,当前值为 textarea。还存储 textarea 内容。
  3. 检查值是否已更改,如果值未更改则保存。

在这里,它不会取消Task,因此它可能效率不高。

-- MODEL
type alias Model =
  { str : String
  , saved : String
  }

init : (Model, Cmd Msg)
init =
  (Model "" "", Cmd.none)

-- UPDATE
type Msg
  = ChangeText String
  | Save String
  | NoOp ()

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    NoOp _ -> (model, Cmd.none)
    Save str ->
      let
        _ = Debug.log "save" str
        newmodel =
          if model.str /= str
          then model
          else { model | saved = str }
      in (newmodel, Cmd.none)    
    ChangeText str ->
      let
        _ = Debug.log "textarea" str
        cmd = Task.perform NoOp Save <|
          Process.sleep (2 * Time.second)
          `Task.andThen`
          \_ -> Task.succeed str
      in ({ model | str = str }, cmd)

-- VIEW
view : Model -> Html Msg
view model =
  Html.div []
  [ Html.textarea [ onInput ChangeText ] []
  , Html.div [] [ Html.text <| "saved: " ++ model.saved ]
  ]
于 2016-09-23T01:33:45.460 回答