我有一个文本区域,用户键入@符号后自动完成功能就会启动。类似于Twitter处理用户名自动完成的方式。我使用jQuery autocomplete和caret插件。
通常,自动完成功能会将用户选择的任何内容替换为整个文本字段。在这种情况下,它只替换@之后的部分。如果文本中有多个@符号,它甚至可以工作。
我的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 )
答案 0 :(得分: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 )