如何让浏览器在设置默认值时显示所有数据列表选项?

问题描述 投票:0回答:11
html browser datalist
11个回答
10
投票

<datalist>
使用自动完成功能,因此这是正常行为。

例如,如果您将输入值设置为“o”,您将在数据列表选项中仅看到orange。它从第一个字母开始检查单词。但如果您将输入值设置为“a”,那么您根本不会看到选项。

因此,如果输入中已经有值,那么数据列表选项中将不会显示任何内容,除非该值存在。它的行为不像选择。

解决此问题的方法是使用 jquery,例如:

$('input').on('click', function() {
  $(this).val('');
});
$('input').on('mouseleave', function() {
  if ($(this).val() == '') {
    $(this).val('apple');
  }
});

完整测试在这里:https://jsfiddle.net/yw5wh4da/

或者您可以使用

<select>
。对我来说,在这种情况下这是更好的解决方案。


7
投票

我发现使用 click 和 mouseleave 事件并不理想,因为它们无法使用 键盘控件。

所以我想出了这个辅助函数:

更新:输入后触发
blur()
事件

正如 @Joe Platano 所评论的,我们可以通过在输入事件后触发

blur()
来改进数据列表行为(至少对于基于 chromium/blink 的浏览器)。

keepDatalistOptions('.keepDatalist');

function keepDatalistOptions(selector = '') {
  // select all input fields by datalist attribute or by class/id
  selector = !selector ? "input[list]" : selector;
  let datalistInputs = document.querySelectorAll(selector);
  if (datalistInputs.length) {
    for (let i = 0; i < datalistInputs.length; i++) {
      let input = datalistInputs[i];
      input.addEventListener("input", function(e) {
        e.target.setAttribute("placeholder", e.target.value);
        e.target.blur();
      });
      input.addEventListener("focus", function(e) {
        e.target.setAttribute("placeholder", e.target.value);
        e.target.value = "";
      });
      input.addEventListener("blur", function(e) {
        e.target.value = e.target.getAttribute("placeholder");
      });
    }
  }
}
<div style="display:flex; gap:1em;">
  <div>
    <h3>Keep datalist options</h3>
    <input class="keepDatalist" type="text" list="data" value="apple">
    <datalist id="data">
  <option value="apple">
  <option value="orange">
  <option value="banana">
</datalist>
  </div>
  <div>
    <h3>Default behavior</h3>
    <input type="text" list="browser" value="">
    <datalist id="browser">
  <option value="firefox">
  <option value="opera">
  <option value="safari">
</datalist>
  </div>
</div>

主要概念基本相同:

  1. 将当前输入值保存到占位符属性
  2. 重置焦点值以显示所有数据列表选项
  3. 将实际输入值与输入上的占位符交换

此函数还会更新输入事件的当前值 - 否则在通过 Tab 键导航到下一个输入后您将丢失当前值。

为什么你不应该搞乱表单元素的默认行为

例如,Firefox 不会接受这种黑客攻击 - 可能有充分的理由。

处理表单时,您的首要任务始终应该是:

  • 可靠性:
    即使在不太现代的浏览器中也可以成功提交表单数据
  • 辅助功能:
    自定义黑客也适用于使用屏幕阅读器(如 NVDA 或 JAWS)的视障人士 因此,如果您的自定义表单元素行为提供了可靠且可预测的用户体验,您应该始终“三重/四重检查”。

HTML:

6
投票
<input list="values" placeholder="select"> <datalist id="values"> <option value="orange"> <option value="banana"> <option value="lemon"> <option value="apple"> </datalist>

JS:

$('input').on('click', function() { $(this).attr('placeholder',$(this).val()); $(this).val(''); }); $('input').on('mouseleave', function() { if ($(this).val() == '') { $(this).val($(this).attr('placeholder')); } });

上面的解决方案很棒,但是如果用户自然地只是单击输入框中占位符值旁边的按钮,打算保留并继续它,那么它将被完全擦除。

2
投票
因此,基于上述解决方案,我为我做了以下解决方案:

HTML:

<input id="other" list="values" value="<?php echo $val; ?>"> <datalist id="values"> <option value="orange"> <option value="banana"> </datalist>

JS:

