1

我有一个文本区域,在用户键入 @ 符号后自动完成功能启动。类似于 Twitter 处理用户名自动完成的方式。我使用 jQuery自动完成插入符号插件。

通常,自动完成会用用户选择的任何内容替换整个文本字段。在这种情况下,它只替换@之后的部分。如果文本中有多个 @ 符号,它甚至可以工作。

我的 CoffeeScript 有点生疏,所以我想知道是否有人可以提出一些改进建议。特别是我不喜欢在搜索和源方法之间传递变量(如当前光标位置)的方式。

$('.myTextArea').autocomplete
search: (event,ui) ->
  # Figure out where in the text we are currently typing
  # Cursor position:
  target = $("#" + event.target.id)  # I'm sure there's a more elegant solution
  window.cursor_pos = target.caret()
  window.word = getWordAt(event.target.value, window.cursor_pos); 

  if window.word[0] == "@"
    $('#spinner').show()
  else
    return false
open: (event, ui) ->
  $('#spinner').hide()
focus: (event, ui) ->
  return false
source: (request, response)  ->
  $.getJSON("/users/autocomplete_username", { term: window.word.slice(1) }, response);
select: (event,ui) ->
  start_of_word =  window.cursor_pos - window.word.length + 1
  start = event.target.value.substring(0, start_of_word)
  ending = event.target.value.substring(window.cursor_pos, event.target.value.length)

  event.target.value = start +  ui.item.id + ending
  target = $("#" + event.target.id) 
  target.caret(start_of_word + ui.item.id.length )
4

1 回答 1

1

良好的直觉回复:在搜索和来源之间传递光标位置 - 将东西附加到window导致死亡!:) 本地范围的变量可以正常工作并且更安全(见下文)。

我一眼就注意到的另一件事是您对 的使用word[0],这在某些浏览器中是未定义的;对于字符串字符访问,您实际上应该使用charAt()跨浏览器友好的。除了 var 作用域之外,我还在这里进行了更改:

cursor_pos = word = null

$('.myTextArea').autocomplete
  search: (event,ui) ->
    # Figure out where in the text we are currently typing
    # Cursor position:
    target = $("#" + event.target.id)  # I'm sure there's a more elegant solution
    cursor_pos = target.caret()
    word = getWordAt(event.target.value, cursor_pos); 

    if word.charAt(0) == "@"
      $('#spinner').show()
    else
      return false
  open: (event, ui) ->
    $('#spinner').hide()
  focus: (event, ui) ->
    return false
  source: (request, response)  ->
    $.getJSON("/users/autocomplete_username", { term: word.slice(1) }, response);
  select: (event,ui) ->
    start_of_word =  cursor_pos - word.length + 1
    start = event.target.value.substring(0, start_of_word)
    ending = event.target.value.substring(cursor_pos, event.target.value.length)

    event.target.value = start +  ui.item.id + ending
    target = $("#" + event.target.id) 
    target.caret(start_of_word + ui.item.id.length )
于 2013-06-14T09:39:20.793 回答