Dito isso, neste tutorial usaremos JavaScript para implementar uma barra de pesquisa básica em um site e uma função de pesquisa para filtrar uma lista de artigos.
1. Marcação com HTML
Esta demonstração reutiliza o layout de dois tutoriais anteriores. Esses tutoriais também discutem como os dados são buscados e exibidos e como o estilo e o layout são configurados.
No nosso layout atualizado, adicionaremos uma barra de pesquisa ao elemento de cabeçalho e um elemento para armazenar o texto dos resultados da pesquisa. Portanto, é assim que a marcação ficará:
1 |
|
2 |
|
3 |
id="search" type="search" placeholder="🔍 Start typing to search..." />
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
Nós usamos o type="search"
para garantir a natureza semântica do nosso campo de entrada. Ele também fornece um botão de pesquisa clara embutido.
Outro recurso que podemos incluir em nossa marcação é uma lista de sugestões de pesquisa que aparecem em um menu suspenso quando o usuário clica no campo de entrada de pesquisa. Isso pode ser obtido usando o elemento e
list
atributo:
1 |
|
2 |
|
3 |
id="search" |
4 |
type="search" |
5 |
placeholder="Start typing to search..." |
6 |
list="search-suggestions" |
7 |
autocomplete="off" |
8 |
/>
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
2. Estilização com CSS
Esta demonstração de pesquisa de site usa o mesmo estilo dos tutoriais listados anteriormente com algumas adições: atualizamos o cabeçalho para que ele fique fixo, de modo que a barra de pesquisa esteja sempre no topo durante a rolagem, e ocultamos o estilo padrão para o campo da lista de entrada.
1 |
header { |
2 |
position: sticky; |
3 |
top: -54px; /* value to scroll past the logo so just the search bar is sticky */ |
4 |
z-index: 2; |
5 |
}
|
6 |
|
7 |
.search-bar { |
8 |
display: flex; |
9 |
justify-content: center; |
10 |
padding: 24px; |
11 |
}
|
12 |
|
13 |
.search-bar input { |
14 |
width: 50%; |
15 |
min-width: 300px; |
16 |
padding: 12px 24px; |
17 |
border-radius: 24px; |
18 |
font-size: 16px; |
19 |
border: 0px; |
20 |
outline: none; |
21 |
}
|
22 |
|
23 |
.search-bar [list]::-webkit-list-button, |
24 |
.search-bar [list]::-webkit-calendar-picker-indicator { |
25 |
display: none !important; |
26 |
}
|
3. Funcionalidade de pesquisa de site com JavaScript
Nós usaremos o Buscar API para recuperar dados simulados extraídos da página de autores do Tuts+ e armazenados em um Github gist e depois anexá-lo à página. A lógica por trás disso é explicada neste tutorial Como filtrar dados em uma página da Web (com JavaScript) e é assim que o código se parece:
1 |
let postsData = ""https://webdesign.tutsplus.com/; |
2 |
const postsContainer = document.querySelector("https://webdesign.tutsplus.com/.posts-container"https://webdesign.tutsplus.com/); |
3 |
|
4 |
fetch( |
5 |
"https://webdesign.tutsplus.com/https://gist.githubusercontent.com/jemimaabu/564beec0a30dbd7d63a90a153d2bc80b/raw/0b7e25ba0ebee6dbba216cfcfbae72d460a60f26/tutorial-levels" |
6 |
).then(async (response) => { |
7 |
postsData = await response.json(); |
8 |
postsData.map((post) => createPost(post)); |
9 |
});
|
10 |
|
11 |
const createPost = (postData) => { |
12 |
const { title, link, image, categories } = postData; |
13 |
const post = document.createElement("https://webdesign.tutsplus.com/div"https://webdesign.tutsplus.com/); |
14 |
post.className = "https://webdesign.tutsplus.com/post"https://webdesign.tutsplus.com/; |
15 |
post.innerHTML = ` |
16 |
${link}" target="_blank">
|
17 |
${image}"> |
18 |
|
19 |
|
20 |
${title} |
21 |
|
22 |
${categories |
23 |
.map((category) => { |
24 |
return "https://webdesign.tutsplus.com/' + category + "https://webdesign.tutsplus.com/"https://webdesign.tutsplus.com/; |
25 |
})
|
26 |
.join(""https://webdesign.tutsplus.com/)} |
27 |
|
28 |
|
29 |
`; |
30 |
|
31 |
postsContainer.append(post); |
32 |
};
|
Agora podemos chegar à lógica de busca.
Ouvinte de entrada
Primeiro, adicionaremos um ouvinte de entrada ao campo de pesquisa para detectar quando o texto está sendo digitado. Ao trabalhar com ouvintes de eventos, é considerado uma prática recomendada controlar quantas vezes o evento é chamado. Podemos fazer isso usando nossa função debounce.
1 |
const search = document.getElementById("https://webdesign.tutsplus.com/search"https://webdesign.tutsplus.com/); |
2 |
|
3 |
let debounceTimer; |
4 |
const debounce = (callback, time) => { |
5 |
window.clearTimeout(debounceTimer); |
6 |
debounceTimer = window.setTimeout(callback, time); |
7 |
};
|
8 |
|
9 |
search.addEventListener( |
10 |
"https://webdesign.tutsplus.com/input"https://webdesign.tutsplus.com/, |
11 |
(event) => { |
12 |
const query = event.target.value; |
13 |
debounce(() => handleSearchPosts(query), 500); |
14 |
},
|
15 |
false
|
16 |
);
|
Nesta função, chamamos o handleSearchPosts
função dentro da nossa função debounce com um tempo debounce de 500 ms. A seguir, definiremos a lógica dentro da handleSearchPosts()
função.
Formatar a entrada
Ao trabalhar com entrada do usuário, é uma boa ideia formatar a entrada de alguma forma para evitar resultados imprevisíveis. No caso da nossa entrada de pesquisa, removeremos qualquer espaço em branco extra e também retornaremos apenas resultados de pesquisa para entrada com mais de um caractere. Também converteremos a função para minúsculas para evitar resultados que diferenciam maiúsculas de minúsculas. É assim que a função se parece até agora:
1 |
const handleSearchPosts = (query) => { |
2 |
const searchQuery = query.trim().toLowerCase(); |
3 |
|
4 |
if (searchQuery.length <= 1) { |
5 |
return
|
6 |
}
|
7 |
}
|
Obtenha os dados corretos
Em seguida, queremos lidar com a busca dos dados corretos com base na consulta. Retornaremos qualquer post em que o título ou o texto da categoria contenha a consulta:
1 |
let searchResults = [...postsData].filter( |
2 |
(post) => |
3 |
post.categories.some((category) => category.toLowerCase().includes(searchQuery)) || |
4 |
post.title.toLowerCase().includes(query) |
5 |
);
|
As categorias de postagem são uma matriz, então usamos some()
método para retornar quaisquer correspondências e o .includes()
método para verificar se a string contém a consulta. O método includes diferencia maiúsculas de minúsculas, então convertemos a categoria e o título do post para minúsculas antes de pesquisar.
Atualizar texto exibido
Agora que obtivemos os resultados da pesquisa, podemos atualizar o texto de exibição da pesquisa para exibir o texto com base nos resultados retornados:
1 |
const searchDisplay = document.querySelector("https://webdesign.tutsplus.com/.search-display"https://webdesign.tutsplus.com/); |
2 |
|
3 |
if (searchResults.length == 0) { |
4 |
searchDisplay.innerHTML = "https://webdesign.tutsplus.com/No results found" |
5 |
} else if (searchResults.length == 1) { |
6 |
searchDisplay.innerHTML = `1 result found for your query: ${query}` |
7 |
} else { |
8 |
searchDisplay.innerHTML = `${searchResults.length} results found for your query: ${query}` |
9 |
}
|
Anexar resultados
Em seguida, anexamos nossos resultados de pesquisa na página usando o createPost()
função.
1 |
postsContainer.innerHTML = ""https://webdesign.tutsplus.com/; |
2 |
searchResults.map((post) => createPost(post)); |
Queremos poder redefinir a página para seu estado padrão quando o usuário limpa o campo de entrada. Podemos fazer isso definindo um resetPosts()
função e chamá-la em nosso handleSearchPosts()
função
1 |
const resetPosts = () => { |
2 |
searchDisplay.innerHTML = "" |
3 |
postsContainer.innerHTML = ""https://webdesign.tutsplus.com/; |
4 |
postsData.map((post) => createPost(post)); |
5 |
};
|
6 |
|
7 |
|
8 |
const handleSearchPosts = (query) => { |
9 |
const searchQuery = query.trim().toLowerCase(); |
10 |
|
11 |
if (searchQuery.length <= 1) { |
12 |
resetPosts() |
13 |
return
|
14 |
}
|
15 |
|
16 |
let searchResults = [...postsData].filter( |
17 |
(post) => |
18 |
post.categories.some((category) => category.toLowerCase().includes(searchQuery)) || |
19 |
post.title.toLowerCase().includes(searchQuery) |
20 |
);
|
21 |
|
22 |
if (searchResults.length == 0) { |
23 |
searchDisplay.innerHTML = "https://webdesign.tutsplus.com/No results found" |
24 |
} else if (searchResults.length == 1) { |
25 |
searchDisplay.innerHTML = `1 result found for your query: ${query}` |
26 |
} else { |
27 |
searchDisplay.innerHTML = `${searchResults.length} results found for your query: ${query}` |
28 |
}
|
29 |
|
30 |
postsContainer.innerHTML = ""https://webdesign.tutsplus.com/; |
31 |
searchResults.map((post) => createPost(post)); |
32 |
};
|
E isso é tudo o que ela escreveu
Com isso, temos nossa barra de pesquisa simples completamente configurada!