feat: add lazy loading of card on home page
feat: add universal organization store fix: optimization for JSON data loaded in home page HTML
This commit is contained in:
parent
2e6e64a6d3
commit
ecf9a0720e
8 changed files with 224 additions and 87 deletions
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* Nav management
|
||||
*/
|
||||
let navOpened = false;
|
||||
let oldNavText = "";
|
||||
let oldNavIcon = "";
|
||||
|
|
@ -9,6 +12,7 @@ let navContent = document.getElementById('nav-content');
|
|||
|
||||
let mosaic = document.getElementById('mosaic');
|
||||
let mosaicHeader = document.getElementById('mosaic-header');
|
||||
let tags = []
|
||||
|
||||
navEnabler.onclick = async () => {
|
||||
if (!navOpened) {
|
||||
|
|
@ -34,6 +38,9 @@ function createEl(className = false, elName = "div") {
|
|||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render
|
||||
*/
|
||||
function renderNavItem(tag) {
|
||||
/*
|
||||
<div class="nav-item">
|
||||
|
|
@ -87,6 +94,7 @@ function renderCard(organization) {
|
|||
// image
|
||||
let image = createEl('card-image-container')
|
||||
let imageTag = createEl('card-image')
|
||||
//mediaBaseUrl + '/' +
|
||||
imageTag.style = `background-image: url('${organization.thumbnail}')`
|
||||
image.appendChild(imageTag)
|
||||
card.appendChild(image)
|
||||
|
|
@ -102,14 +110,15 @@ function renderCard(organization) {
|
|||
let icon = createEl('card-icon')
|
||||
if (Array.isArray(organization.tags) && organization.tags.length > 0) {
|
||||
let tag = tags.filter(tag => organization.tags[0] === tag._id)[0]
|
||||
icon.innerHTML = `<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 ${tag.icon.width} ${tag.icon.height}">
|
||||
<path fill="currentColor" d="${tag.icon.path}"></path>
|
||||
</svg>`
|
||||
// icon.innerHTML = `<svg
|
||||
// aria-hidden="true"
|
||||
// focusable="false"
|
||||
// role="img"
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// viewBox="0 0 ${tag.icon.width} ${tag.icon.height}">
|
||||
// <path fill="currentColor" d="${tag.icon.path}"></path>
|
||||
// </svg>`
|
||||
icon.innerHTML = tag.iconHTML
|
||||
}
|
||||
titleContainer.appendChild(icon)
|
||||
upperContent.appendChild(titleContainer)
|
||||
|
|
@ -117,8 +126,8 @@ function renderCard(organization) {
|
|||
let description = createEl('card-description')
|
||||
description.textContent = organization.description
|
||||
|
||||
let goTo = "/association/" + organization.slugs[organization.slugs.length - 1]
|
||||
if (organization.isProposed) {
|
||||
let goTo = "/association/" + organization.slug
|
||||
if (isProposed) {
|
||||
goTo += "?version=proposed"
|
||||
}
|
||||
// let link = createEl('card-link')
|
||||
|
|
@ -141,13 +150,6 @@ function renderCard(organization) {
|
|||
return card
|
||||
}
|
||||
|
||||
function renderMosaic(data) {
|
||||
let cardContainer = createEl('card-container')
|
||||
data.forEach(orga => {
|
||||
cardContainer.appendChild(renderCard(orga))
|
||||
})
|
||||
return cardContainer
|
||||
}
|
||||
|
||||
let currentTag = null
|
||||
let currentCardContainer = null
|
||||
|
|
@ -159,12 +161,7 @@ function enableTag(node) {
|
|||
tagId = node.attributes['data-tag-id'].value
|
||||
}
|
||||
let data = organizations.filter(orga => orga.tags.filter(id => id === tagId).length > 0 || all)
|
||||
let cards = renderMosaic(data)
|
||||
if (currentCardContainer !== null) {
|
||||
mosaic.removeChild(currentCardContainer)
|
||||
}
|
||||
currentCardContainer = cards
|
||||
mosaic.appendChild(cards)
|
||||
renderMosaic(data)
|
||||
node.className += ' enabled'
|
||||
if (currentTag !== null) {
|
||||
currentTag.className = currentTag.className.replace('enabled', '')
|
||||
|
|
@ -177,10 +174,115 @@ function enableTag(node) {
|
|||
} else {
|
||||
mosaicHeader.textContent = data.length + " associations listées"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
navContent.childNodes.forEach(node => {
|
||||
node.onclick = () => enableTag(node)
|
||||
/***
|
||||
* Is a element in the view ?
|
||||
*/
|
||||
function posY(elm) {
|
||||
var test = elm, top = 0;
|
||||
|
||||
while(!!test && test.tagName.toLowerCase() !== "body") {
|
||||
top += test.offsetTop;
|
||||
test = test.offsetParent;
|
||||
}
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
function viewPortHeight() {
|
||||
var de = document.documentElement;
|
||||
|
||||
if(!!window.innerWidth)
|
||||
{ return window.innerHeight; }
|
||||
else if( de && !isNaN(de.clientHeight) )
|
||||
{ return de.clientHeight; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function scrollY() {
|
||||
if( window.pageYOffset ) { return window.pageYOffset; }
|
||||
return Math.max(document.documentElement.scrollTop, document.body.scrollTop);
|
||||
}
|
||||
|
||||
function isVisible(elm) {
|
||||
var vpH = viewPortHeight(), // Viewport Height
|
||||
st = scrollY(), // Scroll Top
|
||||
y = posY(elm);
|
||||
|
||||
return !(y > (vpH + st));
|
||||
}
|
||||
|
||||
/**
|
||||
* RenderMosaic
|
||||
* (take all the organizations we want to render)
|
||||
* Render only the first 5 elements
|
||||
* Set the focus point on the last - 1 of theses elements
|
||||
* When the focus point is on screen we load the next 5 elements
|
||||
*/
|
||||
let rendering = true
|
||||
let page = 0
|
||||
let elementsPerPage = 5
|
||||
let focusPoint = null
|
||||
let focusElementPos = 2
|
||||
let cardContainer = null
|
||||
let currentOrganizations = []
|
||||
let pageCount = 0
|
||||
|
||||
function renderPage() {
|
||||
rendering = true
|
||||
let data = currentOrganizations.slice(page * elementsPerPage, (page + 1) * elementsPerPage)
|
||||
data.forEach((orga, index) => {
|
||||
let card = renderCard(orga)
|
||||
cardContainer.appendChild(card)
|
||||
if (index === data.length - focusElementPos) {
|
||||
focusPoint = card
|
||||
}
|
||||
})
|
||||
rendering = false
|
||||
}
|
||||
|
||||
function renderMosaic(data) {
|
||||
cardContainer = createEl('card-container')
|
||||
// 1 - parse all the data
|
||||
// 2 - for each
|
||||
currentOrganizations = data
|
||||
pageCount = Math.floor(data.length / elementsPerPage)
|
||||
renderPage()
|
||||
if (currentCardContainer !== null) {
|
||||
mosaic.removeChild(currentCardContainer)
|
||||
}
|
||||
currentCardContainer = cardContainer
|
||||
mosaic.appendChild(cardContainer)
|
||||
}
|
||||
|
||||
window.onscroll = () => {
|
||||
if (focusPoint != null) {
|
||||
//console.log(isVisible(focusPoint))
|
||||
if (isVisible(focusPoint) && !rendering) {
|
||||
if ((page + 1) < pageCount) {
|
||||
page++
|
||||
renderPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch tags and register click handler
|
||||
*/
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
document.querySelectorAll('#nav-content .nav-item').forEach(node => {
|
||||
node.onclick = () => enableTag(node)
|
||||
|
||||
if (node.id === 'nav-all') {
|
||||
return
|
||||
}
|
||||
tags.push({
|
||||
_id: node.attributes['data-tag-id'].value,
|
||||
iconHTML: node.querySelector('.nav-icon').innerHTML
|
||||
})
|
||||
})
|
||||
enableTag(document.getElementById('nav-all'))
|
||||
})
|
||||
|
||||
enableTag(document.getElementById('nav-all'))
|
||||
Loading…
Add table
Add a link
Reference in a new issue