UI
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="bootstrap.min.css">
<title>GITHUB FINDER</title>
</head>
<body>
<nav class="navbar navbar-dark bg-primary mb-3">
<div class="container">
<a href="#" class="navbar-brand">GitHub Finder</a>
</div>
</nav>
<div class="container searchContainer">
<div class="search card card-body">
<h1>Search GitHub Users</h1>
<p class="lead">Enter a username to fetch a user profile and repos from GitHub</p>
<input type="text" id="searchuser" class="form-control" placeholder="GitHub Username...">
</div>
<br>
<div id="profile"></div>
</div>
<footer class="mt-5 p-3 text-center bg-light">
GitHub Finder ©
</footer>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="github.js"></script>
<script src="ui.js"></script>
<script src="app.js"></script>
</body>
</html>
fetch 指定的github user
github.js
class Github{
constructor(){
this.client_id='886ed2a4d8f80aaf5256';
this.client_secret='886ed2a4d8f80aaf5256';
}
async getUser(user){
const profileResponse =await fetch(`https://api.github.com/users/${user}?cliend_id=${this.client_id}&client_secret=${this.client_secret}`);
const profile=await profileResponse.json(); //得到jsondata
return {
profile //prefile object
}
}
}
调用Github类,得到profile.message
app.py
设定keyup事件,输入内容则同时查找profile;
//Init Github
const github=new Github;
//Search input
const searchUser = document.getElementById('searchuser');
//Search input event listener
searchUser.addEventListener('keyup',(e)=>{
//Get input text
const userText = e.target.value;
if(userText !=''){
// Make http call
github.getUser(userText)
.then(data=>{
if(data.profile.message == 'Not Found'){
//Show alert
}else{
//Show the profile
}
console.log(data);
})
} else{
//Clear profile
}
});
设定展示信息的html
UI.js
class UI{
constructor(){
this.profile = document.getElementById('profile');
}
showProfile(user){
this.profile.innerHTML=`
<div class="card card-body mb-3">
<div class="row">
<div class="col-md-3">
<img class="img-fluid md-2" src="${user.avatar_url}">
<a href="${user.html_url}" target ="_blank" class="btn btn-primary btn-block mb-4">View Profile</a>
</div>
<div class="col-md-9">
<span class="badge badge-primary">Public Repos: ${user.public_repos}</span>
<span class="badge badge-secondary">Public Gists: ${user.public_gists}</span>
<span class="badge badge-success">Followers: ${user.followers}</span>
<span class="badge badge-info">Following: ${user.following}</span>
<br><br>
<ul class="list-group">
<li class="list-group-item">Company: ${user.company}</li>
<li class="list-group-item">Website/Blog: ${user.blog}</li>
<li class="list-group-item">Location: ${user.location}</li>
<li class="list-group-item">Member Since: ${user.created_at}</li>
</ul>
</div>
<div class="col-md-3">
</div>
</div>
</div>
<h3 class="page-heading mb-3">Latest Repos</h3>
<div id="repos"></div>
`;
}
}
完成键入对github中用户的搜索和展示;
设置未找到的alert
app.js
//Init Github
const github=new Github;
//Init UI
const ui =new UI;
//Search input
const searchUser = document.getElementById('searchuser');
//Search input event listener
searchUser.addEventListener('keyup',(e)=>{
//Get input text
const userText = e.target.value;
if(userText !=''){
// Make http call
github.getUser(userText)
.then(data=>{
if(data.profile.message == 'Not Found'){
//Show alert
ui.showAlert(`User not found`,`alert alert-danger`);
}else{
//Show the profile
ui.showProfile(data.profile);
}
//console.log(data);
})
} else{
//Clear profile
ui.clearProfile();
}
});
ui.js
class UI{
constructor(){
this.profile = document.getElementById('profile');
}
showProfile(user){
this.profile.innerHTML=`
<div class="card card-body mb-3">
<div class="row">
<div class="col-md-3">
<img class="img-fluid md-2" src="${user.avatar_url}">
<a href="${user.html_url}" target ="_blank" class="btn btn-primary btn-block mb-4">View Profile</a>
</div>
<div class="col-md-9">
<span class="badge badge-primary">Public Repos: ${user.public_repos}</span>
<span class="badge badge-secondary">Public Gists: ${user.public_gists}</span>
<span class="badge badge-success">Followers: ${user.followers}</span>
<span class="badge badge-info">Following: ${user.following}</span>
<br><br>
<ul class="list-group">
<li class="list-group-item">Company: ${user.company}</li>
<li class="list-group-item">Website/Blog: ${user.blog}</li>
<li class="list-group-item">Location: ${user.location}</li>
<li class="list-group-item">Member Since: ${user.created_at}</li>
</ul>
</div>
<div class="col-md-3">
</div>
</div>
</div>
<h3 class="page-heading mb-3">Latest Repos</h3>
<div id="repos"></div>
`;
}
//clear profile
clearProfile(){
this.profile.innerHTML="";
}
//Show alert message
showAlert(message,className){
//Clear any remaining alert
this.clearAlert();
//Create div
const div=document.createElement('div');
//Add classes
div.className=className;
//Add text
div.appendChild(document.createTextNode(message));
//Get parent
const container=document.querySelector('.searchContainer');
//Get search box
const search = document.querySelector('.search');
container.insertBefore(div,search);
//Timeout after 3 secs
setTimeout(()=>{
this.clearAlert();
},3000);
}
//Clear alert message
clearAlert(){
const currentAlert=document.querySelector('.alert');
if(currentAlert){
currentAlert.remove();
}
}
}
加入repos展示功能
UI.js
class UI{
constructor(){
this.profile = document.getElementById('profile');
}
showProfile(user){
this.profile.innerHTML=`
<div class="card card-body mb-3">
<div class="row">
<div class="col-md-3">
<img class="img-fluid md-2" src="${user.avatar_url}">
<a href="${user.html_url}" target ="_blank" class="btn btn-primary btn-block mb-4">View Profile</a>
</div>
<div class="col-md-9">
<span class="badge badge-primary">Public Repos: ${user.public_repos}</span>
<span class="badge badge-secondary">Public Gists: ${user.public_gists}</span>
<span class="badge badge-success">Followers: ${user.followers}</span>
<span class="badge badge-info">Following: ${user.following}</span>
<br><br>
<ul class="list-group">
<li class="list-group-item">Company: ${user.company}</li>
<li class="list-group-item">Website/Blog: ${user.blog}</li>
<li class="list-group-item">Location: ${user.location}</li>
<li class="list-group-item">Member Since: ${user.created_at}</li>
</ul>
</div>
<div class="col-md-3">
</div>
</div>
</div>
<h3 class="page-heading mb-3">Latest Repos</h3>
<div id="repos"></div>
`;
}
//clear profile
clearProfile(){
this.profile.innerHTML="";
}
//Show alert message
showAlert(message,className){
//Clear any remaining alert
this.clearAlert();
//Create div
const div=document.createElement('div');
//Add classes
div.className=className;
//Add text
div.appendChild(document.createTextNode(message));
//Get parent
const container=document.querySelector('.searchContainer');
//Get search box
const search = document.querySelector('.search');
container.insertBefore(div,search);
//Timeout after 3 secs
setTimeout(()=>{
this.clearAlert();
},3000);
}
//Clear alert message
clearAlert(){
const currentAlert=document.querySelector('.alert');
if(currentAlert){
currentAlert.remove();
}
}
//Show user repos
showRepos(repos){
let output=``;
repos.forEach(function(repo){
output+=`
<div class="card card-body mb-2">
<div class="row">
<div class="col-md-6">
<a href="${repo.html_url}" target="_blank">${repo.name}</a>
</div>
<div class="col-md-6">
<span class="badge badge-primary">Stars: ${repo.stargazers_count}</span>
<span class="badge badge-secondary">Watchers: ${repo.watchers}</span>
<span class="badge badge-success">Forks: ${repo.forms_count}</span>
</div>
</div>
</div>
`;
})
//Output repos
document.getElementById('repos').innerHTML=output;
}
}
app.js
//Init Github
const github=new Github;
//Init UI
const ui =new UI;
//Search input
const searchUser = document.getElementById('searchuser');
//Search input event listener
searchUser.addEventListener('keyup',(e)=>{
//Get input text
const userText = e.target.value;
if(userText !=''){
// Make http call
github.getUser(userText)
.then(data=>{
if(data.profile.message == 'Not Found'){
//Show alert
ui.showAlert(`User not found`,`alert alert-danger`);
}else{
//Show the profile
ui.showProfile(data.profile);
ui.showRepos(data.repos);
}
//console.log(data);
})
} else{
//Clear profile
ui.clearProfile();
}
});