jQuery HTML5 数据列表的事件,当项目被选择或输入与列表中的项目匹配时
jQuery event for HTML5 datalist when item is selected or typed input match with item in the list
我有如下数据列表 -
<input id="name" list="allNames" />
<datalist id="allNames">
<option value="Adnan1"/>
<option value="Faizan2"/>
</datalist>
我想要的是,当一个项目被完全输入时(例如当用户完全输入 "Adnan1" 时在输入框中说)或从列表中选择,那么我想要一个事件。我尝试了几种方法,但到目前为止都没有帮助。方法是 -
$("#name").change(function(){
console.log("change");
}
问题在于,只有当输入失去焦点时才会触发事件,即当我点击屏幕上的某处时。
我也试过了
$("#name").bind('change', function () {
console.log('changed');
});
但是每次输入时都会触发回调。实际上我需要在完全选择项目时进行 AJAX 调用。通过输入或从下拉列表中选择。
第一种方法对用户来说是不利的,因为他必须进行额外的点击,而第二种方法的缺点是每个字母都会触发一个事件。
我想要的只是一个用户做出选择或键入完整句子的事件。有没有办法做到这一点?任何我错过的事件都可以解决我的问题。
在 modern browsers 上,您可以使用 input
事件,例如:
$("#name").on('input', function () {
var val = this.value;
if($('#allNames option').filter(function(){
return this.value.toUpperCase() === val.toUpperCase();
}).length) {
//send ajax request
alert(this.value);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="name" list="allNames" />
<datalist id="allNames">
<option value="Adnan1" />
<option value="Faizan2" />
</datalist>
PS:由于 input
事件比 datalist 元素有更好的支持,如果您已经在使用 datalist
元素,确实没有理由不使用它。
您可以使用 input
事件来实现此类功能,如下所示:
$(document).ready(function() {
$('#name').on('input', function() {
var userText = $(this).val();
$("#allNames").find("option").each(function() {
if ($(this).val() == userText) {
alert("Make Ajax call here.");
}
})
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="name" list="allNames" />
<datalist id="allNames">
<option value="Adnan1" />
<option value="Faizan2" />
</datalist>
检查这是否适合您:
var dataList=[];
$("#allNames").find("option").each(function(){dataList.push($(this).val())})
console.log(dataList);
$("#name").on("keyup focus blur change",function(){
if(dataList.indexOf($(this).val())!=-1)
console.log("change");
})
我将数据列表选项推入数组,并在更改事件 keyup、blur 或 focus 时检查输入值是否存在于我的数据列表数组中。
简单的解决方案
document.getElementById('name').addEventListener('input', function () {
console.log('changed');
});
Hacky 是一种罪过,但对我有用。 (请注意,如果您输入 'Rum-Cola',它不会停在 'Rum' 选项上)
const opts = $("option").map(function(){return this.value;}).get();
$("#favourite-drink").on("keydown", function(e){
if(e.key){ // in case of mouse event e.key is 'undefined'
if (e.key === "Enter") { // looks like user wants to confirm the choice
if(opts.indexOf(this.value) >= 0){
this.blur();
console.log("Selected: " + this.value);
}
}
else {
this.setAttribute("data-keyboardinput", "true"); // remember that it's keyboard event
setTimeout(function(){ //and keep it in memory for 100ms
this.removeAttribute("data-keyboardinput")
}.bind(this), 100);
}
}
});
$("#favourite-drink").on("input", function(){
if(!this.dataset.keyboardinput && opts.indexOf(this.value) >= 0){ // if it's not a key press followed event
console.log("Selected: " + this.value);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Choose a drink:</p>
<input id="favourite-drink" list="drinks">
<datalist id="drinks">
<option value="Rum"></option>
<option value="Rum-Cola"></option>
<option value="Vodka"></option>
</datalist>
除了上面说的,我们还可以查看input的inputType,必须对应“insertReplacementText”
function textThatComesFromADatalist (event){
const inputType = event.inputType;
const isReplacingText = (typeof inputType === "undefined")
|| (inputType === "insertReplacementText");
return isReplacingText;
}
function onInput(event) {
if(textThatComesFromADatalist(event)){
alert('selected: '+event.target.value);
}
}
<input oninput="onInput(event)" list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice" />
<datalist id="ice-cream-flavors">
<option value="Chocolate">
<option value="Coconut">
<option value="Mint">
<option value="Strawberry">
<option value="Vanilla">
</datalist>
我有如下数据列表 -
<input id="name" list="allNames" />
<datalist id="allNames">
<option value="Adnan1"/>
<option value="Faizan2"/>
</datalist>
我想要的是,当一个项目被完全输入时(例如当用户完全输入 "Adnan1" 时在输入框中说)或从列表中选择,那么我想要一个事件。我尝试了几种方法,但到目前为止都没有帮助。方法是 -
$("#name").change(function(){
console.log("change");
}
问题在于,只有当输入失去焦点时才会触发事件,即当我点击屏幕上的某处时。
我也试过了
$("#name").bind('change', function () {
console.log('changed');
});
但是每次输入时都会触发回调。实际上我需要在完全选择项目时进行 AJAX 调用。通过输入或从下拉列表中选择。
第一种方法对用户来说是不利的,因为他必须进行额外的点击,而第二种方法的缺点是每个字母都会触发一个事件。
我想要的只是一个用户做出选择或键入完整句子的事件。有没有办法做到这一点?任何我错过的事件都可以解决我的问题。
在 modern browsers 上,您可以使用 input
事件,例如:
$("#name").on('input', function () {
var val = this.value;
if($('#allNames option').filter(function(){
return this.value.toUpperCase() === val.toUpperCase();
}).length) {
//send ajax request
alert(this.value);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="name" list="allNames" />
<datalist id="allNames">
<option value="Adnan1" />
<option value="Faizan2" />
</datalist>
PS:由于 input
事件比 datalist 元素有更好的支持,如果您已经在使用 datalist
元素,确实没有理由不使用它。
您可以使用 input
事件来实现此类功能,如下所示:
$(document).ready(function() {
$('#name').on('input', function() {
var userText = $(this).val();
$("#allNames").find("option").each(function() {
if ($(this).val() == userText) {
alert("Make Ajax call here.");
}
})
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="name" list="allNames" />
<datalist id="allNames">
<option value="Adnan1" />
<option value="Faizan2" />
</datalist>
检查这是否适合您:
var dataList=[];
$("#allNames").find("option").each(function(){dataList.push($(this).val())})
console.log(dataList);
$("#name").on("keyup focus blur change",function(){
if(dataList.indexOf($(this).val())!=-1)
console.log("change");
})
我将数据列表选项推入数组,并在更改事件 keyup、blur 或 focus 时检查输入值是否存在于我的数据列表数组中。
简单的解决方案
document.getElementById('name').addEventListener('input', function () {
console.log('changed');
});
Hacky 是一种罪过,但对我有用。 (请注意,如果您输入 'Rum-Cola',它不会停在 'Rum' 选项上)
const opts = $("option").map(function(){return this.value;}).get();
$("#favourite-drink").on("keydown", function(e){
if(e.key){ // in case of mouse event e.key is 'undefined'
if (e.key === "Enter") { // looks like user wants to confirm the choice
if(opts.indexOf(this.value) >= 0){
this.blur();
console.log("Selected: " + this.value);
}
}
else {
this.setAttribute("data-keyboardinput", "true"); // remember that it's keyboard event
setTimeout(function(){ //and keep it in memory for 100ms
this.removeAttribute("data-keyboardinput")
}.bind(this), 100);
}
}
});
$("#favourite-drink").on("input", function(){
if(!this.dataset.keyboardinput && opts.indexOf(this.value) >= 0){ // if it's not a key press followed event
console.log("Selected: " + this.value);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Choose a drink:</p>
<input id="favourite-drink" list="drinks">
<datalist id="drinks">
<option value="Rum"></option>
<option value="Rum-Cola"></option>
<option value="Vodka"></option>
</datalist>
除了上面说的,我们还可以查看input的inputType,必须对应“insertReplacementText”
function textThatComesFromADatalist (event){
const inputType = event.inputType;
const isReplacingText = (typeof inputType === "undefined")
|| (inputType === "insertReplacementText");
return isReplacingText;
}
function onInput(event) {
if(textThatComesFromADatalist(event)){
alert('selected: '+event.target.value);
}
}
<input oninput="onInput(event)" list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice" />
<datalist id="ice-cream-flavors">
<option value="Chocolate">
<option value="Coconut">
<option value="Mint">
<option value="Strawberry">
<option value="Vanilla">
</datalist>