Я подготовил следующий код для прямого поиска. В фокусе ввода отображается список доступных параметров. При размытии ввода параметры исчезают. Там лежит моя проблема. Когда вы нажимаете на элемент формы списка, вход теряет фокус, и список исчезает до того, как произойдет событие клика.Пользовательский datalist - опции исчезают перед выбором
var artists = [{"artist":"3 Doors Down"},{"artist":"5 Seconds of Summer"},{"artist":"Adele"},{"artist":"Alicia Keys"},{"artist":"Amanda Abizaid"}];
function liveSearch(element) {
return new liveSearch.prototype.init(element);
}
liveSearch.prototype = {
init : function(element) {
if (!element) {
this.element = document.createElement("ul");
this.element.classList.add("liveSearch");
} else {
this.element = element;
}
},
update : function(queryElement) {
this.clear();
var lookUpArray = queryElement.name + "s";
var results = this.search(artists, queryElement.value, queryElement.name);
for (var i = 0; i < results.length; i++) {
var li = document.createElement("li");
var value = results[i];
if (queryElement.value != "") {
var re = new RegExp(queryElement.value, "gi");
value = value.replace(re, "<span class=\"highlight\">" + "$&" + "</span>");
}
li.innerHTML = value;
this.element.appendChild(li);
}
return results.length;
},
search : function(lookUpArray, string) {
var results = [];
for (var i = 0; i < lookUpArray.length; i++) {
if (lookUpArray[i].artist.toLowerCase().search(string.toLowerCase()) != -1) {
results.push(lookUpArray[i].artist);
}
}
return results;
},
clear : function() {
this.element.innerHTML = "";
},
hidden : function() {
this.element.style.display = "none";
},
visible : function() {
this.element.style.display = "";
},
remove : function() {
this.element.parentElement.removeChild(this.element);
},
};
liveSearch.prototype.init.prototype = liveSearch.prototype;
$("#lyrics-form").on("focus", "input.liveSearch-input", function() {
this.parentElement.appendChild(liveSearch().element);
if (liveSearch(this.nextElementSibling).update(this)) {
liveSearch(this.nextElementSibling).visible();
} else {
liveSearch(this.nextElementSibling).hidden();
}
});
$("#lyrics-form").on("blur", "input.liveSearch-input", function() {
liveSearch(this.nextElementSibling).remove();
});
$("#lyrics-form").on("keyup", "input.liveSearch-input", function() {
if (this.value != "") {
if (liveSearch(this.nextElementSibling).update(this)) {
liveSearch(this.nextElementSibling).visible();
} else {
liveSearch(this.nextElementSibling).hidden();
}
} else {
liveSearch(this.nextElementSibling).update(this);
}
});
$("#lyrics-form").on("click", "li", function() {
this.parentElement.previousElementSibling.value = this.innerText;
liveSearch(this.parentElement).hidden();
});
input, ul {
width: 180px;
box-sizing: border-box;
}
.liveSearch {
margin: 0;
border: 1px solid silver;
box-shadow: 0 2px 5px rgba(0,0,0,.5);
position: absolute;
background: white;
padding: 5px;
max-height: 195px;
width: 180px;
overflow-y: scroll;
z-index: 1000;
}
.liveSearch li {
padding: 2px 5px;
cursor: default;
}
.liveSearch li:hover {
background: rgba(0,0,0,.05);
color: black;
}
.liveSearch .highlight {
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="addlyrics.php" id="lyrics-form" method="post" autocomplete="off" enctype="multipart/form-data">
\t <input type="text" name="artist" id="artist" class="liveSearch-input" placeholder="Artist" required />
</form>
Я использовал тайм-аут на смазывание, чтобы обойти эту проблему, но это не достаточно хорошо. Это непротиворечиво, и более высокие задержки делают дизайн уродливым. Как я могу это исправить?
$("#lyrics-form").on("blur", "input.liveSearch-input", function() {
/* liveSearch(this.nextElementSibling).remove(); */
setTimeout(function() {
liveSearch(this.nextElementSibling).remove();
}.bind(this), 100);
});
Весь список исчезает после выбора пункта. Я обнаружил, что это происходит каждый раз, когда я пытаюсь использовать datalist (Chrome Version 63.0.3239.84 (Official Build) (64-разрядная версия)) –
@Rid Я не думаю, что это ошибка, потому что при вводе в поле это фильтрует элементы списка и возвращает согласованные элементы. Если вы нажмете на поле после выбора, он будет обрабатывать его, поскольку вы набрали что-то, и он вернул соответствующие элементы. – akinuri
вы, вероятно, правы, но я нахожу этот счетчик интуитивным, и я точно знаю, что не могу представить его так, как это для нашей пользовательской базы. –