如何为“选择”框创建占位符?

我正在使用占位符进行文本输入,效果很好。但是我也想为我的选择框使用一个占位符。当然,我可以使用以下代码:

<select>
    <option value="">Select your option</option>
    <option value="hurr">Durr</option>
</select>

但是“选择您的选项”是黑色而不是浅灰色。因此,我的解决方案可能基于CSS。jQuery也很好。

这只会使下拉菜单中的选项变为灰色(因此,单击箭头后):

option:first {
    color: #999;
}

问题是:人们如何在选择框中创建占位符?但它已经得到回答,欢呼。

使用此方法会导致所选值始终为灰色(即使在选择实选项后):

select {
    color: #999;
}
猴子神乐2020/03/13 17:26:43

Angular 2解决方案

在选择的顶部创建标签

<label class="hidden-label" for="IsActive"
    *ngIf="filterIsActive == undefined">Placeholder text</label>
<select class="form-control form-control-sm" type="text" name="filterIsActive"
    [(ngModel)]="filterIsActive" id="IsActive">
    <option value="true">true</option>
    <option value="false">false</option>
</select>

并应用CSS将其放在顶部

.hidden-label {
    position: absolute;
    margin-top: .34rem;
    margin-left: .56rem;
    font-style: italic;
    pointer-events: none;
}

pointer-events: none 允许您在单击标签时显示选择,在选择选项时该标签将隐藏。

MandyEva2020/03/13 17:26:43

尝试以下更改:

$("select").css("color", "#757575");
$(document).on("change", "select", function(){
    if ($(this).val() != "") {
        $(this).css("color", "");
    } 
    else {
        $(this).css("color", "#757575");
    }
});
达蒙Itachi理查德2020/03/13 17:26:43

您可以不Javascript使用仅使用的方式进行此操作。HTML您需要设置默认的选择选项 disabled=""selected=""并选择标签required="".浏览器不允许用户在不选择任何选项的情况下提交表单。

<form action="" method="POST">
    <select name="in-op" required="">
        <option disabled="" selected="">Select Option</option>
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
    </select>
    <input type="submit" value="Submit">
</form>
YOC456920462020/03/13 17:26:42

我希望SELECT在选择之前为灰色,因此对于这段HTML:

<select>
  <option value="" disabled selected>Select your option</option>
  <option value="hurr">Durr</option>
</select>

我添加了以下CSS定义:

select { color: grey; }
select:valid { color: black; }

它可以在Chrome / Safari和其他浏览器中按预期工作,但我尚未检查。

小哥梅Stafan2020/03/13 17:26:42

我对仅HTML / CSS的解决方案不满意,因此我决定select使用JavaScript 创建自定义

这是我在过去30分钟内写的,因此可以进一步改进。

您所要做的就是创建一个包含少量数据属性的简单列表。该代码自动将列表变成可选的下拉列表。它还添加了一个隐藏项input来保存选定的值,因此可以在表单中使用它。

输入:

<ul class="select" data-placeholder="Role" data-name="role">
  <li data-value="admin">Administrator</li>
  <li data-value="mod">Moderator</li>
  <li data-value="user">User</li>
</ul>

输出:

<div class="ul-select-container">
    <input type="hidden" name="role" class="hidden">
    <div class="selected placeholder">
        <span class="text">Role</span>
        <span class="icon">▼</span>
    </div>
    <ul class="select" data-placeholder="Role" data-name="role">
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li data-value="user">User</li>
    </ul>
</div>

本应为占位符的项目文本显示为灰色。如果用户想要还原他/她的选择,则可以选择占位符。同样使用CSS,select可以克服的所有缺点(例如,选项样式无法设置)。

