Html stackoverflow 如何制作它的 Tag 输入字段?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10839570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 00:46:44  来源:igfitidea点击:

How does stackoverflow make its Tag input field?

htmlinputtags

提问by Mathew Kurian

How does StackOverflow create its tag system. How can it format the html in a text area?

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

I just don't know where to begin. If someone could guide me, then I can know what direction to take so I can write some code that someone can check.

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

Like this:

像这样:

enter image description here

在此处输入图片说明

EDIT: Basically, when I press space, how do i add a new element/div to the inside of the div?

编辑:基本上,当我按下空格键时,如何在 div 内部添加一个新元素/div?

采纳答案by David Bélanger

What I would do is:

我会做的是:

  • Create a master DIV with a border (like here the border 1px solid #000)
  • After, inside this DIV, I will create another DIV (float: left;), another DIV (float: right) and an input inside the right div.
  • 创建一个带边框的主 DIV(就像这里的边框 1px solid #000)
  • 之后,在这个 DIV 中,我将创建另一个 DIV(浮动:左;),另一个 DIV(浮动:右)和右 div 内的输入。

When you write inside the input and let's say you select HTML, it creates a span in the left DIV and reduces the width of the right div to match the remaining size. Of course, inside your span there's the text HTML with the delete sign.

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

You could do it easily using jQuery.

您可以使用 jQuery 轻松完成。

Example:

例子:

<div id="master_div">
    <div id="categories">

    </div>
    <div id="input">
        <input type="text" value="" />
    </div>
</div>

And you write some jQuery / JS

然后你写了一些 jQuery / JS

回答by Jad Chahine

What about Bootstrap solution?

Bootstrap 解决方案怎么样?

You can try this :

你可以试试这个:

HTML Code:

HTML代码:

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

For CSS, call these two files:

对于 CSS,调用这两个文件:

<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">

For Javascript, call these two files:

对于 Javascript,调用这两个文件:

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

The code will generate the result below:

该代码将生成以下结果:

enter image description here

在此处输入图片说明

Check it out.

一探究竟。

回答by sachleen

It doesn't. If you look at the DOM, you see initially just an input box. Once you add a tag, it inserts a <span>tag before the input box with that tag and it's delete icon. The input box is now to the right of this <span>tag. When you click on a tag to edit it, it puts a textbox in its place so you can edit it. All this is done with Javascript and there are some JQuery plugins to help you do this. Here's one from a quick Google search: http://xoxco.com/projects/code/tagsinput/

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

As far as styling goes, the <span>elements can have whatever CSS you want on them.

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

回答by Максим

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();
    }
  }
}
*{
  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;
}
<div class="input-categories">
  <ul>
    <li>moscow</li>
    <li>new york</li>
  </ul>
  <input type="text"/>
</div>

<div class="input-categories">
  <ul>
    <li>CSS</li>
    <li>PHP</li>
  </ul>
  <input type="text"/>
</div>

回答by alvin lal

React functional component

反应功能组件

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

}

CSS:-

CSS:-

.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;
}

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="masterStackDiv">
              <div
                className="stackTags"
                style={{ display: tags.length > 0 ? "flex":"none"}} 
              >
                {tags.map((tag, index) => {
                  return (
                    <div className="stackTag" key={index}>
                      <button
                        onClick={() => removeTag(index)}
                        className="tagCloseBtn"
                      >
                        x
                      </button>
                      #{tag}
                    </div>
                  );
                })}
              </div>
              <div className="stackInput">
                <input
                  type="text"
                  onKeyDown={handleTag}
                  onChange={handleTag}
                  value={currentTagText}
                />
              </div>
            </div>
            )
       }
ReactDOM.render(<StackTag/>,document.getElementById("react"))
.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;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
</head>
<body>
<div id="react"></div>
</body>
</html>