创造Stack Overflow的标签系统?

4

我正在尝试创建一个类似于SO的标签系统。我已经添加了标签,现在想要删除它们。

我的问题:

  • 如何删除已添加的标签?
  • 如何使叉号按钮(一个span元素)看起来与SO标签系统中的叉号一样?

SO TAGGING

var tags = [];
$("#textBox").keypress(function (e) {
    if (e.which === 13) {
        $(".target").append("<a href='#' class='tag' >"  + this.value+'<span class="cross" onclick="remove_tag()">X</span>'+ "</a>");

        function remove_tag(){
        //what to do here?
        }
        tags.push(this.value);
        this.value = "";
    }
});

2
http://ivaynberg.github.io/select2/ - hjpotter92
1
不需要使用 JavaScript,我认为 25 行代码就足够完成这个任务了。请查看 fiddle,添加已经完成,现在还需要删除功能。 - HIRA THAKUR
回答问题2 - 从源代码来看,他们使用了一个精灵图像来表示X。 - rtpHarry
由于您正在keypress回调内定义remove_tag函数,因此它不在onclick事件触发的范围内。请尝试在其定义之外定义该函数。 - Eric Levine
4个回答

2
这是我的JSFiddle链接:http://jsfiddle.net/Wky2Z/11/。基本上,监听.cross被点击,然后从数组中删除删除元素。请注意保留HTML标记。
//enter something in textbox and press enter....
var tags = [];
$("#textBox").keypress(function (e) {
    if (e.which === 13) {
        $(".target").append("<a href='#' class='tag' >"  + this.value+'<span class="cross">X</span>'+ "</a>");


        tags.push(this.value);
        this.value = "";
    }
});

$('body').on('click','.cross',function(){

    tags.splice($(this).parent('a').html(), 1);
    $(this).parent('a').remove();
});

关于十字架的外观,SO使用CSS Sprite,因此您可以通过制作包含两种状态(关闭(灰色)和悬停(红色))的png、gif或jpeg图像,并使用CSS将background-position切换为红色,例如:.cross:hover { background-position:0px -20px }


1
你可以使用remove()删除元素。此外,我建议您使用jQuery事件而不是使用内联事件。(如果您查看stackoverflow的源代码,您会注意到没有内联javascript调用)在这种情况下,您需要向document对象添加事件处理程序,因为您想将事件分配给从开始时未加载到DOM中的元素。
$(document).on('click', '.tag span', function(){
   $(this).parent().remove();
});

实例展示: http://jsfiddle.net/Wky2Z/7/

更新

我更新了这个例子,也从标签列表中移除了该元素: http://jsfiddle.net/Wky2Z/8/

为标签链接添加了一个 data-value:

$(".target").append("<a href='#' class='tag' data-value='" + this.value + "' >"  + this.value+'<span class="cross">X</span>'+ "</a>");

并修改了点击事件:

$(document).on('click', '.tag span', function(){
   $(this).parent().remove();
   var removeItem = $(this).parent().data('value');

   tags = $.grep(tags, function(value) {
       return value != removeItem;
   });
});

1

如果您需要完整的jQuery解决方案,可以删除内联remove_tag函数并使用jQuery on函数。它也适用于动态创建的元素。

为所选元素附加一个或多个事件处理程序函数。

在这里,您可以获取已删除元素的父元素,并使用remove从DOM中删除它。

要将数组与当前情况“同步”,您可以使用grep从数组中删除该项;请注意使用removedItem变量仅获取父项的文本,不包括子项。

代码:

//enter something in textbox and press enter....
var tags = [];
$(document).ready(function () {

    $('body').on('click', 'span.cross', function () {
        var removedItem = $(this).parent().contents(':not(span)').text();
        $(this).parent().remove();
        tags = $.grep(tags, function (value) {
            return value != removedItem;
        });
    });

    $("#textBox").keypress(function (e) {
        if (e.which === 13) {
            $(".target").append("<a href='#' class='tag' >" + this.value + '<span class="cross">X</span>' + "</a>");

            tags.push(this.value);
            this.value = "";
        }
    });
});

示例:http://jsfiddle.net/IrvinDominin/pDFnG/


基本上和我建议的一样,但你使用了 contents 而不是使用 data 属性。 - Alvaro

0

这是更新后的链接:http://jsfiddle.net/Wky2Z/6/

remove_tag移出keypress事件处理程序,并传递一个this指针以进行快速解决:

//enter something in textbox and press enter....
var tags = [];

function remove_tag(x) {
    $(x).parent('a').remove();
}
$(function () {
    $("#textBox").keypress(function (e) {
        if (e.which === 13) {
            $(".target").append("<a href='#' class='tag' >" + this.value + '<span class="cross" onclick="remove_tag(this)">X</span>' + "</a>");

            tags.push(this.value);
            this.value = "";
        }
    });
});

我应该在 DOM 准备好之外编写 remove_tag(x) 函数吗? - HIRA THAKUR
@VAGABOND 是的,在外面。 - rtpHarry
@rtpHarry: 但是标签数组会超出范围吗?如果我将它放在dom准备好的位置,这样可以吗? - HIRA THAKUR
@VAGABOND,你为什么在使用tags数组? - hjpotter92
1
我认为你需要像这样在remove_tag()方法中加入array.splice https://dev59.com/wG865IYBdhLWcg3wKLT6#13361892,以保持标签数组与UI同步。 - rtpHarry
选择一个答案很难,因此我会为每个回答投票,并勾选最完整的回答。 - HIRA THAKUR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接