草庐IT

javascript - 模拟 SO 标签编辑器

coder 2023-08-04 原文

我正在尝试在我的应用程序中实现“标签编辑器”字段,方法与 SO 相同。 现在我得到了这个:

编辑:我已经将其编码到一个 jQuery 插件中: https://github.com/fernandotenorio/tagme.git

fiddle

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: '&times',
            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设计)方案:

  1. tags_container div 中删除 white-space: nowrap,然后让 随着用户添加更多标签,div“增长”。

  2. overflow: scroll 添加到 tags_container div(非常难看!)

因此,我很欣赏关于如何近似 SO 标签编辑器行为的任何新想法。 谢谢!

最佳答案

重新发明轮子是一种不好的做法:看看优秀的 Tag-it jQuery 插件代码,它实现了您正在处理的内容。

关于javascript - 模拟 SO 标签编辑器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17256460/

有关javascript - 模拟 SO 标签编辑器的更多相关文章

  1. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  2. ruby - 在院子里用@param 标签警告 - 2

    我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

  3. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  4. css - 用 watir 检查标签类? - 2

    我有一个div,它根据表单是否正确提交而改变。我想知道是否可以检查类的特定元素?开始元素看起来像这样。如果输入不正确,添加错误类。 最佳答案 试试这个:browser.div(:id=>"myerrortest").class_name更多信息:http://watir.github.com/watir-webdriver/doc/Watir/HTMLElement.html#class_name-instance_method另一种选择是只查看具有您期望的类的div是否存在browser.div((:id=>"myerrortes

  5. ruby-on-rails - 在这种情况下我如何模拟一个对象?没有明显的方法可以用模拟替换对象 - 2

    假设我在Store的模型中有这个非常简单的方法:defgeocode_addressloc=Store.geocode(address)self.lat=loc.latself.lng=loc.lngend如果我想编写一些不受地理编码服务影响的测试脚本,这些脚本可能已关闭、有限制或取决于我的互联网连接,我该如何模拟地理编码服务?如果我可以将地理编码对象传递到该方法中,那将很容易,但我不知道在这种情况下该怎么做。谢谢!特里斯坦 最佳答案 使用内置模拟和stub的rspecs,你可以做这样的事情:setupdo@subject=MyCl

  6. ruby - "public/protected/private"方法是如何实现的,我该如何模拟它? - 2

    在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定

  7. ruby - 在 RSpec 中 stub /模拟全局常量 - 2

    我有一个gem,它有一个根据Rails.env的不同行为的方法:defself.envifdefined?(Rails)Rails.envelsif...现在我想编写一个规范来测试这个代码路径。目前我是这样做的:Kernel.const_set(:Rails,nil)Rails.should_receive(:env).and_return('production')...没关系,只是感觉很丑。另一种方法是在spec_helper中声明:moduleRails;end而且效果也很好。但也许有更好的方法?理想情况下,这应该有效:rails=double('Rails')rails.sho

  8. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  9. ruby - 如何用 Nokogiri 解析连续的标签? - 2

    我有这样的HTML代码:Label1Value1Label2Value2...我的代码不起作用。doc.css("first").eachdo|item|label=item.css("dt")value=item.css("dd")end显示所有首先标记,然后标记标签,我需要“标签:值” 最佳答案 首先,您的HTML应该有和中的元素:Label1Value1Label2Value2...但这不会改变您解析它的方式。你想找到s并遍历它们,然后在每个你可以使用next_element得到;像这样:doc=Nokogiri::HTML(

  10. ruby-on-rails - 在 Label 标签中嵌套 Ruby on Rails HAML 复选框 - 2

    我有以下不起作用的代码:=form_for(resource,:as=>resource_name,:url=>session_path(resource_name),:html=>{:class=>"well"})do|f|=f.label:email=f.email_field:email=f.label:password=f.password_field:password-ifdevise_mapping.rememberable?%p=f.label:remember_me,:class=>"checkbox"=f.check_box:remember_me,:class=>"

随机推荐