- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 JavaScript 应用程序,用户可以在其中搜索 map 上的地点。输入文本提供自动完成建议:当用户键入时,一些建议会出现在文本输入本身的底部。
我正在使用第三方 JavaScript 自动完成库,该库按用户请求收费。不幸的是,每次击键都算作一次请求,因为当从输入元素接收到 onInput
回调时,库没有实现任何去抖动。因此,这些建议看起来很活泼,但却以许多用户请求为代价。
我想做的是重新定义输入元素内的输入回调以实现去抖动(假设为 500 毫秒)。
由于第三方库接受 JavaScript 元素本身,我无法使用外部去抖动机制:(可能库检测到输入元素本身发送的 onInput
消息)
var placesAutocomplete = places({
appId: 'xxxxxxxxxxx',
apiKey: 'kkkkkkkkkk',
container: document.querySelector('#inputelement'), // <- the library accepts the element itself, not an "on input" listener (which could be easily debounced by an external function)
language: G_lang
});
placesAutocomplete.on('change', function(res){
// user leaves the input text, set lat lon on my map (code not shown here on SO)
var lat = res.suggestion.latlng.lat;
var lon = res.suggestion.latlng.lng;
finish(lat, lon);
});
debounce 必须由 JavaScript 元素本身提供。所以基本上,该元素应该触发一个由去抖动机制过滤的 onInput
回调。
是否可以仅使用原生 JavaScript 来实现?
编辑
看起来有人试图在 GitHub 项目页面上提出去抖动功能的拉取请求但被拒绝了: https://github.com/algolia/places/issues/281
其他人 fork 了库并将拉取请求合并到自己的 fork 上 -> https://github.com/AcuityScheduling/places/tree/feature/debounce
最佳答案
使用官方codepen ,我制作了这个骇人听闻的去抖动版本:
var client = algoliasearch("latency", "6be0576ff61c053d5f9a3225e2a90f76")
var index = client.initIndex('movies');
var myAutocomplete = autocomplete('#search-input', {
hint: false
}, [{
source: autocomplete.sources.hits(index, {
hitsPerPage: 5
}),
displayKey: 'title',
templates: {
suggestion: function(suggestion) {
var sugTemplate = "<img src='" + suggestion.image + "'/><span>" + suggestion._highlightResult.title.value + "</span>"
return sugTemplate;
}
}
}]).on('autocomplete:selected', function(event, suggestion, dataset) {
console.log(suggestion, dataset);
});
document.querySelector(".searchbox [type='reset']").addEventListener("click", function() {
document.querySelector(".aa-input").focus();
this.classList.add("hide");
myAutocomplete.autocomplete.setVal("");
});
document.querySelector("#debouncer").addEventListener("input", function() {
var s = document.querySelector("#search-input");
s.value = this.value;
clearTimeout(this.tick);
this.tick = setTimeout(() => s.dispatchEvent(new KeyboardEvent('input')), 500);
});
document.querySelector("#search-input").addEventListener("input", function() {
var searchbox = document.querySelector(".aa-input");
var reset = document.querySelector(".searchbox [type='reset']");
if (searchbox.value.length === 0) {
reset.classList.add("hide");
} else {
reset.classList.remove('hide');
}
});
body {
padding: 60px;
}
.searchbox {
display: inline-block;
position: relative;
width: 200px;
height: 37px;
white-space: nowrap;
box-sizing: border-box;
font-size: 13px;
font-family: arial, sans-serif;
}
#debouncer {
position: absolute;
z-index: 1;
box-sizing:border-box;
padding: 0 30px 0 37px;
width: 100%;
height: 100%;
vertical-align: middle;
white-space: normal;
font-size: inherit;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: none;
border:0;
}
.algolia-autocomplete {
display: block;
height: 100%;
}
.searchbox__wrapper {
width: 100%;
height: 100%;
}
.searchbox__input {
display: inline-block;
-webkit-transition: box-shadow .4s ease, background .4s ease;
transition: box-shadow .4s ease, background .4s ease;
border: 0;
border-radius: 19px;
box-shadow: inset 0 0 0 1px #D9D9D9;
color:transparent;
background: #FFFFFF;
padding: 0;
padding-right: 30px;
padding-left: 37px;
width: 100%;
height: 100%;
vertical-align: middle;
white-space: normal;
font-size: inherit;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.searchbox__input::-webkit-search-decoration,
.searchbox__input::-webkit-search-cancel-button,
.searchbox__input::-webkit-search-results-button,
.searchbox__input::-webkit-search-results-decoration {
display: none;
}
#debouncer:hover ~ * .searchbox__input {
box-shadow: inset 0 0 0 1px silver;
}
#debouncer:focus ~ * .searchbox__input,
#debouncer:active ~ * .searchbox__input {
outline: 0;
box-shadow: inset 0 0 0 1px #4098CE;
background: #FFFFFF;
}
#debouncer::-webkit-input-placeholder {
color: #AAAAAA;
}
#debouncer::-moz-placeholder {
color: #AAAAAA;
}
#debouncer:-ms-input-placeholder {
color: #AAAAAA;
}
#debouncer::placeholder {
color: #AAAAAA;
}
.searchbox__submit {
position: absolute; z-index:2;
top: 0;
right: inherit;
left: 0;
margin: 0;
border: 0;
border-radius: 18px 0 0 18px;
background-color: rgba(255, 255, 255, 0);
padding: 0;
width: 37px;
height: 100%;
vertical-align: middle;
text-align: center;
font-size: inherit;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.searchbox__submit::before {
display: inline-block;
margin-right: -4px;
height: 100%;
vertical-align: middle;
content: '';
}
.searchbox__submit:hover,
.searchbox__submit:active {
cursor: pointer;
}
.searchbox__submit:focus {
outline: 0;
}
.searchbox__submit svg {
width: 17px;
height: 17px;
vertical-align: middle;
fill: #666666;
}
.searchbox__reset {
position: absolute; z-index:2;
top: 8px;
right: 8px;
margin: 0;
border: 0;
background: none;
cursor: pointer;
padding: 0;
font-size: inherit;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
fill: rgba(0, 0, 0, 0.5);
}
.searchbox__reset.hide {
display: none;
}
.searchbox__reset:focus {
outline: 0;
}
.searchbox__reset svg {
display: block;
margin: 4px;
width: 13px;
height: 13px;
}
.searchbox__input:valid~.searchbox__reset {
display: block;
-webkit-animation-name: sbx-reset-in;
animation-name: sbx-reset-in;
-webkit-animation-duration: .15s;
animation-duration: .15s;
}
@-webkit-keyframes sbx-reset-in {
0% {
-webkit-transform: translate3d(-20%, 0, 0);
transform: translate3d(-20%, 0, 0);
opacity: 0;
}
100% {
-webkit-transform: none;
transform: none;
opacity: 1;
}
}
@keyframes sbx-reset-in {
0% {
-webkit-transform: translate3d(-20%, 0, 0);
transform: translate3d(-20%, 0, 0);
opacity: 0;
}
100% {
-webkit-transform: none;
transform: none;
opacity: 1;
}
}
.aa-dropdown-menu {
position: relative;
top: -6px;
border-radius: 3px;
margin: 6px 0 0;
padding: 0;
text-align: left;
height: auto;
position: relative;
background: transparent;
border: none;
width: 100%;
left: 0 !important;
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2), 0 2px 3px 0 rgba(0, 0, 0, 0.1);
}
.aa-dropdown-menu:before {
position: absolute;
content: '';
width: 14px;
height: 14px;
background: #fff;
z-index: 0;
top: -7px;
border-top: 1px solid #D9D9D9;
border-right: 1px solid #D9D9D9;
transform: rotate(-45deg);
border-radius: 2px;
z-index: 999;
display: block;
left: 24px;
}
.aa-dropdown-menu .aa-suggestions {
position: relative;
z-index: 1000;
}
.aa-dropdown-menu [class^="aa-dataset-"] {
position: relative;
border: solid 1px #D9D9D9;
border-radius: 3px;
overflow: auto;
padding: 8px 8px 8px;
}
.aa-dropdown-menu * {
box-sizing: border-box;
}
.aa-suggestion {
font-size: 1.1em;
padding: 4px 4px 0;
display: block;
width: 100%;
height: 38px;
clear: both;
}
.aa-suggestion span {
white-space: nowrap!important;
text-overflow: ellipsis;
overflow: hidden;
display: block;
float: left;
line-height: 2em;
width: calc(100% - 30px);
}
.aa-suggestion.aa-cursor {
background: #eee;
}
.aa-suggestion em {
color: #4098CE;
}
.aa-suggestion img {
float: left;
vertical-align: middle;
height: 30px;
width: 20px;
margin-right: 6px;
}
<script src="//cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
<script src="//cdn.jsdelivr.net/autocomplete.js/0/autocomplete.min.js"></script>
<form novalidate="novalidate" onsubmit="return false;" class="searchbox">
<div role="search" class="searchbox__wrapper">
<input id="debouncer" type="text" name="search" autocomplete="off" placeholder="Search for a movie">
<input id="search-input" type="search" name="autocomplete" autocomplete="off" required="required" class="searchbox__input">
<button type="submit" title="Submit your search query." class="searchbox__submit">
<svg role="img" aria-label="Search">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sbx-icon-search-13"></use>
</svg>
</button>
<button type="reset" title="Clear the search query." class="searchbox__reset hide">
<svg role="img" aria-label="Reset">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sbx-icon-clear-3"></use>
</svg>
</button>
</div>
</form>
<div class="svg-icons" style="height: 0; width: 0; position: absolute; visibility: hidden">
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="sbx-icon-clear-3" viewBox="0 0 40 40"><path d="M16.228 20L1.886 5.657 0 3.772 3.772 0l1.885 1.886L20 16.228 34.343 1.886 36.228 0 40 3.772l-1.886 1.885L23.772 20l14.342 14.343L40 36.228 36.228 40l-1.885-1.886L20 23.772 5.657 38.114 3.772 40 0 36.228l1.886-1.885L16.228 20z" fill-rule="evenodd"/></symbol>
<symbol id="sbx-icon-search-13" viewBox="0 0 40 40"><path d="M26.806 29.012a16.312 16.312 0 0 1-10.427 3.746C7.332 32.758 0 25.425 0 16.378 0 7.334 7.333 0 16.38 0c9.045 0 16.378 7.333 16.378 16.38 0 3.96-1.406 7.593-3.746 10.426L39.547 37.34c.607.608.61 1.59-.004 2.203a1.56 1.56 0 0 1-2.202.004L26.807 29.012zm-10.427.627c7.322 0 13.26-5.938 13.26-13.26 0-7.324-5.938-13.26-13.26-13.26-7.324 0-13.26 5.936-13.26 13.26 0 7.322 5.936 13.26 13.26 13.26z" fill-rule="evenodd"/></symbol>
</svg>
</div>
这种方法并不比这个自动完成实现本身好多少..希望对您有所帮助。
关于javascript - 创建一个带有输入回调去抖动的 HTML 输入文本元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56819169/
前言: 有时候,一个数据库有多个帐号,包括数据库管理员,开发人员,运维支撑人员等,可能有很多帐号都有比较大的权限,例如DDL操作权限(创建,修改,删除存储过程,创建,修改,删除表等),账户多了,管理
所以我用 Create React App 创建并设置了一个大型 React 应用程序。最近我们开始使用 Storybook 来处理和创建组件。它很棒。但是,当我们尝试运行或构建应用程序时,我们不断遇
遵循我正在创建的控件的代码片段。这个控件用在不同的地方,变量也不同。 我正在尝试编写指令来清理代码,但在 {{}} 附近插入值时出现解析错误。 刚接触 Angular ,无法确定我错过了什么。请帮忙。
我正在尝试创建一个 image/jpeg jax-rs 提供程序类,它为我的基于 post rest 的 Web 服务创建一个图像。我无法制定请求来测试以下内容,最简单的测试方法是什么? @POST
我一直在 Windows 10 的模拟器中练习 c。后来我改用dev C++ IDE。当我在 C 中使用 FILE 时。创建的文件的名称为 test.txt ,而我给出了其他名称。请帮助解决它。 下面
当我们创建自定义 View 时,我们将 View 文件的所有者设置为自定义类,并使用 initWithFrame 或 initWithCode 对其进行实例化。 当我们创建 customUITable
我正在尝试为函数 * Producer 创建一个线程,但用于创建线程的行显示错误。我为这句话加了星标,但我无法弄清楚它出了什么问题...... #include #include #include
今天在做项目时,遇到了需要创建JavaScript对象的情况。所以Bing了一篇老外写的关于3种创建JavaScript对象的文章,看后跟着打了一遍代码。感觉方法挺好的,在这里与大家分享一下。 &
我正在阅读将查询字符串传递给 Amazon 的 S3 以进行身份验证的文档,但似乎无法理解 StringToSign 的创建和使用方式。我正在寻找一个具体示例来说明 (1) 如何构造 String
前言:我对 C# 中任务的底层实现不太了解,只了解它们的用法。为我在下面屠宰的任何东西道歉: 对于“我怎样才能开始一项任务但不等待它?”这个问题,我找不到一个好的答案。在 C# 中。更具体地说,即使任
我有一个由一些复杂的表达式生成的 ILookup。假设这是按姓氏查找人。 (在我们简单的世界模型中,姓氏在家庭中是唯一的) ILookup families; 现在我有两个对如何构建感兴趣的查询。 首
我试图创建一个 MSI,其中包含 和 exe。在 WIX 中使用了捆绑选项。这样做时出错。有人可以帮我解决这个问题。下面是代码: 错误 error LGH
在 Yii 中,Create 和 Update 通常使用相同的形式。因此,如果我在创建期间有电子邮件、密码、...other_fields...等字段,但我不想在更新期间专门显示电子邮件和密码字段,但
上周我一直在努力创建一个给定一行和一列的 QModelIndex。 或者,我会满足于在已经存在的 QModelIndex 中更改 row() 的值。 任何帮助,将不胜感激。 编辑: QModelInd
出于某种原因,这不起作用: const char * str_reset_command = "\r\nReset"; const char * str_config_command = "\r\nC
现在,我有以下由 original.df %.% group_by(Category) %.% tally() %.% arrange(desc(n)) 创建的 data.frame。 DF 5),
在今天之前,我使用/etc/vim/vimrc来配置我的vim设置。今天,我想到了创建.vimrc文件。所以,我用 touch .vimrc cat /etc/vim/vimrc > .vimrc 所
我可以创建一个 MKAnnotation,还是只读的?我有坐标,但我发现使用 setCooperative 手动创建 MKAnnotation 并不容易。 想法? 最佳答案 MKAnnotation
在以下代码中,第一个日志语句按预期显示小数,但第二个日志语句记录 NULL。我做错了什么? NSDictionary *entry = [[NSDictionary alloc] initWithOb
我正在使用与此类似的代码动态添加到数组; $arrayF[$f+1][$y][$x+1] = $value+1; 但是我在错误报告中收到了这个: undefined offset :1 问题:尝试创
我是一名优秀的程序员,十分优秀!