HomeLập trìnhJavaScriptTìm kiếm tức...

Tìm kiếm tức thì với Vanilla JavaScript


Ban đầu được đăng trên www.florin-pop.com

Các chủ đề cho tuần #15 của Thử thách viết mã hàng tuần là:

Tìm kiếm tức thì

Chúng ta sống trong một thế giới nhanh và chúng ta muốn mọi thứ phải NHANH CHÓNG, bao gồm cả kết quả tìm kiếm, đây là lý do tại sao chức năng tìm kiếm tức thì trở thành một tính năng “phải có” thay vì một tính năng “có thì tốt”.

Trong bài viết này, chúng ta sẽ xây dựng tính năng này, nhưng chỉ sử dụng Vanilla JavaScript :smiley:.

Dưới đây là Bản xem trước trực tiếp về những gì chúng ta sẽ xây dựng trong bài viết này. Hãy tìm kiếm qua các Quốc gia trên thế giới để xem Dân số và Cờ của họ:

Thử thách viết mã hàng tuần #15 – Tìm kiếm tức thì với Vanilla JavaScript

Ghi chú: rằng bạn có thể sử dụng React, Vue, Angular hoặc bất kỳ khung/thư viện nào khác để tạo chức năng này, mặc dù làm cho nó trong Vanilla JavaScript thú vị hơn nhiều. ?

HTML

Chúng tôi sẽ cần 2 thứ trong HTML của mình:

  1. Một search cánh đồng
  2. Một results div nơi chúng tôi sẽ hiển thị kết quả tìm kiếm
<input type="text" id="search" placeholder="Search for a Country" />
<div id="results"></div>

Thông thường chúng ta sẽ đi vào phần tạo kiểu tiếp theo, nhưng trong trường hợp này do chúng ta chưa có toàn bộ phần đánh dấu (bạn sẽ thấy trong giây lát), chúng ta sẽ chuyển sang phần JS trước. ?

JavaScript

Hãy lập một kế hoạch trước khi chúng ta thực sự gõ bất kỳ mã nào. Những việc chúng ta cần làm là:

  1. Thu thập danh sách tất cả các quốc gia trên thế giới
  2. Hiển thị danh sách các quốc gia
  3. Cập nhật kết quả dựa trên truy vấn tìm kiếm

Khá tuyệt phải không? ?

Bước một – lấy dữ liệu

Tôi đã tìm thấy một API hay mà chúng tôi có thể sử dụng để lấy danh sách các quốc gia mà chúng tôi cần. Đó là: RestCountries.eu.

Đọc thêm  JavaScript cơ bản - Sử dụng nhiều toán tử có điều kiện (Tternary) - JavaScript

Chúng tôi sẽ sử dụng API Tìm nạp tích hợp để truy xuất tất cả các quốc gia và chúng tôi sẽ lưu trữ chúng trong một biến: countries.

let countries;

const fetchCountries = async () => {
    countries = await fetch(
        'https://restcountries.eu/rest/v2/all?fields=name;population;flag'
    ).then(res => res.json());
};

Như bạn có thể thấy, chúng tôi đã tạo một chức năng không đồng bộ; Bạn có thể đọc thêm về điều này ở đây.

Ngoài ra, lưu ý rằng chúng tôi chỉ muốn 3 trường từ API (tên, dân số và cờ) vì vậy đây là những gì chúng tôi sẽ nhận được từ API bằng cách đặt fields tham số truy vấn.

Bước hai – hiển thị dữ liệu

Bây giờ, chúng ta cần tạo cấu trúc danh sách của mình để hiển thị dữ liệu và để làm được điều đó, chúng ta sẽ tạo tất cả các thành phần mà chúng ta cần (ul, litiêu đề, v.v.) bên trong một hàm và chúng tôi sẽ chèn chúng vào results div chúng tôi đã khai báo trong HTML của mình.

Chúng tôi cũng sẽ gọi cho chúng tôi fetchCountries chức năng ở đây vì chúng tôi muốn lặp qua các quốc gia để tạo các phần tử tương ứng:

