JavaScript
Memo
Traitement des chaînes de caractères
Remplacement des caractères spéciaux
function removeAccents (text) {
return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
kebab-case to camelCase
const capitalizeFirstLetter = (text: string) => text.charAt(0).toUpperCase() + text.slice(1)
const kebab2camelCase = (text: string) => text.split('-').map(capitalizeFirstLetter).join('')
Echapement d'une expression régulière
Voir la librairie regexp.escape : https://www.npmjs.com/package/regexp.escape
Traitement des tableaux
Tri multicritères
myArray.sort((a, b) => a.firstname.localeCompare(b.firstname) || a.lastname.localeCompare(b.lastname) || a.age - b.age)
Variante
myArray.sort((a, b) => {
const compFirstname = a.firstname.localeCompare(b.firstname)
const compLastname = a.lastname.localeCompare(b.lastname)
const compAge = a.age - b.age
return compFirstname || compLastname || compAge
})
Traitement des objets
Tri des clés
Object.keys(myObject).sort().reduce(
(obj, key) => {
obj[key] = myObject[key]
return obj
}, {}
)
Traitement des dates
Formatage
En javascript pur :
function formatDate (date) {
return `${date.getDate()}/${('0' + (date.getMonth() + 1)).slice(-2)}/${date.getFullYear()} ${date.getHours()}:${('0' + date.getMinutes()).slice(-2)}:${('0' + date.getSeconds()).slice(-2)}`
}
Gestion des appels successifs
Debounce
Appeler qu'une seule fois une fonction au début ou à la fin d'une succession de déclenchements d'un événement.
function debounce (delay, callback) {
var timeout = null
return function () {
if (timeout) {
clearTimeout(timeout)
}
var args = arguments
timeout = setTimeout(function () {
callback.apply(null, args)
timeout = null
}, delay)
}
}
window.onresize = debounce(250, function () {
console.log('e')
})
throttle
Exécuter une fonction de manière périodique durant la séquence de déclenchements.
function throttle(delay, callback) {
var previousCall = new Date().getTime()
return function () {
var time = new Date().getTime()
if ((time - previousCall) >= delay) {
previousCall = time
callback.apply(null, arguments)
}
}
}
window.onresize = throttle(250, function () {
console.log('e')
})
Génération de nombres et chaînes aléatoires
Série de chiffres de longueur donnée
genNumbers (length) {
return Math.floor(Math.pow(10, length - 1) + Math.random() * 9 * Math.pow(10, length - 1))
}
Gestion des clics et double-clics sur un même élément
let clickCounter = 0
let timer: NodeJS.Timeout
domElement.addEventListener('click', () => {
clickCounter++
if (clickCounter === 1) {
timer = setTimeout(() => {
clickCounter = 0
// Simple click
onSvgNodeClick(node)
}, 300)
return
} else {
clearTimeout(timer)
clickCounter = 0
// Double click
onSvgNodeDblclick(node)
}
})
Gestion des erreurs
Etendre la classe Error
class DownloadError extends Error {
response: Response
constructor(message: string, response: Response) {
super(message);
this.response = response;
Object.setPrototypeOf(this, DownloadError.prototype);
}
};
new DownloadError('Erreur au téléchargement du fichier', response);
Manipulation du DOM
Attendre le chargement complet du DOM
window.readyHandlers = [];
window.ready = function ready(handler) {
window.readyHandlers.push(handler);
handleState();
};
window.handleState = function handleState () {
if (['interactive', 'complete'].indexOf(document.readyState) > -1) {
while(window.readyHandlers.length > 0) {
(window.readyHandlers.shift())();
}
}
};
document.onreadystatechange = window.handleState;
ready(function () {
// your code here
});
Attendre la présence d'un élément
function waitForElement (selector, callback) {
const wait = setInterval(function () {
const element = document.querySelector(selector);
if (element !== null) {
callback(element);
clearInterval(wait);
}
}, 100);
}
Divers
Mise en surbrillance de text HTML
Avec mark.js
highlight (text, search) {
if (typeof text !== 'undefined' && text !== null && !!search) {
const el = document.createElement('div')
el.innerHTML = text
const mark = new Mark(el)
mark.mark(search, {
'acrossElements': true
})
return el.innerHTML
}
return text
}
Fixer plusieurs lignes et/ou plusieurs colonnes d'un tableau
HTML
<table class="software-table" data-sticky-rows="2" data-sticky-cols="3">
...
</table>
CSS
table[data-sticky-rows] th,
table[data-sticky-rows] td,
table[data-sticky-cols] th,
table[data-sticky-cols] td {
position: relative;
z-index: -2;
}
table[data-sticky-rows] tr.sticky th,
table[data-sticky-rows] tr.sticky td,
table[data-sticky-cols] tr th.sticky,
table[data-sticky-rows] tr td.sticky {
position: sticky;
z-index: -1;
}
table[data-sticky-rows] tr.sticky th.sticky,
table[data-sticky-rows] tr.sticky td.sticky {
z-index: 0;
}
Javascript
document.querySelectorAll('table[data-sticky-rows],table[data-sticky-cols]').forEach(table => {
const options = {
rows: parseInt(table.getAttribute('data-sticky-rows')) || 0,
cols: parseInt(table.getAttribute('data-sticky-cols')) || 0
};
const tableStyle = getComputedStyle(table);
let deltaV = deltaH = 0;
// Si le style border-collapse est "separate", il faut en tenir compte
if (tableStyle.borderCollapse === 'separate') {
const borderSpacing = tableStyle.borderSpacing.split(' ');
deltaV += parseFloat(borderSpacing[0]) * 2;
deltaH += parseFloat(borderSpacing[1]) * 2;
}
let top = 0;
// Pour chaque ligne du tableau
table.querySelectorAll('tr').forEach((row, rowI) => {
let left = 0;
let totalColspan = 0;
// Pour chaque cellule de la ligne
[...row.querySelectorAll('th,td')].some((cell, cellI) => {
const colspan = cell.getAttribute('colspan');
colspan && (totalColspan += parseInt(colspan) - 1);
if (rowI < options.rows) {
cell.style.top = `${top}px`
}
if (cellI < options.cols - totalColspan) {
cell.classList.add('sticky');
cell.style.left = `${left}px`;
}
if (rowI >= options.rows && cellI >= options.cols - totalColspan) {
return true;
}
left += cell.offsetWidth + deltaH;
});
if (rowI < options.rows) {
row.classList.add('sticky');
top += row.offsetHeight + deltaV;
}
});
});
Télécharger des données en provenance d'une variable
function download (data, type = 'text') {
const a = document.createElement('a')
a.setAttribute('download', 'data')
a.href = window.URL.createObjectURL(new Blob([data], { type: type }))
document.body.appendChild(a)
a.click()
a.remove()
}
const data = Array.from({ length: 256 }, (_, i) => -128 + i)
.sort(() => Math.random() - 0.5)
.join("\n")
download(data)