需求
提高用戶體驗感,輸入框自動聚焦并鍵盤控制下拉菜單的選項上下移
效果如圖:
初期使用的el-dropdown下拉菜單,組件默認可鍵盤上下移
<el-dropdown
v-if="authoritys.length > 0"
trigger="click"
@visible-change="toggleSchoolDrop"
@command="_changeSchool"
>
<el-dropdown-menu slot="dropdown">
<el-input
v-model="searchSchoolName"
clearable
class="school-input"
size="mini"
:placeholder="$t('el.input.placeholder')"
@input="searchSchool"
/>
<div class="school-menu-list">
<el-dropdown-item
v-for="(s,i) in authoritysList"
v-show="!s.isHide"
:key="i"
:command="s.id"
>
{{ i < 9 ? `0${i + 1}` : i + 1 }}. {{ s.name }}
</el-dropdown-item>
</div>
</el-dropdown-menu>
</el-dropdown>
但是鍵盤按上下移不生效.
可能因為我的el-dropdown-item是由數組遍歷出來的,文檔的菜單是寫死的.
換成el-popover組件,內部用ul和li實現遍歷菜單.
<el-popover
v-if="authoritys.length > 0"
v-model="visible"
trigger="click"
@visible-change="toggleSchoolDrop"
>
<el-input
v-model="searchSchoolName"
clearable
class="school-input mr-b-m"
size="mini"
:placeholder="$t('el.input.placeholder')"
@input="searchSchool"
/>
<ul
id="school-menu-list"
class="school-menu-list"
>
<li
v-for="(s,i) in authoritysList"
v-show="!s.isHide"
:key="i"
class="result-option"
:class="{'is-active': i===activeIndex,'selectActive': i===selectIndex}"
@mouseover="_handleMouseOver(i)"
@click="_changeSchool(s.id,i)"
>
{{ i < 9 ? `0${i + 1}` : i + 1 }}. {{ s.name }}
</li>
</ul>
</el-popover>
后續(xù)需要在input框自動聚焦后再觸發(fā)鍵盤上下移事件.
實現自動聚焦,首先想到的方法是 給el-input 添加ref,獲取后調用focus()
<el-input
placeholder="請輸入內容"
v-model="value"
clearable
@keyup.enter.native="confirm"
ref="sInput"
>
this.$refs.sInput.focus()
但是不生效,
后續(xù)查看element官方文檔可用popover的show event手動給el-input獲取焦點
<el-popover placement="bottom" width="200" trigger="manual" v-model="visible" @show="onShow">
<el-input
placeholder="請輸入內容"
v-model="value"
clearable
@keyup.enter.native="confirm"
ref="sInput"
>
</el-popover>
methods: {
onShow () {
this.$refs.sInput.focus()
}
}
還是不生效,
對焦需要下拉打開后執(zhí)行,也就是dom更新后所以添加 this.$nextTick生效
methods: {
onShow () {
this.$nextTick(() => {
this.$refs.sInput.focus()
});
}
}
完成搜索輸入框的自動對焦后添加鍵盤事件,
添加的鍵盤事件讓用戶看到選擇的選項樣式變化以外,滾輪是不會變動的,
繼續(xù)提升用戶體驗感,需要讓滾輪隨著用戶的操作而滑動
<el-input
ref="searchSchool"
v-model="searchSchoolName"
clearable
class="school-input mr-b-m"
size="mini"
:placeholder="$t('el.input.placeholder')"
@input="searchSchool"
@keyup.enter.native="_handleEnter(selectIndex)"
@keyup.up.native="_handleUp"
@keyup.down.native="_handleDown"
/>
methods: {
_handleUp(){
// 實現對樣式的替換
this.selectIndex = this.selectIndex === 0 ? this.authoritysList.length - 1 : this.selectIndex - 1;
let selectNum = this.selectIndex + 1;
let schoolMenuList = document.getElementById("school-menu-list");
let intervalTop = schoolMenuList.scrollTop;
// 實現在用戶操作是,滾輪隨著上下移的動
if (selectNum * 35 <= intervalTop){
schoolMenuList.scrollTop = (selectNum - 1) * 35;
} else if (selectNum * 35 <= intervalTop + schoolMenuList.offsetHeight){
schoolMenuList.scrollTop = intervalTop;
} else if (selectNum * 35 > intervalTop){
schoolMenuList.scrollTop = selectNum * 35;
}
},
_handleDown(){
this.selectIndex = this.selectIndex < this.authoritysList.length - 1 ? this.selectIndex + 1 : 0;
let selectNum = this.selectIndex + 1;
let schoolMenuList = document.getElementById("school-menu-list");
let intervalTop = schoolMenuList.scrollTop;
if (selectNum * 35 <= intervalTop){
schoolMenuList.scrollTop = (selectNum - 1) * 35;
} else if (selectNum * 35 <= intervalTop + schoolMenuList.offsetHeight){
schoolMenuList.scrollTop = intervalTop;
} else if (selectNum * 35 > intervalTop){
schoolMenuList.scrollTop = selectNum * 35 - schoolMenuList.offsetHeight;
}
}
}