在 Firefox 中延迟加载输入数据列表
Deferred loading of input datalist in Firefox
我想为用户名创建一个输入字段,应该可以从大量名称/用户名中进行选择。应该可以输入名称或用户名中包含的部分字符串。我不想最初加载列表,而是在用户输入最少数量的字符(例如 3)之后加载列表,因为列表最终非常大,应该通过最初的 3 个字符缩减为一个子集。
如果在 Chrome 或 Chromium 中将 <input>
与 <datalist>
一起使用,这将完美运行,但在 Firefox 中无法正常运行。我还没有测试过其他浏览器。
预期的行为(以及它在 Chromium 中的工作方式)是我输入我的字符,在第三个字符之后,下拉自动建议列表被加载并自动显示。如果我继续键入,列表将继续被过滤。此外,我可以使用 escape 使列表消失,并使用向下箭头或向上箭头重新出现。
在 Firefox 中,列表不会自动出现。我必须输入另一个字符,然后退格。另外,我不能让它出现向下箭头或向上箭头。 (虽然该解决方案在 Firefox 中确实有效,如果列表是最初创建的并且不是延迟加载的,但这不是如上所述的选项)。
我想找到一种使建议列表自动打开(或在按键时)或以不同方式解决此问题(没有 datalist
)的方法。
要求
- 尽可能少地使用外部库。我目前使用jquery,如果它是jquery解决方案就可以了,但是纯JavaScript会更可取。
- 在所有浏览器中自动下拉建议列表(列表加载后)将是理想的。但至少有可能通过按键或按钮下拉列表。
例子
最初填充的数据列表
- 这也适用于 Firefox。
- 只要您键入列表中包含的一个字符(例如“1”、'o'、“12”等),列表就会立即出现
<input class="my-input-class" placeholder="Enter '123' ... or 'one' ... " list="myDatalist" size="100">
<datalist id="myDatalist">
<option value="1">one</option>
<option value="12">one two</option>
<option value="123">one two three</option>
<option value="1234">one two three four</option>
<option value="12345">one two three four five</option>
<option value="123456">one two three four five six</option>
</datalist>
延迟填充的数据列表
- 不适用于 Firefox
- 只要您键入列表中包含的至少三个字符(例如“123”或 'one'),列表就会立即出现
var previous = null;
function delayedCallback(callback, ms) {
var timer = 0;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(context, args);
}, ms || 0);
};
}
function generateSelectList(inputElement) {
var value = inputElement.val();
var optionList = {
'123': 'one two three',
'1234': 'one two three four',
'12345': 'one two three four five',
'123456': 'one two three four five six',
'1234567': 'one two three four five six seven',
}
$('#myDatalist').remove();
dl = document.createElement('datalist');
inputElement.attr('list', 'myDatalist');
dl.id = 'myDatalist';
for (var key in optionList) {
var option = document.createElement('option');
option.value = key;
option.append(optionList[key]);
dl.append(option);
}
inputElement.append(dl);
}
$(document).on('input', '.my-input-class', delayedCallback(function(event) {
var inputElement = $(event.target);
var value = inputElement.val();
// only get result list if
// - minimum 3 chars
// - same result list has not already been fetched (if string starts with previous string)
if (value.length >= 3) {
if (previous && value.startsWith(previous) && $('#myDatalist').length) {
console.log("DO NOT fetch list (again) value=" + value + " previous=" + previous);
} else {
console.log("fetch list: value=" + value);
generateSelectList(inputElement);
previous = value;
}
}
}, 500));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="my-input-class" placeholder="Enter '123' ... or 'one' ... (at least 3 characters)" list="myDatalist" size="100">
我搜索了一些解决方案,或者其他人是否遇到了同样的问题。我确实发现了一些关于 datalist
未按预期工作或在不同浏览器中工作不相同的投诉,以及使用某些 jquery 库的建议。虽然我可以只使用建议的解决方案之一,但我不确定它们是否能解决我的问题,或者是否有办法使 datalist
和其他浏览器(Chrome 除外)也能正常工作。
根据 canIuse,Firefox 中存在一个错误,需要将自动完成设置为关闭,数据列表才能正常工作。也许这会有所帮助?
我想为用户名创建一个输入字段,应该可以从大量名称/用户名中进行选择。应该可以输入名称或用户名中包含的部分字符串。我不想最初加载列表,而是在用户输入最少数量的字符(例如 3)之后加载列表,因为列表最终非常大,应该通过最初的 3 个字符缩减为一个子集。
如果在 Chrome 或 Chromium 中将 <input>
与 <datalist>
一起使用,这将完美运行,但在 Firefox 中无法正常运行。我还没有测试过其他浏览器。
预期的行为(以及它在 Chromium 中的工作方式)是我输入我的字符,在第三个字符之后,下拉自动建议列表被加载并自动显示。如果我继续键入,列表将继续被过滤。此外,我可以使用 escape 使列表消失,并使用向下箭头或向上箭头重新出现。
在 Firefox 中,列表不会自动出现。我必须输入另一个字符,然后退格。另外,我不能让它出现向下箭头或向上箭头。 (虽然该解决方案在 Firefox 中确实有效,如果列表是最初创建的并且不是延迟加载的,但这不是如上所述的选项)。
我想找到一种使建议列表自动打开(或在按键时)或以不同方式解决此问题(没有 datalist
)的方法。
要求
- 尽可能少地使用外部库。我目前使用jquery,如果它是jquery解决方案就可以了,但是纯JavaScript会更可取。
- 在所有浏览器中自动下拉建议列表(列表加载后)将是理想的。但至少有可能通过按键或按钮下拉列表。
例子
最初填充的数据列表
- 这也适用于 Firefox。
- 只要您键入列表中包含的一个字符(例如“1”、'o'、“12”等),列表就会立即出现
<input class="my-input-class" placeholder="Enter '123' ... or 'one' ... " list="myDatalist" size="100">
<datalist id="myDatalist">
<option value="1">one</option>
<option value="12">one two</option>
<option value="123">one two three</option>
<option value="1234">one two three four</option>
<option value="12345">one two three four five</option>
<option value="123456">one two three four five six</option>
</datalist>
延迟填充的数据列表
- 不适用于 Firefox
- 只要您键入列表中包含的至少三个字符(例如“123”或 'one'),列表就会立即出现
var previous = null;
function delayedCallback(callback, ms) {
var timer = 0;
return function() {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
callback.apply(context, args);
}, ms || 0);
};
}
function generateSelectList(inputElement) {
var value = inputElement.val();
var optionList = {
'123': 'one two three',
'1234': 'one two three four',
'12345': 'one two three four five',
'123456': 'one two three four five six',
'1234567': 'one two three four five six seven',
}
$('#myDatalist').remove();
dl = document.createElement('datalist');
inputElement.attr('list', 'myDatalist');
dl.id = 'myDatalist';
for (var key in optionList) {
var option = document.createElement('option');
option.value = key;
option.append(optionList[key]);
dl.append(option);
}
inputElement.append(dl);
}
$(document).on('input', '.my-input-class', delayedCallback(function(event) {
var inputElement = $(event.target);
var value = inputElement.val();
// only get result list if
// - minimum 3 chars
// - same result list has not already been fetched (if string starts with previous string)
if (value.length >= 3) {
if (previous && value.startsWith(previous) && $('#myDatalist').length) {
console.log("DO NOT fetch list (again) value=" + value + " previous=" + previous);
} else {
console.log("fetch list: value=" + value);
generateSelectList(inputElement);
previous = value;
}
}
}, 500));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="my-input-class" placeholder="Enter '123' ... or 'one' ... (at least 3 characters)" list="myDatalist" size="100">
我搜索了一些解决方案,或者其他人是否遇到了同样的问题。我确实发现了一些关于 datalist
未按预期工作或在不同浏览器中工作不相同的投诉,以及使用某些 jquery 库的建议。虽然我可以只使用建议的解决方案之一,但我不确定它们是否能解决我的问题,或者是否有办法使 datalist
和其他浏览器(Chrome 除外)也能正常工作。
根据 canIuse,Firefox 中存在一个错误,需要将自动完成设置为关闭,数据列表才能正常工作。也许这会有所帮助?