// Helper function to create elements faster/easier
// https://github.com/akinuri/js-lib/blob/master/element.js
var elem = function(tagName, attributes, children, isHTML) {
  let parent;
  if (typeof tagName == "string") {
    parent = document.createElement(tagName);
  } else if (tagName instanceof HTMLElement) {
    parent = tagName;
  }
  if (attributes) {
    for (let attribute in attributes) {
      parent.setAttribute(attribute, attributes[attribute]);
    }
  }
  var isHTML = isHTML || null;
  if (children || children == 0) {
    elem.append(parent, children, isHTML);
  }
  return parent;
};
elem.append = function(parent, children, isHTML) {
  if (parent instanceof HTMLTextAreaElement || parent instanceof HTMLInputElement) {
    if (children instanceof Text || typeof children == "string" || typeof children == "number") {
      parent.value = children;
    } else if (children instanceof Array) {
      children.forEach(function(child) {
        elem.append(parent, child);
      });
    } else if (typeof children == "function") {
      elem.append(parent, children());
    }
  } else {
    if (children instanceof HTMLElement || children instanceof Text) {
      parent.appendChild(children);
    } else if (typeof children == "string" || typeof children == "number") {
      if (isHTML) {
        parent.innerHTML += children;
      } else {
        parent.appendChild(document.createTextNode(children));
      }
    } else if (children instanceof Array) {
      children.forEach(function(child) {
        elem.append(parent, child);
      });
    } else if (typeof children == "function") {
      elem.append(parent, children());
    }
  }
};


// Initialize all selects on the page
$("ul.select").each(function() {
  var parent    = this.parentElement;
  var refElem   = this.nextElementSibling;
  var container = elem("div", {"class": "ul-select-container"});
  var hidden    = elem("input", {"type": "hidden", "name": this.dataset.name, "class": "hidden"});
  var selected  = elem("div", {"class": "selected placeholder"}, [
    elem("span", {"class": "text"}, this.dataset.placeholder),
    elem("span", {"class": "icon"}, "&#9660;", true),
  ]);
  var placeholder = elem("li", {"class": "placeholder"}, this.dataset.placeholder);
  this.insertBefore(placeholder, this.children[0]);
  container.appendChild(hidden);
  container.appendChild(selected);
  container.appendChild(this);
  parent.insertBefore(container, refElem);
});

// Update necessary elements with the selected option
$(".ul-select-container ul li").on("click", function() {
  var text     = this.innerText;
  var value    = this.dataset.value || "";
  var selected = this.parentElement.previousElementSibling;
  var hidden   = selected.previousElementSibling;
  hidden.value = selected.dataset.value = value;
  selected.children[0].innerText = text;
  if (this.classList.contains("placeholder")) {
    selected.classList.add("placeholder");
  } else {
    selected.classList.remove("placeholder");
  }
  selected.parentElement.classList.remove("visible");
});

// Open select dropdown
$(".ul-select-container .selected").on("click", function() {
  if (this.parentElement.classList.contains("visible")) {
    this.parentElement.classList.remove("visible");
  } else {
    this.parentElement.classList.add("visible");
  }
});

