我正在尝试在我的应用程序中实现一个“标签编辑器”字段,就像 SO 一样。现在我得到了这个:
编辑:我已将其编码到一个 jQuery 插件中: https ://github.com/fernandotenorio/tagme.git
小提琴
http://jsfiddle.net/FernandoTen/PnYuF/
html
<div style="margin-left: auto; margin-right: auto; width: 400px;">
<span style='color: #333; font-size: small'>
Tags [a-z A-Z 0-9 # + . -]
</span>
<div id='tags_container'>
<span id='tags_queue'></span>
<input type='text' id='tf' />
</div>
</div>
js
$(document).ready(function () {
var rexp = /[^a-zA-Z0-9#+\.\-]/
var left = 37;
var right = 39;
var del = 8;
var space = 32;
var comma = 188;
var minlen = 3;
var maxlen = 15;
var current_tag = null
$('#tf').focus().attr('maxlength', maxlen)
$('#tags_container').click(function () {
$('#tf').focus()
})
$('#tf').keydown(function (e) {
var code = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
var txt = $(this).val().trim()
// handle navigation between tags
if ((code === left || code === right) && txt.length === 0) {
if (!current_tag)
{
if (code === left)
current_tag = $('#tags_queue span').last()
else
current_tag = $('#tags_queue span').first()
if (current_tag.length > 0) current_tag.css('background-color', '#9FC2D6')
} else //current tag exists
{
if (code === left)
current_tag = current_tag.css('background-color', '#B8D0DE').prev()
else
current_tag = current_tag.css('background-color', '#B8D0DE').next()
if (current_tag.length > 0)
current_tag.css('background-color', '#9FC2D6')
// hit last/first, clean current_tag
else
{
current_tag.css('background-color', '#B8D0DE')
current_tag = null
}
}
}
});
$('#tf').keypress(function (e) {
var token = String.fromCharCode(e.which)
var code = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
if (token.match(rexp) && (code !== del) && (code !== left) && (code !== right))
return false;
});
$('#tf').keyup(function (e) {
var code = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
var txt = $(this).val().trim()
if (code === del && txt.length === 0 && current_tag) {
current_tag.remove()
current_tag = null
return
}
// clean current_tag, user is typing
if (current_tag && (code !== left) && (code != right))
{
current_tag.css('background-color', '#B8D0DE')
current_tag = null
}
if (txt.length > maxlen) txt = txt.substring(0, maxlen)
if (txt.match(rexp)) {-
$(this).val("")
return
} else if (code === space || code === comma) {
if (txt.length < minlen) return;
var tag = $('<span></span>', {
'class': 'tag'
}).html(txt).append($('<a></a>', {
'class': 'close_tag',
html: '×',
click: function () {
$(this).parent().fadeOut(function(){
$(this).remove()
current_tag.css('background-color', '#B8D0DE')
current_tag = null
})
}
}))
$('#tags_queue').append(tag)
$(this).val("")
}
});
})
css
div#tags_container {
border: 1px solid #ccc;
padding-bottom: 5px;
border-radius: 5px;
background-color: beige;
overflow: hidden;
}
input#tf {
border: 1px solid orange !important;
outline: none !important;
background-color: transparent !important;
height: 30px;
margin-top: 2px;
padding-left: 5px;
}
a.close_tag {
margin-left: 5px;
color: #fff;
}
a.close_tag:hover {
cursor: pointer;
}
span.tag {
background-color: #B8D0DE;
color: #111;
margin-left: 5px;
margin-top: 5px;
padding: 5px;
float: left;
border-radius: 5px;
}
span.tag:hover {
background-color: #9FC2D6;
}
span#tags_queue {
margin-right: 5px;
vertical-align: middle;
}
问题是,我如何像 SO 那样使用箭头键处理“隐藏”内容?看起来我必须处理文本字段内的光标位置,并注意左箭头和右箭头事件......还有对已完成标签的点击。
我可以想到以下(反SO设计)解决方案:
white-space: nowrap
从div中删除tags_container
,并让 div 在用户添加更多标签时“增长”。添加
overflow: scroll
到tags_container
div(非常难看!)
所以,我很欣赏关于如何近似SO 标签编辑器行为的任何新想法。谢谢!