<div class="main-app">
<header class="my-transition">
<h1 class="my-transition">
<a href="javascript:void(0);" class="effect-underline"><span class="text-deco">Wiki</span>pedia Viewer</a>
</h1>
</header>
<section class="my-transition search-wrapper">
<input class="my-transition" id="inp-search" type="search" placeholder="Search..." autofocus>
<div class="row">
<div class="btn-wrapper">
<button class="my-transition" id="wiki-search">Search</button>
</div>
<div class="btn-wrapper">
<button class="my-transition link">
<a href="https://en.wikipedia.org/wiki/Special:Random" target="_blank">Random</a>
</button>
</div>
</div>
</section>
<section class="result">
</section>
<footer class="row">Made with
<i class="fa fa-heart heart"></i> by
<a class="effect-underline" href="http://about.phamvanlam.com"><span class="text-deco">Lam Pham</span></a>
</footer>
<div class="loading">
<div class="lds-hourglass"></div>
</div>
</div>
* {box-sizing: border-box;}
body {
margin: 0;
color: #fff;
font: normal normal normal 0.9rem/1.6 Nunito Sans, Helvetica, Arial, sans-serif;
}
h1 {
font-size: 2.25rem;
}
a {
color: #fff;
text-decoration: none;
display: inline-block;
position: relative;
}
.effect-underline:after {
content: '';
display: block;
width: 100%;
border-bottom: 2px solid;
margin: 0px auto;
opacity: 0;
-webkit-transition: opacity 0.35s, -webkit-transform 0.35s;
transition: opacity 0.35s, transform 0.35s;
-webkit-transform: scale(0,1);
transform: scale(0,1);
}
.effect-underline:hover:after {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
}
h1 .effect-underline:after {
margin: -5px auto;
}
.main-app {
position: absolute;
top: 0;
left: 0;
width: 100%;
min-height: 100%;
text-align: center;
background: linear-gradient(to bottom right, rgb(115, 237, 241), rgb(81, 81, 229));
}
header {padding-top: 125px;}
header.view-result {padding-top: 0px;}
.search-wrapper input[type="search"] {
background-color: transparent;
border: solid 2px #fff;
width: 300px;
height: 40px;
border-radius: 20px;
padding: 0px 10px;
color: #fff;
font-size: 1rem;
}
.search-wrapper input[type="search"]:focus { outline: none;}
.search-wrapper input[type="search"]::-webkit-input-placeholder {
color: rgba(255, 255, 255, 0.6);
font-size: 0.9rem;
}
.search-wrapper input[type="search"]:-moz-placeholder { /* Firefox 18- */
color: rgba(255, 255, 255, 0.6);
font-size: 0.9rem;
}
.search-wrapper input[type="search"]::-moz-placeholder { /* Firefox 19+ */
color: rgba(255, 255, 255, 0.6);
font-size: 0.9rem;
}
.search-wrapper input[type="search"]:-ms-input-placeholder {
color: rgba(255, 255, 255, 0.6);
font-size: 0.9rem;
}
.row {margin-top: 25px;}
.btn-wrapper {
display: inline-block;
padding: 0px 5px;
}
.my-transition {
transition: all 0.35s ease-in-out;
-webkit-transition: all 0.35s ease-in-out;
-moz-transition: all 0.35s ease-in-out;
}
.text-deco{color: #f6cd61;}
footer {
height: 40px;
width: 100%;
position: absolute;
bottom: 0px;
left: 0px;
text-align: center;
}
footer .heart {color: #fe4a49;}
button {
background-color: transparent;
border: solid 2px #fff;
color: #fff;
padding: 8px 10px;
border-radius: 6px;
font-size: 0.9rem;
width: 100px;
}
button:focus {outline: none;}
button:hover {
cursor: pointer;
transform: translate(0, -2px);
}
button.link {padding: 0;}
button.link a {padding: 8px 10px;}
.result {
width: 100%;
padding: 40px 15px;
}
.result-item {
width: 100%;
max-width: 800px;
text-align: left;
background-color: #fff;
color: #444;
display: flex;
display: -webkit-flex;
align-items: center;
margin: 0px auto;
margin-bottom: 15px;
cursor: pointer;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}
.result-item:hover {
transform: translate(0, -2px);
box-shadow: 0 2px 5px rgba(0,0,0,0.12), 0 3px 5px rgba(0,0,0,0.24);
-webkit-box-shadow: 0 2px 5px rgba(0,0,0,0.12), 0 3px 5px rgba(0,0,0,0.24);
-moz-box-shadow: 0 2px 5px rgba(0,0,0,0.12), 0 3px 5px rgba(0,0,0,0.24);
}
.result-item a {
color: #3da4ab;
}
.hidden {
display: none;
}
.result-item .content {
padding-left: 15px;
}
.loading {
visibility: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
min-height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
display: -webkit-flex;
justify-content: center;
align-items: center;
}
.lds-hourglass {
display: inline-block;
position: relative;
width: 64px;
height: 64px;
}
.lds-hourglass:after {
content: " ";
display: block;
border-radius: 50%;
width: 0;
height: 0;
margin: 6px;
box-sizing: border-box;
border: 26px solid #fff;
border-color: #fff transparent #fff transparent;
animation: lds-hourglass 1.2s infinite;
}
@keyframes lds-hourglass {
0% {
transform: rotate(0);
animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
50% {
transform: rotate(900deg);
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
100% {
transform: rotate(1800deg);
}
}
@media (min-width: 400px) {
h1 {font-size: 2.5rem;}
header {padding-top: 135px;}
.search-wrapper input[type="search"]{width: 370px;}
}
@media (min-width: 576px) {
h1 {font-size: 3.25rem;}
header {padding-top: 135px;}
.search-wrapper input[type="search"]{width: 450px;}
.rest-text {margin-left: -15px;}
}
@media (min-width: 768px) {
h1 {font-size: 3.5rem;}
header {padding-top: 160px;}
header.view-result h1 {
margin-top: 10px auto;
}
.search-wrapper input[type="search"]{
width: 500px;
margin-right: 8px;
}
.search-wrapper.view-result {
display: flex;
display: -webkit-flex;
align-items: center;
}
.search-wrapper.view-result {
display: flex;
display: -webkit-flex;
justify-content: center;
}
.search-wrapper.view-result .row {margin-top: 0px;}
}
document.addEventListener("DOMContentLoaded", () => {
let $ = document.querySelector.bind(document);
let _input = $("#inp-search");
let _searchWrapper = $(".search-wrapper");
let _header = $("header");
let _resultWrapper = $(".result");
let _loading = $(".loading");
let _title = $("header");
let api = 'https://en.wikipedia.org/w/api.php?format=json&action=query&' +
'generator=search&gsrnamespace=0&gsrlimit=10&prop=pageimages|extracts&' +
'pilimit=max&exintro&explaintext&exsentences=1&exlimit=max&gsrsearch=';
let cors = 'https://cors-anywhere.herokuapp.com/';
let wikiPage = 'https://en.wikipedia.org/?curid=';
$("#wiki-search").addEventListener("click", () => {
let searchText = _input.value;
if (searchText !== '') search(searchText);
});
_title.addEventListener("click", () => location.reload());
_input.addEventListener("search", event => {
let _target = event.target;
let searchText = _target.value;
if (searchText !== '') search(searchText);
else resetViewResult();
});
_input.addEventListener("input", event => {
let _target = event.target;
let searchText = _target.value;
if (searchText === '') resetViewResult();
});
function showLoading(show) {
if (show) _loading.style.visibility = "visible";
else _loading.style.visibility = "hidden";
}
function search(text) {
showLoading(true);
fetch(cors + api + text)
.then(response => response.json())
.then(json => viewResult(json))
.catch(error => onSearchError());
}
function onSearchError(error) {
console.log(error);
showLoading(false);
}
function viewResult(result) {
showLoading(false);
resetViewResult();
if (result.query) {
_searchWrapper.classList.add("view-result");
_header.classList.add("view-result");
let pages = result.query.pages;
for (let key in pages) {
let page = pages[key];
let html = itemHTMLTemplate(page.title, page.extract, page.pageid);
let _resultItem = htmlToElement(html);
_resultWrapper.appendChild(_resultItem);
_resultItem.addEventListener("click", onResultItemClicked);
}
}
}
function onResultItemClicked(event) {
let _resultItem = this;
let linkTarget = _resultItem.getAttribute("target");
window.open(linkTarget, '_blank');
}
function resetViewResult() {
_searchWrapper.classList.remove("view-result");
_header.classList.remove("view-result");
clearDom(_resultWrapper);
}
function clearDom(_domWrapper) {
while (_domWrapper.firstChild) {
delete _domWrapper.removeChild(_domWrapper.firstChild);
}
}
function itemHTMLTemplate(title, description, pageid) {
let linkTarget = `${wikiPage}${pageid}`;
return `<div class="result-item my-transition" target="${linkTarget}">\n` +
`<div class="content">\n` +
`<h2><a href="${linkTarget}" target="_blank">${title}</a></h2>\n` +
`<p>${description}</p>\n` +
`</div>\n` +
`</div>\n`;
}
function htmlToElement(html) {
let template = document.createElement('template');
html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = html;
return template.content.firstChild;
}
});
This Pen doesn't use any external JavaScript resources.