<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>
。对我来说,在这种情况下这是更好的解决方案。
我发现使用 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>
主要概念基本相同:
此函数还会更新输入事件的当前值 - 否则在通过 Tab 键导航到下一个输入后您将丢失当前值。
例如,Firefox 不会接受这种黑客攻击 - 可能有充分的理由。
处理表单时,您的首要任务始终应该是:
HTML:
<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'));
}
});
上面的解决方案很棒,但是如果用户自然地只是单击输入框中占位符值旁边的按钮,打算保留并继续它,那么它将被完全擦除。
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
与发生单击的元素以及事件本身绑定。基于建议的解决方案的另一种选项,保留先前的值或选择的新值。
// 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/最干净的选项可能是
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>
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>
我在动态填充
<option>
。我的用例是输入
type=search
,就像搜索引擎输入一样。
技巧是将输入的
.value
设置为 单个不间断行空格
,或 ,或简单地“”。 (不是“”。必须有一个空格“”)。因此,在动态
.append
选项之后,myDatalist.value = " ";
。现在将显示所有选项。我尝试了很多东西,终于找到了这个。希望开发者喜欢这样。
<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>
这是
<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>