Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| kb_it:javascript [2022/09/15 02:09] – befe | kb_it:javascript [2024/12/12 21:59] (Version actuelle) – befe | ||
|---|---|---|---|
| Ligne 13: | Ligne 13: | ||
| </ | </ | ||
| - | ==== kebab-case to camelCase | + | === kebab-case to camelCase === |
| <code javascript> | <code javascript> | ||
| Ligne 19: | Ligne 19: | ||
| const kebab2camelCase = (text: string) => text.split(' | const kebab2camelCase = (text: string) => text.split(' | ||
| </ | </ | ||
| + | |||
| + | === Echapement d'une expression régulière === | ||
| + | |||
| + | Voir la librairie regexp.escape : https:// | ||
| ==== Traitement des tableaux ==== | ==== Traitement des tableaux ==== | ||
| Ligne 118: | Ligne 122: | ||
| return Math.floor(Math.pow(10, | return Math.floor(Math.pow(10, | ||
| } | } | ||
| + | </ | ||
| + | |||
| + | ==== Gestion des clics et double-clics sur un même élément ==== | ||
| + | |||
| + | <code javascript> | ||
| + | let clickCounter = 0 | ||
| + | let timer: NodeJS.Timeout | ||
| + | domElement.addEventListener(' | ||
| + | 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 === | ||
| + | |||
| + | <code javascript> | ||
| + | class DownloadError extends Error { | ||
| + | response: Response | ||
| + | constructor(message: | ||
| + | super(message); | ||
| + | this.response = response; | ||
| + | Object.setPrototypeOf(this, | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | new DownloadError(' | ||
| </ | </ | ||
| Ligne 178: | Ligne 222: | ||
| return text | return text | ||
| } | } | ||
| + | </ | ||
| + | |||
| + | === Fixer plusieurs lignes et/ou plusieurs colonnes d'un tableau === | ||
| + | |||
| + | HTML | ||
| + | <code html> | ||
| + | <table class=" | ||
| + | ... | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | CSS | ||
| + | <code 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 | ||
| + | <code javascript> | ||
| + | document.querySelectorAll(' | ||
| + | const options = { | ||
| + | rows: parseInt(table.getAttribute(' | ||
| + | cols: parseInt(table.getAttribute(' | ||
| + | }; | ||
| + | const tableStyle = getComputedStyle(table); | ||
| + | let deltaV = deltaH = 0; | ||
| + | // Si le style border-collapse est " | ||
| + | if (tableStyle.borderCollapse === ' | ||
| + | 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(' | ||
| + | let left = 0; | ||
| + | let totalColspan = 0; | ||
| + | // Pour chaque cellule de la ligne | ||
| + | [...row.querySelectorAll(' | ||
| + | const colspan = cell.getAttribute(' | ||
| + | colspan && (totalColspan += parseInt(colspan) - 1); | ||
| + | if (rowI < options.rows) { | ||
| + | cell.style.top = `${top}px` | ||
| + | } | ||
| + | if (cellI < options.cols - totalColspan) { | ||
| + | cell.classList.add(' | ||
| + | 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(' | ||
| + | top += row.offsetHeight + deltaV; | ||
| + | } | ||
| + | }); | ||
| + | }); | ||
| + | </ | ||
| + | |||
| + | === Télécharger des données en provenance d'une variable === | ||
| + | |||
| + | <code javascript> | ||
| + | function download (data, type = ' | ||
| + | const a = document.createElement(' | ||
| + | a.setAttribute(' | ||
| + | a.href = window.URL.createObjectURL(new Blob([data], | ||
| + | document.body.appendChild(a) | ||
| + | a.click() | ||
| + | a.remove() | ||
| + | } | ||
| + | |||
| + | const data = Array.from({ length: 256 }, (_, i) => -128 + i) | ||
| + | .sort(() => Math.random() - 0.5) | ||
| + | .join(" | ||
| + | |||
| + | download(data) | ||
| </ | </ | ||