vue输入框联想词功能
1.實現(xiàn)的功能
輸入框輸入字符后,聯(lián)想詞列表出現(xiàn),可以按“↓”或“↑”選擇列表中的內(nèi)容,也可以鼠標點選,且互相不影響選擇樣式,即只會出現(xiàn)一個被選中,“Enter”鍵發(fā)起檢索。
2.DOM結(jié)構(gòu)
<template><div class="input-m"> <div class="search"> <input type="text" :placeholder=placeholder v-model="content" @keyup="input"> </div> <ul class="associate-list" v-show="associateWords&&showList" @mouseout="selectedLi(0)"><li class="associate-item">{{inputContent}}</li> <li class="associate-item" v-for="(item,index) of associateWords" :key="index" @mouseover="selectedLi(index+1)">{{item}}</li> </ul></div> </template>復(fù)制代碼3.變量
content: '',---雙向綁定的數(shù)據(jù),input輸入框中的內(nèi)容,用戶選擇聯(lián)想詞列表時同步變化inputContent: '',---保存用戶通過鍵盤輸入的內(nèi)容,不與用戶選擇的聯(lián)想詞列表同步變化focusIndex: 0,---用戶選擇的聯(lián)想詞<li>列表的下標associateWords: [],---聯(lián)想詞列表數(shù)組showList: true---是否顯示聯(lián)想詞列表由此變量和associateWords的長度共同控制inputConent是用于記錄用戶通過鍵盤輸入的內(nèi)容,通過上下鍵選擇或鼠標懸浮時選擇的會通過雙向綁定同步到content中,以百度搜索聯(lián)想詞列表為例,當用戶一直按向下鍵時,超過聯(lián)想詞列表后,input框中的內(nèi)容為用戶最開始輸入的內(nèi)容。
focusIndex記錄用戶選擇的<li>標簽的下標,當一直按向上或向下鍵時,會出現(xiàn)focusIndex超出<li>列表長度的或小于0的清理,用focusIndex = (focusIndex+length)%length操作,可以實現(xiàn)fousIndex總是在0至length-1范圍內(nèi)。
當通過document.getElementsByClassName獲取<li>數(shù)組時,數(shù)組下標從0開始,而foucusIndex初始值為0,當按下“↓”時,focusIndex+1,選中的就是<li>列表的下標為1的元素,即第2個<li>,這是不合理的。
如果將focusIndex的下標初始值設(shè)為-1,滿足了上邊的需求。那么當按下“↑”時,focusIndex-1,通過取余操作可以得到foucusIndex = length-2,即<li>列表的倒數(shù)第2項,也是不合理的。
故將用戶輸入的文字內(nèi)容作為<li>列表的第一項,且隱藏,將focusIndex初始值設(shè)為0。這樣就實現(xiàn)了按上下鍵選擇,且超出顯示的長度時,是用戶通過鍵盤輸入的內(nèi)容。
用showList與associateWords一起控制列表的顯示,沒有相關(guān)聯(lián)想詞時肯定不顯示,但用戶點擊輸入框以外的位置時,聯(lián)想詞列表應(yīng)該可以隱藏。如果采用將associateWords來隱藏的話,用戶再次點擊輸入框時,會多向服務(wù)器發(fā)送一次搜索相關(guān)聯(lián)想詞的請求。
4.JavaScript部分
input (e) { //keyup事件的event e = e || window.event this.showList = true // 按“↑” 鍵 if (e.keyCode === 38) { this.focusIndex-- this.selectedLi() } else if (e.keyCode === 40) { // 按“↓”,數(shù)組下標從0開始,list的[0]項內(nèi)容為用戶輸入內(nèi)容,不顯示,從[1]項開始顯示 this.focusIndex++ this.selectedLi() } else if (e.keyCode === 13) { // 按“Enter”調(diào)用搜索函數(shù) this.doSomething() //----向后臺發(fā)送搜索請求 this.associateWords = [] } else { // 用戶繼續(xù)輸入時,將inputContent置空----非常重要的一步 this.inputContent = '' this.focusIndex = 0 // 搜索聯(lián)想內(nèi)容 this.getAssociateWords() //----向后臺請求相關(guān)聯(lián)想詞列表 this.clearSelected() } }復(fù)制代碼與樣式相關(guān)的js操作
selectedLi (hoverIndex) { // 當inputContent內(nèi)容為空時,記錄下搜索框中用戶輸入的內(nèi)容,作為associate-item的第一項 if (this.inputContent === '') { this.inputContent = this.content } let associateList = document.getElementsByClassName('associate-item') // 移除已添加的.selected樣式 for (var i = 0; i < associateList.length; i++) { associateList[i].classList.remove('selected') } if (hoverIndex !== undefined) { this.focusIndex = hoverIndex } // 一直按向下鍵超出聯(lián)想內(nèi)容li長度時,應(yīng)回到聯(lián)想內(nèi)容第一個 this.focusIndex = (this.focusIndex + associateList.length) % associateList.length // 為選中的li添加.selected樣式 let selectedOne = associateList[this.focusIndex] this.content = selectedOne.textContent selectedOne.classList.add('selected') } clearSelected () { let associateList = document.getElementsByClassName('associate-item') // 移除已添加的.selected樣式 for (var i = 1; i < associateList.length; i++) { associateList[i].classList.remove('selected') } }復(fù)制代碼為除了input框以外的頁面部分添加監(jiān)聽事件,點擊input以外的部分時,隱藏聯(lián)想詞列表
// 點擊input輸入框以外的位置時 隱藏聯(lián)想詞列表 document.body.addEventListener('click', e => { if (e.target.nodeName === 'INPUT') { this.showList = true } else { this.showList = false } })復(fù)制代碼向后臺服務(wù)器請求聯(lián)想詞列表
getAssociateWords () { let self = this axios.get('XX/data.json').then(function (res) { self.associateWords = result.slice(0, 5) }) }復(fù)制代碼總結(jié)
以上是生活随笔為你收集整理的vue输入框联想词功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库三大范式(1NF,2NF,3NF)
- 下一篇: vue如何在用户要关闭当前网页时弹出提示