jQuery(document).ready(function ($) { function putValueBackFromPlaceholder() { var $this = $('#other'); if ($this.val() === '') { $this.val($this.attr('placeholder')); $this.attr('placeholder',''); } } $('#other') .on('click', function(e) { var $this = $(this); var inpLeft = $this.offset().left; var inpWidth = $this.width(); var clickedLeft = e.clientX; var clickedInInpLeft = clickedLeft - inpLeft; var arrowBtnWidth = 12; if ((inpWidth - clickedInInpLeft) < arrowBtnWidth ) { $this.attr('placeholder',$this.val()); $this.val(''); } else { putValueBackFromPlaceholder(); } }) .on('mouseleave', putValueBackFromPlaceholder); });

对于我来说,页面上有很多输入框,我只希望这个输入框具有这种行为,所以我使用 id 并将其设置为“个人”。如果您希望将其更改为更通用的函数,则必须将
putValueBackFromPlaceholder
与发生单击的元素以及事件本身绑定。


基于建议的解决方案的另一种选项,保留先前的值或选择的新值。

1
投票
// Global variable to store current value var oldValue = ''; // Blank value when click to activate all options $('input').on('click', function() { oldValue = $(this).val(); $(this).val(''); }); // Restore current value after click $('input').on('mouseleave', function() { if ($(this).val() == '') { $(this).val(oldValue); } });

https://jsfiddle.net/jpussacq/7Ldbc013/

最干净的选项可能是

0
投票
推荐的选项。

input.onfocus = function () { datalist.style.display = 'block'; } input.onblur = function () { datalist.style.display = 'none'; } for (let option of datalist.options) { option.onclick = function () { input.value = this.value; datalist.style.display = 'none'; } } datalist.style.width = input.offsetWidth + 'px'; datalist.style.left = input.offsetLeft + 'px'; datalist.style.top = input.offsetTop + input.offsetHeight + 'px';
datalist { position: absolute; background-color: lightgrey; font-family: sans-serif; font-size: 0.8rem; } option { background-color: #bbb; padding: 4px; margin-bottom: 1px; cursor: pointer; }
<input
  list=""
  name="option"
  id="input"
  autocomplete="off"
>

<datalist id="datalist">
  <option>Carrots</option>
  <option>Peas</option>
  <option>Beans</option>
</datalist>


0
投票

function InputDropList_Focus(elementID) {//input must have value and valuetemp attributes const el=document.getElementById(elementID); el.setAttribute("valuetemp", el.value); el.value=""; } function InputDropList_FocusOut(elementID) { const el=document.getElementById(elementID); if(el.value !== el.getAttribute("valuetemp")) el.value=el.getAttribute("valuetemp"); } function InputDropList_OnChange(elementID, action) { const el=document.getElementById(elementID); el.setAttribute("valuetemp", el.value); el.blur(); if(action != null) action(); } function DoSmthOnChange(elementID) { const el=document.getElementById(elementID); console.log("new value: " + el.value); }
<input id="mylist" list="mylistOptions" value="apple" valuetemp="apple" onfocus="InputDropList_Focus('mylist')" onfocusout="InputDropList_FocusOut('mylist')" onchange="InputDropList_OnChange('mylist', DoSmthOnChange('mylist'))" > <datalist id="mylistOptions"> <option value="apple"> <option value="orange"> <option value="banana"> </datalist>

我在动态填充

0
投票
时遇到了这个问题。仅显示一个

<option>

。我的用例是输入
type=search
,就像搜索引擎输入一样。
技巧是将输入的 
.value

设置为

单个不间断行空格

,或  ,或简单地“”。 (不是“”。必须有一个空格“”)。
因此,在动态 .append

选项之后,

myDatalist.value = " ";

。现在将显示所有选项。

我尝试了很多东西,终于找到了这个。希望开发者喜欢这样。

0
投票

<input id="mylist" list="mylistOptions" value="" onfocus="this.value=null;" onchange="this.blur();" > <datalist id="mylistOptions"> <option value="apple"> <option value="orange"> <option value="banana"> </datalist>

这是


-7
投票
<input list="skills" value="DBA"> <datalist name="skills" id="skills"> <option value="PHP">Zend PHP</option> <option value="DBA">ORACLE DBA</option> <option value="APEX">APEX 5.1</option> <option value="ANGULAR">ANGULAR JS</option> </datalist>


© www.soinside.com 2019 - 2024. All rights reserved.