前端切图学习-Github 用户搜索

Github Profiles

Posted by R1NG on September 1, 2021 Viewed Times

GitHub 用户搜索 Github Profiles

1. 概述

项目展示了一个可搜索 GitHub 用户的搜索组件.

效果:

20210902175827


2. 结构和切图

网页的基本结构如下:

1
2
3
4
5
6
7
8
9
<body>
    <form class="user-form" id="form">
      <input type="text" id="search" placeholder="Search a Github User">
    </form>

    <main id="main"></main>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.0/axios.min.js" integrity="sha512-DZqqY3PiOvTP9HkjIWgjO6ouCbq+dxqWoJZ/Q+zPYNHmlnI2dQnbJ5bxAHpAMw+LXRm4D72EIRXzvcHQtE8/VQ==" crossorigin="anonymous"></script>
  </body>


3. 编写 CSS 样式

完整的 CSS 样式表如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
* {
    box-sizing: border-box;
}

body {
    background-color: #2a2a72;
    color: #fff;
    font-family: 'Poppins', sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
    margin: 0;
}

.user-form {
    width: 100%;
    max-width: 700px;
}
.user-form input {
    width: 100%;
    display: block;
    background-color: #4c2885;
    border: none;
    border-radius: 10px;
    color: #fff;
    padding: 1rem;
    margin-bottom: 2rem;
    font-family: inherit;
    font-size: 1rem;
    box-shadow: 0 5x 10px rgba(154, 160, 185, 0.05), 0 15px 40px rgba(0, 0, 0, .1);
}
.user-form input::placeholder {
    color: #bbb;
}
.user-form input:focus {
    outline: none;
}

.card {
    max-width: 800px;
    background-color: #4c2885;
    border-radius: 20px;
    box-shadow: 0 5x 10px rgba(154, 160, 185, 0.05), 0 15px 40px rgba(0, 0, 0, .1);
    display: flex;
    padding: 3rem;
    margin: 0 1.5rem;
}
.avatar {
    border-radius: 50%;
    border: 10px solid #2a2a72;
    height: 150px;
    width: 150px;
}

.user-info {
    color: #eee;
    margin-left: 2rem;
}
.user-info h2 {
    margin-top: 0;
}
.user-info ul {
    list-style-type: none;
    display: flex;
    justify-content: space-between;
    padding: 0;
    max-width: 400px;
}
.user-info ul li {
    display: flex;
    align-items: center;
}
.user-info ul li strong {
    font-size: 0.9rem;
    margin-left: .5rem;
}

.repo {
    text-decoration: none;
    color: #fff;
    background-color: #212a72;
    font-size: .7rem;
    padding: .25rem .5rem;
    margin-right: .5rem;
    margin-bottom: .5rem;
    display: inline-block;
}

@media (max-width: 500px) {
    .card {
        flex-direction: column;
        align-items: center;
    }

    .user-form {
        max-width: 400px;
    }
}


4. JavaScript

最后, 我们编写 JavaScript 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
const APIURL = 'https://api.github.com/users/';
const main = document.getElementById('main');
const form = document.getElementById('form');
const search = document.getElementById('search')

async function getUser(username) {
    try {
        const {data} = await axios(APIURL + username);
        createUserCard(data);
        getRepos(username);
    } catch (err) {
        if (err.response.status == 404) {
            createErrorCard('No profile with this username');
        }
    }
}

async function getRepos(username) {
    try {
        const {data} = await axios(APIURL + username + '/repos?sort=created');
        addReposToCard(data);
    } catch (err) {
        createErrorCard('Problem fetching repos');
    }
}

function createUserCard(user) {
    const userID = user.name || user.login;
    const userBio = user.bio ? `<p>${user.bio}</p>` : '';
    const cardHTML = `
    <div class="card">
        <div>
            <img src="${user.avatar_url}" alt="${user.name}" class="avatar">
        </div>
        <div class="user-info">
            <h2>${userID}</h2>
                ${userBio}
            <ul>
                <li>${user.followers} <strong>Followers</strong></li>
                <li>${user.following} <strong>Following</strong></li>
                <li>${user.public_repos} <strong>Repos</strong></li>
            </ul>
            <div id="repos"></div>
        </div>
    </div>`;
    main.innerHTML = cardHTML;
}

function createErrorCard(msg) {
    const cardHTML = `
        <div class="card">
            <h1>${msg}</h1>
        </div>`;
    main.innerHTML = cardHTML;
}

function addReposToCard(repos) {
    const reposEl = document.getElementById('repos')
    repos.slice(0, 5).forEach(repo => {
        const repoEl = document.createElement('a')
        repoEl.classList.add('repo')
        repoEl.href = repo.html_url
        repoEl.target = '_blank'
        repoEl.innerText = repo.name
        reposEl.appendChild(repoEl)
    })
}

form.addEventListener('submit', (e) => {
    e.preventDefault()
    const user = search.value
    if(user) {
        getUser(user)
        search.value = ''
    }
})

最后, 完整的网页演示可见 此处