使用 React 實作取得搜尋建議列表的功能

這次要實作的是利用 React 與 google 的 suggestion 來實作一個可以自動取得 search suggestion 的 input 功能,結果展示如下:

這邊我們主要展示的取得列表的功能,所以使用 jQuery 幫我們完成一些方便的 DOM 操作功能。

首先,此 React 元件有4個屬性,分別是:searchWords, suggsKeywords, suggs 與 showSuggs,其中 searchWords 是用來儲存使用者輸入的文字, suggsKeywords 則是儲存對應到 suggs 的搜尋關鍵字,而 suggs 則是儲存 google 給的建議關鍵字們,最後 showSuggs 則是用來判斷是否該顯示搜尋建議關鍵字,在這邊只有當使用者輸入的文字(searchWords)和搜尋關鍵字對應的文字(suggsKeywords)是相同時 (代表我們目前儲存的關鍵字列表就是使用著輸入的文字),以及 showSuggs是 true時,才會真正的顯示搜尋關鍵字列表,相關的判斷式如下:

if (this.state.showSuggestions && this.checkSuggsKeywords(this.state.searchWords)) {
// show the suggestions list
}

另外在取得 google 的 suggestions 列表時,我們使用了 JSONP (這邊有一些安全性的討論可以看一下) 來方便地做一些 CROS 的請求。

$.ajax({
...
dataType: ‘jsonp’,
type: ‘GET’,
success: function(data, textStatus, jqXHR) {
...
}
}

另外使用者也可以使用鍵盤上下鍵來選取建議的關鍵字,相關的程式碼如下:

handleSelectSuggestions(event) {
let li = $(‘.searcher-suggs-word.selected’);
// 40 => down, 38 => up
if (event.keyCode == 40 || event.keyCode == 38) {
// move to the next or previous element in the suggestions list
} else {
// 13 => enter
if (event.keyCode == 13) {
// set the current selected element
}
}
}

除此之外,當使用者沒有點選在建議列表或輸入的元件上時,應該把顯示的建議列表給隱藏起來,這邊我們註冊了一個 mousedown 的 event listener 來判斷這件事,判斷的部份如下:

handleMouseDown(event) {
let x = $(document).scrollLeft() + event.clientX; // event.offsetX
let y = $(document).scrollTop() + event.clientY; // event.offsetY

// did not click on the search input or the suggestion list
if (this.state.showSuggestions && !this.checkXYInElement(x, y, ‘.searcher-suggs’) && !this.checkXYInElement(x, y, ‘.searcher-input’)) {
   this.setState({showSuggestions: false});
  }
}

最後因為這邊希望使用滑鼠或鍵盤選取是同一個事件,所以在滑鼠滑過建議列表時,我們也將目前滑過的建議關鍵字增加一個與鍵盤選取相同的 class name,相關的程式如下:

handleHoverSearcherSuggestions(event) {
$(‘.searcher-suggs-word.selected’).removeClass(‘selected’);
$(‘.searcher-suggs-word:hover’).addClass(‘selected’);
}

以上就可以實作一個簡單的顯示建議關鍵字列表的功能。