关于html:stackoverflow如何使它的Tag输入字段?

How does stackoverflow make its Tag input field?

StackOverflow如何创建其标签系统。如何在文本区域中格式化html?

我只是不知道从哪里开始。如果有人可以指导我,那么我可以知道应该采取什么方向,这样我就可以编写一些可以检查的代码。

赞:

enter


Bootstrap解决方案如何?

您可以尝试以下方法:

HTML代码:

1
<input type="text" value="html,input,tag" data-role="tagsinput"></input>

对于CSS,调用以下两个文件:

1
2
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="http://bootstrap-tagsinput.github.io/bootstrap-tagsinput/dist/bootstrap-tagsinput.css">

对于Javascript,调用以下两个文件:

1
2
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js">
<script src="http://bootstrap-tagsinput.github.io/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js">

代码将在下面生成结果:

enter


我要做的是:

  • 创建一个带边框的主DIV(例如此处的边框1px实心#000)
  • 之后,在此DIV中,我将创建另一个DIV(float:左;),另一个DIV(float:右)和右div中的输入。

当您在输入中编写内容并假设您选择HTML时,它将在左侧DIV中创建一个跨度,并减小右侧div的宽度以匹配其余大小。当然,在您的跨度之内是带有删除符号的文本HTML。

您可以使用jQuery轻松实现。

示例:

1
        <input type="text" value="" />

然后您编写一些jQuery / JS


不是。如果查看DOM,最初只会看到一个输入框。添加标签后,它将在带有该标签及其删除图标的输入框之前插入一个<span>标签。输入框现在位于此<span>标记的右侧。单击标签进行编辑时,它将在其位置放置一个文本框,以便您可以对其进行编辑。所有这些操作都是使用Javascript完成的,并且有一些JQuery插件可以帮助您完成此操作。这是来自Google的快速搜索:http://xoxco.com/projects/code/tagsinput/

就样式而言,<span>元素可以具有您想要的任何CSS。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var es = document.querySelectorAll('.input-categories');
for (var i = 0; i < es.length; i++) {
  es[i]._list = es[i].querySelector('ul');
  es[i]._input = es[i].querySelector('input');
  es[i]._input._icategories = es[i];
  es[i].onkeydown = function(e){
    var e = event || e;
    if(e.keyCode == 13) {
      var c = e.target._icategories;
      var li = document.createElement('li');
      li.innerHTML = c._input.value;
      c._list.appendChild(li);
      c._input.value = '';
      e.preventDefault();
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
*{
  margin: 0px;
  padding: 0px;
}

.input-categories{
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  border: 1px solid black;
}

.input-categories ul{
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  list-style-type: none;
  flex-wrap: wrap;
}

.input-categories li{
  border: 1px solid black;
  border-radius: 2px;
  padding: 1px;
  margin: 1px;
}
.input-categories input{
  flex: 1 1 auto;
  align-self: flex-start;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<ul>

   
<li>
moscow
</li>

   
<li>
new york
</li>

 
</ul>

  <input type="text"/>



 
<ul>

   
<li>
CSS
</li>

   
<li>
PHP
</li>

 
</ul>

  <input type="text"/>


反应功能组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const AutoList=()=>{
const [currentTagText, setCurrentTagText] = useState("");
const [tags, setTags] = useState(["javascript"]);

const handleTag = (e) => {
   setCurrentTagText(e.target.value);
   if (e.keyCode == 13 && currentTagText) {
    setTags((prevTags) => [...prevTags, currentTagText]);
    setCurrentTagText("");
   } else if (e.keyCode == 32 && currentTagText) {
    setTags((prevTags) => [...prevTags, currentTagText]);
    setCurrentTagText("");
   }
};
const removeTag = (index) => {
   const newTagArray = tags;
   newTagArray.splice(index, 1);
   setTags([...newTagArray]);
};

return (

 
          <div
            className="stackTags"
            style={{ display: tags.length > 0 ?"flex" :"none" }}
          >
            {tags.map((tag) => {
              return (
             
                 <button
                    onClick={() => removeTag(index)}
                    className="tagCloseBtn"
                  >
                    x
                  </button>
                  #{tag}
             
               )
            })}
         
         
            <input
              type="text"
              onKeyDown={handleTag}
              onChange={handleTag}
              value={currentTagText}
            />
         
       
 )

}

CSS:-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
.masterStackDiv {
  width: auto;
  background-color: transparent;
  border: none;
  display: flex;
  align-items: center;
}
.stackInput input[type="text"] {
  border: none;
  background-color: transparent;
  color: white;
  font-family:"Segoe UI";
  font-size: 0.8em;
  float: right;
  margin-left: 5px;
  width: auto;
  border-bottom: 2px solid white;
}

.stackTag {
  background-color: #707070;
  color: white;
  height: 20px;
  width: auto;
  border-radius: 10px;
  font-size: 0.7em;
  padding: 5px;
  margin: 3px;
  display: flex;
  align-items: center;
}

.stackTags {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 30px;
  width: auto;
}
.tagCloseBtn {
  border: none;
  background-color: transparent;
  border-radius: 5px;
}
.tagCloseBtn:hover {
  background-color: white;
  cursor: pointer;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const {useState} = React
 
const StackTag=()=>{
 const [currentTagText, setCurrentTagText] = useState("");
 const [tags, setTags] = useState(["javascript"]);
 
 const handleTag = (e) => {
    setCurrentTagText(e.target.value);
    if (e.keyCode == 13 && currentTagText) {
      setTags((prevTags) => [...prevTags, currentTagText]);
      setCurrentTagText("");
    } else if (e.keyCode == 32 && currentTagText) {
      setTags((prevTags) => [...prevTags, currentTagText]);
      setCurrentTagText("");
    }
  };
 
  const removeTag = (index) => {
    const newTagArray = tags;
    newTagArray.splice(index, 1);
    setTags([...newTagArray]);
  };

  return (
       
              <div
                className="stackTags"
                style={{ display: tags.length > 0 ?"flex":"none"}}
              >
                {tags.map((tag, index) => {
                  return (
                   
                      <button
                        onClick={() => removeTag(index)}
                        className="tagCloseBtn"
                      >
                        x
                      </button>
                      #{tag}
                   
                  );
                })}
             
             
                <input
                  type="text"
                  onKeyDown={handleTag}
                  onChange={handleTag}
                  value={currentTagText}
                />
             
           
            )
       }
ReactDOM.render(<StackTag/>,document.getElementById("react"))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
.masterStackDiv {
  width: auto;
  background-color: transparent;
  border: none;
  display: flex;
  align-items: center;
}
.stackInput input[type="text"] {
  border: none;
  background-color: transparent;
  color: black;
  font-family:"Segoe UI";
  font-size: 0.8em;
  float: right;
  margin-left: 5px;
  width: auto;
  border-bottom: 2px solid black;
}

.stackTag {
  background-color: #707070;
  color: white;
  height: 20px;
  width: auto;
  border-radius: 10px;
  font-size: 0.7em;
  padding: 5px;
  margin: 3px;
  display: flex;
  align-items: center;
}

.stackTags {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 30px;
  width: auto;
}
.tagCloseBtn {
  border: none;
  background-color: transparent;
  border-radius: 5px;
}
.tagCloseBtn:hover {
  background-color: white;
  cursor: pointer;
}
1
2
3
4
5
6
7
8
9
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js">
</head>
<body>

</body>
</html>