// Close select when focus is lost
$(document).on("click", function(e) {
  var container = $(e.target).closest(".ul-select-container");
  if (container.length == 0) {
    $(".ul-select-container.visible").removeClass("visible");
  }
});
.ul-select-container {
  width: 200px;
  display: table;
  position: relative;
  margin: 1em 0;
}
.ul-select-container.visible ul {
  display: block;
  padding: 0;
  list-style: none;
  margin: 0;
}
.ul-select-container ul {
  background-color: white;
  border: 1px solid hsla(0, 0%, 60%);
  border-top: none;
  -webkit-user-select: none;
  display: none;
  position: absolute;
  width: 100%;
  z-index: 999;
}
.ul-select-container ul li {
  padding: 2px 5px;
}
.ul-select-container ul li.placeholder {
  opacity: 0.5;
}
.ul-select-container ul li:hover {
  background-color: dodgerblue;
  color: white;
}
.ul-select-container ul li.placeholder:hover {
  background-color: rgba(0, 0, 0, .1);
  color: initial;
}
.ul-select-container .selected {
  background-color: white;
  padding: 3px 10px 4px;
  padding: 2px 5px;
  border: 1px solid hsla(0, 0%, 60%);
  -webkit-user-select: none;
}
.ul-select-container .selected {
  display: flex;
  justify-content: space-between;
}
.ul-select-container .selected.placeholder .text {
  color: rgba(0, 0, 0, .5);
}
.ul-select-container .selected .icon {
  font-size: .7em;
  display: flex;
  align-items: center;
  opacity: 0.8;
}
.ul-select-container:hover .selected {
  border: 1px solid hsla(0, 0%, 30%);
}
.ul-select-container:hover .selected .icon {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul class="select" data-placeholder="Role" data-name="role">
  <li data-value="admin">Administrator</li>
  <li data-value="mod">Moderator</li>
  <li data-value="user">User</li>
</ul>

<ul class="select" data-placeholder="Sex" data-name="sex">
  <li data-value="male">Male</li>
  <li data-value="female">Female</li>
</ul>


更新:我已经对此进行了改进(使用向上/向下/输入键进行选择),对输出进行了一些整理,并将其变成了对象。电流输出:

<div class="li-select-container">
    <input type="text" readonly="" placeholder="Role" title="Role">
    <span class="arrow">▼</span>
    <ul class="select">
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li data-value="user">User</li>
    </ul>
</div>

初始化:

new Liselect(document.getElementsByTagName("ul")[0]);

进一步检查: JSFiddleGitHub(重命名)。


更新:我已经再次重写了这个。除了使用列表,我们还可以使用选择。这样即使没有JavaScript,它也可以正常工作(以防被禁用)。

输入:

<select name="role" data-placeholder="Role" required title="Role">
    <option value="admin">Administrator</option>
    <option value="mod">Moderator</option>
    <option>User</option>
</select>

new Advancelect(document.getElementsByTagName("select")[0]);

输出:

<div class="advanced-select">
    <input type="text" readonly="" placeholder="Role" title="Role" required="" name="role">
    <span class="arrow">▼</span>
    <ul>
        <li class="placeholder">Role</li>
        <li data-value="admin">Administrator</li>
        <li data-value="mod">Moderator</li>
        <li>User</li>
    </ul>
</div>

JSFiddleGitHub

蛋蛋Itachi2020/03/13 17:26:42

我喜欢公认的解决方案,并且在没有JavaScript的情况下效果很好。

我只想补充一下我如何对受控选择的React Component采纳这个答案,因为这花了我一些努力才能弄清楚。合并react-select并完成它确实很简单,但是除非您需要此存储库提供的惊人功能(我不打算使用该项目),否则无需在软件包中添加更多千字节。注意,react-select通过对各种复杂的系统处理中选择的占位符inputshtml元件。

在React中,对于受控组件,您不能将selected属性添加到选项中。React通过自身value属性select以及更改处理程序来处理选择的状态,其中值应与选项本身内的值属性之一匹配。

例如

<select value={this.state.selectValue} onChange={this.handleChange} required={true}>
    {options}
</select>

由于这将是不适当的,并且实际上会引发将selected属性添加到选项之一的错误,那么该怎么办?

一旦您想到它,答案就很简单。由于我们希望我们的第一个条件optionand selected一样好,因此我们需要做三件事:disabledhidden

  1. hiddenand disabled属性添加到第一个定义的中option
  2. 将第一个的值设置为option空字符串。
  3. 将的值初始化select为也是一个空字符串。
state = { selectValue = "" } // State or props or their equivalent

// In the render function
<select value={this.state.selectValue} onChange={this.handleChange} required={true}>
    <option key="someKey" value="" disabled="disabled" hidden="hidden">Select from Below</option>
    {renderOptions()}
</select>

现在,您可以按照上面的指示(或根据需要通过a className设置选择的样式

select:invalid { color: gray; }
小胖TonyLEY2020/03/13 17:26:42

如果您使用的是Angular,请按照以下步骤操作:

<select>
    <option [ngValue]="undefined"  disabled selected>Select your option</option>
    <option [ngValue]="hurr">Durr</option>
</select>

西门樱Eva2020/03/13 17:26:42

HTML + CSS解决方案为我工作:

form select:invalid {
  color: gray;
}

form select option:first-child {
  color: gray;
}

form select:invalid option:not(:first-child) {
  color: black;
}
<form>
  <select required>
    <option value="">Select Planet...</option>
    <option value="earth">Earth</option>
    <option value="pandora">Pandora</option>
  </select>
</form>

祝好运...

西里Davaid2020/03/13 17:26:42

用户不应在选择选项中看到占位符。我建议使用hidden占位符选项属性,而您不需要selected此选项属性。您可以将其放在第一位。

select:not(:valid) {
  color: #999;
}
<select required>
    <option value="" hidden>Select your option</option>
    <option value="0">First option</option>
    <option value="1">Second option</option>
</select>

小哥TonyEva2020/03/13 17:26:42

这是我的:

select:focus option.holder {
  display: none;
}
<select>
    <option selected="selected" class="holder">Please select</option>
    <option value="1">Option #1</option>
    <option value="2">Option #2</option>

</select>

Sam逆天2020/03/13 17:26:42

在这里,我修改了大卫的答案(可接受的答案)。关于他的回答,他在option标签上放置了disable和selected属性,但是当我们还隐藏标签时,它将看起来更好。

通过在option标签上添加额外的隐藏属性,可以防止在选择“ Durr”选项后重新选择“ Select your option”选项。

<select>
    <option value="" disabled selected hidden>Select your option</option>
    <option value="hurr">Durr</option>
</select>

伽罗理查德2020/03/13 17:26:42

我遇到了同样的问题,在搜索时遇到了这个问题,在找到适合我的解决方案之后,我想与大家分享一下,以防有人可以从中受益。

这里是:

HTML:

<select class="place_holder dropdown">
    <option selected="selected" style=" display: none;">Sort by</option>
    <option>two</option>
    <option>something</option>
    <option>4</option>
    <option>5</option>
</select>

CSS:

.place_holder {
    color: gray;
}
option {
    color: #000000;
}

JavaScript:

jQuery(".dropdown").change(function () {
    jQuery(this).removeClass("place_holder");
});

在客户做出第一选择之后,就不需要灰色了,因此JavaScript代码删除了class place_holder

感谢@ user1096901,作为Internet Explorer浏览器的解决方法,您可以在place_holder再次选择第一个选项的情况下再次添加类:)

2020/03/13 17:26:42

我看到了正确答案的迹象,但是综合考虑,这将是我的解决方案:

select {
  color: grey;
}

option {
  color: black;
}

option[default] {
   display: none;
}
<select>
    <option value="" default selected>Select your option</option>
    <option value="hurr">Durr</option>
</select>

Itachi达蒙Green2020/03/13 17:26:42

下面的解决方案也可以在Firefox中运行,无需任何JavaScript:

option[default] {
  display: none;
}
<select>
  <option value="" default selected>Select Your Age</option>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select>

Itachi达蒙Green2020/03/13 17:26:42

像这样:

HTML:

<select id="choice">
    <option value="0" selected="selected">Choose...</option>
    <option value="1">Something</option>
    <option value="2">Something else</option>
    <option value="3">Another choice</option>
</select>

CSS:

#choice option { color: black; }
.empty { color: gray; }

JavaScript:

$("#choice").change(function () {
    if($(this).val() == "0") $(this).addClass("empty");
    else $(this).removeClass("empty")
});

$("#choice").change();

工作示例:http : //jsfiddle.net/Zmf6t/

猿伽罗2020/03/13 17:26:42

我只是在option下面类似图中添加了一个隐藏属性对我来说很好。

<select>
  <option hidden>Sex</option>
  <option>Male</option>
  <option>Female</option>
</select>

Davaid番长十三2020/03/13 17:26:42

对于必填字段,现代浏览器中有一个纯CSS解决方案:

select:required:invalid {
  color: gray;
}
option[value=""][disabled] {
  display: none;
}
option {
  color: black;
}
<select required>
  <option value="" disabled selected>Select something...</option>
  <option value="1">One</option>
  <option value="2">Two</option>
</select>

JinJinTom2020/03/13 17:26:42

非CSS-没有JavaScript / jQuery答案:

<select>
    <option value="" disabled selected>Select your option</option>
    <option value="hurr">Durr</option>
</select>