admin管理员组文章数量:1335623
I have a search ponent in Vue.js
. When you type into the text input, a list of search results is fetched from the server, then displayed in a list beneath the search field. When you click one of the results, the submit
event fires.
However, now I tried adding a blur event to the text input, which should hide the list of results when the user clicks away from the input. This works fine, except for one crucial situation - clicking on a result no longer fires the submit
event.
I understand why this is - the blur
event apparently fires before the click
event, and hides the results list before the click can be registered on one of the results. My question is, how do I get around this? I need the results list to close when clicking outside the text input, but I obviously also need the submit
method to function.
Here is the ponent in full:
<template>
<div class="search basic-search">
<input type="text" v-model="search_string" v-on:keyup="search" v-on:focus="activate" v-on:blur="inactivate" class="form-control search" placeholder="Search stocks" />
<div :class="['search-results', active === true ? 'active' : '']">
<div class="search-result" v-for="result in search_results" v-on:click="submit(result.id)">
{{ result.name }} ({{ result.ticker }})
</div>
</div>
</div>
</template>
<script>
export default {
data: function() {
return {
search_string : '',
search_results : [],
active : false
};
},
methods : {
search : function() {
const axios_data = {
_token : $('meta[name="csrf-token"]').attr('content'),
str : this.search_string
};
axios.post('/stock-search', axios_data).then(response => {
if(response.data.success){
this.search_results = response.data.stocks;
this.active = true;
}
});
},
activate : function() {
if(this.search_string !== '')
this.active = true;
},
inactivate : function() {
this.active = false;
},
submit : function(stock_id) {
document.location = "/graphs/" + stock_id;
}
}
}
</script>
I have a search ponent in Vue.js
. When you type into the text input, a list of search results is fetched from the server, then displayed in a list beneath the search field. When you click one of the results, the submit
event fires.
However, now I tried adding a blur event to the text input, which should hide the list of results when the user clicks away from the input. This works fine, except for one crucial situation - clicking on a result no longer fires the submit
event.
I understand why this is - the blur
event apparently fires before the click
event, and hides the results list before the click can be registered on one of the results. My question is, how do I get around this? I need the results list to close when clicking outside the text input, but I obviously also need the submit
method to function.
Here is the ponent in full:
<template>
<div class="search basic-search">
<input type="text" v-model="search_string" v-on:keyup="search" v-on:focus="activate" v-on:blur="inactivate" class="form-control search" placeholder="Search stocks" />
<div :class="['search-results', active === true ? 'active' : '']">
<div class="search-result" v-for="result in search_results" v-on:click="submit(result.id)">
{{ result.name }} ({{ result.ticker }})
</div>
</div>
</div>
</template>
<script>
export default {
data: function() {
return {
search_string : '',
search_results : [],
active : false
};
},
methods : {
search : function() {
const axios_data = {
_token : $('meta[name="csrf-token"]').attr('content'),
str : this.search_string
};
axios.post('/stock-search', axios_data).then(response => {
if(response.data.success){
this.search_results = response.data.stocks;
this.active = true;
}
});
},
activate : function() {
if(this.search_string !== '')
this.active = true;
},
inactivate : function() {
this.active = false;
},
submit : function(stock_id) {
document.location = "/graphs/" + stock_id;
}
}
}
</script>
Share
Improve this question
asked Apr 10, 2020 at 9:29
sveti petarsveti petar
3,79714 gold badges77 silver badges158 bronze badges
3 Answers
Reset to default 6You could delay the hiding of the box until click
fires
inactivate : function() {
setTimeout( () => this.active = false, 100)
},
You may also try to use mousedown
instead of click
<div class="search-result" v-for="result in search_results" v-on:mousedown="submit(result.id)">
I don't know if the order of the events is determined, but mousedown should be triggered before blur.
I had the same problem but instead of click I was doing they "enter". So the solution for Vue is:
@keydown.enter="selectPreselectedOption"
Which triggers before the blur on my input (which also triggers on enter, but keyup)
I was able to solve this issue by adding v-on:mousedown.prevent
like this
<div :class="['search-results', active === true ? 'active' : '']">
<div
class="search-result"
v-for="result in search_results"
v-on:click="submit(result.id)"
v-on:mousedown.prevent
>
{{ result.name }} ({{ result.ticker }})
</div>
</div>
This prevents the click from propagating up to the parent with v-on:blur
.
With this solution you'd still need call inactivate
manually in function submit
.
本文标签: javascriptBlur event cancels click event in Vue componentStack Overflow
版权声明:本文标题:javascript - Blur event cancels click event in Vue component - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742391701a2466118.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论