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