const results = document.getElementById('results');

const showCountries = async () => {
    // getting the data
    await fetchCountries();

    const ul = document.createElement('ul');
    ul.classList.add('countries');

    countries.forEach(country => {
        // creating the structure
        const li = document.createElement('li');
        li.classList.add('country-item');

        const country_flag = document.createElement('img');
        // Setting the image source
        country_flag.src = country.flag;
        country_flag.classList.add('country-flag');

        const country_name = document.createElement('h3');
        country_name.innerText = country.name;
        country_name.classList.add('country-name');

        const country_info = document.createElement('div');
        country_info.classList.add('country-info');

        const country_population = document.createElement('h2');
        country_population.innerText = numberWithCommas(country.population);
        country_population.classList.add('country-population');

        const country_popupation_text = document.createElement('h5');
        country_popupation_text.innerText="Population";
        country_popupation_text.classList.add('country-population-text');

        country_info.appendChild(country_population);
        country_info.appendChild(country_popupation_text);

        li.appendChild(country_flag);
        li.appendChild(country_name);
        li.appendChild(country_info);

        ul.appendChild(li);
    });

    results.appendChild(ul);
};

// display initial countries
showCountries();

// From StackOverflow https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

Có một chút mã ở trên, vì vậy hãy chia nhỏ nó. ?

Đầu tiên, chúng tôi có danh sách của chúng tôi (ul) với lis được tạo ra trong forEach vòng.

Tất cả lis có ba người con:

  1. Lá cờ – img
  2. Tên của tiêu đề quốc gia – h3
  3. Một div trong đó giữ: (a) các population con số – h2 – và (b) Các 'Population' chữ – h5

Chúng tôi đã sắp xếp chúng theo cách này vì CSS sẽ dễ dàng căn chỉnh mọi thứ hơn bằng cách sử dụng hộp linh hoạt.

Đọc thêm  Tham số so với Đối số trong JavaScript – Đâu là sự khác biệt?

Bên cạnh đó, chúng tôi đã thêm một class cho từng phần tử vì chúng tôi muốn tạo kiểu riêng cho chúng trong CSS và sau đó chúng tôi đã sử dụng appendChild để thêm các phần tử này vào DOM ở cuối forEach chức năng.

Và cuối cùng, chúng ta có một numberWithComma chức năng từ StackOverflow sẽ thêm dấu phẩy dưới dạng dấu phân cách nghìn cho population con số.

Bước 3 – cập nhật chế độ xem dựa trên truy vấn tìm kiếm

Trong bước cuối cùng này, chúng ta sẽ lấy truy vấn tìm kiếm từ input bằng cách đính kèm một eventListener trên đó, và chúng tôi sẽ sửa đổi showCountries hoạt động để nó sẽ filter ra các giá trị chúng tôi không muốn được hiển thị. Hãy xem làm thế nào chúng ta có thể làm điều đó:

const search_input = document.getElementById('search');

let search_term = '';

search_input.addEventListener('input', e => {
    // saving the input value
    search_term = e.target.value;

    // re-displaying countries based on the new search_term
    showCountries();
});

const showCountries = async () => {
    // clear the results
    results.innerHTML = '';

    // see code above at Step 2.

    countries
        .filter(country =>
            country.name.toLowerCase().includes(search_term.toLowerCase())
        )
        .forEach(country => {
            // see code above at Step 2.
        });

    // see code above at Step 2.
};

Như bạn có thể thấy, chúng tôi đã thêm hai điều mới trong showCountries chức năng:

  1. Chúng tôi đang xóa trước đó results bằng cách thiết lập innerHTML đến một chuỗi rỗng
  2. Chúng tôi đang lọc countries bằng cách kiểm tra nếu đã nhập search_termincluded bên trong name của quốc gia và chúng tôi cũng đang chuyển đổi hai giá trị này toLowerCase vì người dùng có thể nhập chữ in hoa và chúng tôi vẫn muốn hiển thị quốc gia tương ứng

Toàn bộ mã JS

