One thing that I could not find for my website was a fully functional search. So I wrote one.
It works completely on the client side and uses a .json
file generated by hexo-search.
I split up my code in four sections:
- The html for the search
- The start up of the search
- The search function
- The Range class I wrote for this
- And some miscellaneous functions and methods
At the end of the post is the complete code.
HTML and CSS
This is the HTML and CSS code for the search input. The showing and hiding is completely done by css, no javascript required. It used the :checked
selector of a checkbox in combination with a label.
|
|
|
|
Start Up
This start up code is called once when the site is loading.
It gets the search.json and add an event listener to the search input.
|
|
Search
The Algorithm
The search algorithm takes the query and splits it up in parts with variable length. With these it can easily find the longest connected part of a query in a post. The longer the found part is, the higher is the score for this post.
Let’s take this query: "some special programming topic"
.
The first step is splitting up the query in all lengths form 1 to 4:
This would be the result: (look at the source)
The clue behind this splitting is that the score of a post is higher if it contains "special programming topic"
in a row, rather than the words "special"
, "programming"
and "topic"
independently.
All the strings are then searched in the title and content, and the quantity of occurrences is used to calculate the score:score += queryWordCount² * (occurrencesInTitle * 100 + occurrencesInContent)
The categories and tags are also checked. A matching category adds 2000 and a tag 1000 to the score.
When the score of all posts is calculated they are sorted with the highest score on top.
After that the first occurrence of all found keywords in each post are searched and highlighted. The content of the post is then cut +100 and -100 characters around the highlighted keywords.
At the end the method generates the html code that gets displayed and shows the search result.
This code was generated when I searched for keywords
. You can see how it is highlighted in the text:
|
|
Range Class
The Range class represents a range between two numbers. It simplifies the work with ranges by providing methods to combine ranges, check if ranges intersect or are equal and combine or sort an array of ranges.
This class is used to save the ranges of post content that should be shown in the result +100 and -100 characters around each keyword.
|
|
Miscellaneous
This are some miscellaneous functions and methods I’m using to make it easier to work with javascript.
|
|
|
|
Complete Code
Here you can download the complete code either minified or not.