// https://www.jianshu.com/p/3ab716ee1a2e
const supportsWebp = ({ createImageBitmap, Image }) => {
if (!createImageBitmap || !Image) return Promise.resolve(false);
return new Promise(resolve => {
const image = new Image();
image.onload = () => {
createImageBitmap(image)
.then(() => {
resolve(true);
})
.catch(() => {
resolve(false);
});
};
image.onerror = () => {
resolve(false);
};
image.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
});
};
const webpIsSupported = () => {
let memo = null;
return () => {
if (!memo) {
memo = supportsWebp(window);
console.log('memo');
}
return memo;
};
};
const result = webpIsSupported();
result()
.then(res => {
alert('OK', res);
})
.catch(err => {
alert(err);
});
result()
.then(res => {
alert('OK', res);
})
.catch(err => {
alert(err);
});
/* OLD */
let currentPage = 1;
let totalPages = 5;
window.addEventListener('scroll', function() {
// Check if the user has reached the bottom of the page
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
// Check if there are more pages to load
if (currentPage < totalPages) {
// Fetch the data
await fetch('url')
currentPage++
}
}
});
/* NEW */
/* https://javascript.plainenglish.io/you-dont-need-using-scroll-event-to-load-data-infinite-b893c46a84ea */
let isVisible = false;
// the element visible / unvisble will trigger the function.
const observer = new IntersectionObserver(entries => {
isVisible = entries[0].isIntersecting
if (entries[0].isIntersecting) {
// load new content
loadData().then(() => {
setTimeout(() => {
// if the loading element still visible means the list height is less than container
// so try to load more
isVisible && loadData()
}, 100)
})
}
});
observer.observe(document.querySelector('.more')
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li id="selected">6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
// Your personal API key.
// Get it here: https://console.cloud.google.com/google/maps-apis
const API_KEY = '***'
const CALLBACK_NAME = 'gmapsCallback'
let initialized = !!window.google
let resolveInitPromise
let rejectInitPromise
// This promise handles the initialization
// status of the google maps script.
const initPromise = new Promise((resolve, reject) => {
resolveInitPromise = resolve
rejectInitPromise = reject
})
export default function init() {
// If Google Maps already is initialized
// the `initPromise` should get resolved
// eventually.
if (initialized) return initPromise
initialized = true
// The callback function is called by
// the Google Maps script if it is
// successfully loaded.
window[CALLBACK_NAME] = () => resolveInitPromise(window.google)
// We inject a new script tag into
// the `<head>` of our HTML to load
// the Google Maps script.
const script = document.createElement('script')
script.async = true
script.defer = true
script.src = `https://maps.googleapis.com/maps/api/js?key=${API_KEY}&callback=${CALLBACK_NAME}`
script.onerror = rejectInitPromise
document.querySelector('head').appendChild(script)
return initPromise
}
let post = {
title: 'JavaScript Template Literals',
excerpt: 'Introduction to JavaScript template literals in ES6',
body: 'Content of the post will be here...',
tags: ['es6', 'template literals', 'javascript']
};
let {title, excerpt, body, tags} = post;
let postHtml = `<article>
<header>
<h1>${title}</h1>
</header>
<section>
<div>${excerpt}</div>
<div>${body}</div>
</section>
<footer>
<ul>
${tags.map(tag => `<li>${tag}</li>`).join('\n ')}
</ul>
</footer>`;
window['out'].innerHTML = postHtml