Dưới đây bạn có thể tìm thấy toàn bộ mã JS trong trường hợp bạn muốn sao chép nó:

const search_input = document.getElementById('search');
const results = document.getElementById('results');

let search_term = '';
let countries;

const fetchCountries = async () => {
    countries = await fetch(
        'https://restcountries.eu/rest/v2/all?fields=name;population;flag'
    ).then(res => res.json());
};

const showCountries = async () => {
    results.innerHTML = '';

    await fetchCountries();

    const ul = document.createElement('ul');
    ul.classList.add('countries');

    countries
        .filter(country =>
            country.name.toLowerCase().includes(search_term.toLowerCase())
        )
        .forEach(country => {
            const li = document.createElement('li');
            li.classList.add('country-item');

            const country_flag = document.createElement('img');
            country_flag.src = country.flag;
            country_flag.classList.add('country-flag');

            const country_name = document.createElement('h3');
            country_name.innerText = country.name;
            country_name.classList.add('country-name');

            const country_info = document.createElement('div');
            country_info.classList.add('country-info');

            const country_population = document.createElement('h2');
            country_population.innerText = numberWithCommas(country.population);
            country_population.classList.add('country-population');

            const country_popupation_text = document.createElement('h5');
            country_popupation_text.innerText="Population";
            country_popupation_text.classList.add('country-population-text');

            country_info.appendChild(country_population);
            country_info.appendChild(country_popupation_text);

            li.appendChild(country_flag);
            li.appendChild(country_name);
            li.appendChild(country_info);

            ul.appendChild(li);
        });

    results.appendChild(ul);
};

showCountries();

search_input.addEventListener('input', e => {
    search_term = e.target.value;
    showCountries();
});

// From StackOverflow https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

CSS

Cuối cùng, hãy thêm một số kiểu dáng cho ứng dụng nhỏ của chúng ta:

@import url('https://fonts.googleapis.com/css?family=Roboto:300,500&display=swap');

* {
    box-sizing: border-box;
}

body {
    background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
    font-family: 'Roboto', sans-serif;

    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;

    min-height: 100vh;
}

.countries {
    padding: 0;
    list-style-type: none;
    width: 480px;
}

.country-item {
    background-color: #fff;
    border-radius: 3px;
    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.3);
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 10px;
    margin: 10px 0;
}

.country-item:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.country-flag {
    width: 40px;
}

.country-name {
    flex: 2;
    font-weight: normal;
    letter-spacing: 0.5px;
    margin: 0 5px;
    text-align: center;
}

.country-info {
    border-left: 1px solid #aaa;
    color: #777;
    padding: 0 15px;
    flex: 1;
}

.country-population {
    font-weight: 300;
    line-height: 24px;
    margin: 0;
    margin-bottom: 12px;
}

.country-population-text {
    font-weight: 300;
    letter-spacing: 1px;
    margin: 0;
    text-transform: uppercase;
}

input {
    font-family: 'Roboto', sans-serif;
    border-radius: 3px;
    border: 1px solid #ddd;
    padding: 15px;
    width: 480px;
}

Bởi vì nó không có gì lạ mắt nên tôi sẽ không đi sâu vào chi tiết về CSS, nhưng nếu bạn có bất kỳ câu hỏi nào liên quan đến CSS, vui lòng liên hệ với tôi và tôi sẽ sẵn lòng trả lời câu hỏi của bạn! ?

Đọc thêm  Sắp xếp theo thứ tự bảng chữ cái trong JavaScript – Cách sắp xếp theo tên trong JS

Phần kết luận

Như đã đề cập ở trên, ứng dụng nhỏ này có thể được thực hiện đơn giản hơn nhiều với React, Vue hoặc Angular và bạn có thể tự do làm như vậy nếu muốn để gửi, nhưng tôi muốn thử với Vanilla JS và đó là một trải nghiệm thú vị cho tôi! ?

Như mọi khi, hãy chắc chắn rằng bạn chia sẻ những gì bạn sẽ tạo!

Mã hóa vui vẻ! ?



Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status