Aller au contenu

JavaScript⚓︎

Raccourci pour sélectionner une liste de nœuds⚓︎

La méthode standard qui consiste à utiliser querySelectorAll() est relativement verbeuse et ne permet pas de faire facilement un forEach() dessus. Cette version simplifiée est un raccourci utile lorsqu’on doit le faire souvent :

qsa.js
1
2
3
function qsa(selector, root = document) {
  return Array.from(root.querySelectorAll(selector)) // (1)
}
  1. On en profite pour retourner un Array !

Récupérer la chaîne de l’ancre d’une URL⚓︎

Je passe toujours trop de temps à retrouver comment faire.

anchor.js
1
2
3
function currentAnchor() {
  return document.location.hash ? document.location.hash.slice(1) : ''
}

Prendre en compte les préférences utilisateur·ice pour lancer une animation⚓︎

Très important car des personnes sont mal à l’aise avec certaines animations (j’en fait partie, parfois).

motion.js
1
2
3
4
5
6
7
const prefersReducedMotion = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches

if (prefersReducedMotion !== true) {
  // do animation
}

Raccourci pour créer/attacher un évènement⚓︎

Un bout de code qui vient de Chris Ferdinandi (voir 1, 2 et 3) :

emit.js
1
2
3
4
5
6
7
8
function emit(type, detail, elem = document) {
  let event = new CustomEvent(type, {
    bubbles: true,
    cancelable: true,
    detail: detail,
  })
  return elem.dispatchEvent(event)
}

Il peut s’utiliser ainsi emit('calculator:add', {total: 20}, calendarElement) et s’écouter de manière classique.

Polyfills à la demande⚓︎

Il est possible d’importer des polyfills externes directement depuis une balise <script>, par exemple pour Promise ou fetch :

polyfills.html
<script>
  window.Promise ||
    document.write(
      '<script src="https://unpkg.com/es6-promise@4.2.8/dist/es6-promise.auto.min.js"><\/script>'
    )
  window.fetch ||
    document.write(
      '<script src="https://unpkg.com/whatwg-fetch@3.6.2/dist/fetch.umd.js"><\/script>'
    )
</script>

En pratique, c’est quand même mieux de ne pas faire des requêtes externes et d’avoir les fichiers en local.

Copier dans le presse-papier⚓︎

Lorsqu’il y a un champ avec un code ou une URL à copier-coller, ça peut être intéressant de proposer à l’utilisateur·ice de cliquer pour mettre l’information dans son presse-papier et le coller ailleurs.

copy-clipboard.js
function copyToClipboard(codeElement, alert) {
  try {
    navigator.clipboard.writeText(codeElement.innerText)
    alert.innerHTML = `<div class="custom-class">Code copied!</div>`
    setTimeout(() => {
      alert.innerHTML = ''
    }, 3000) // (1)
  } catch (ex) {
    alert.innerHTML = ''
  }
}
  1. Vous pouvez adapter cette valeur qui correspond au temps d’affichage de l’information (en millisecondes).

Confirmation de suppression⚓︎

La façon la plus simple d’ouvrir une popup de confirmation.

delete-confirmation.js
1
2
3
4
5
6
7
function deleteConfirmation(event) {
  if (window.confirm('Are you sure you want to delete this?')) {
    return
  } else {
    event.preventDefault()
  }
}

Fermeture automatique

Notez qu’à force de recevoir des notifications, les utilisateur·ices sont promptes à fermer une fenêtre, aussi rouge soit-elle. Il peut-être pertinent de demander une confirmation qui demande de saisir quelque chose comme le fait Github lorsqu’on supprime un dépôt (il faut taper le nom complet du dépôt concerné).

Générer un slug⚓︎

Pour transformer un titre en français en une portion d’URL par exemple. Adapté depuis cet article.

slugify.js
function slugify(str) {
  const a =
    'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;'
  const b =
    'aaaaaaaaaacccddeeeeeeeegghiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------'
  const p = new RegExp(a.split('').join('|'), 'g')

  return str
    .toString()
    .toLowerCase()
    .replace(/\s+/g, '-') // Replace spaces with -
    .replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
    .replace(/’/g, "'") // Turn apostrophes to single quotes
    .replace(/[^a-zA-Z0-9-']+/g, '') // Remove all non-word characters except single quotes
    .replace(/--+/g, '-') // Replace multiple - with single -
    .replace(/^-+/, '') // Trim - from start of text
    .replace(/-+$/, '') // Trim - from end of text
}

Un système de plugins⚓︎

Ce fragment est issu de ce qu’à fait Simon Willison pour Datasette, aidé par Matthew Somerville.

plugins.js
var datasette = datasette || {}
datasette.plugins = (() => {
  var registry = {}
  return {
    register: (hook, fn) => {
      registry[hook] = registry[hook] || []
      registry[hook].push(fn)
    },
    call: (hook, args) => {
      var results = (registry[hook] || []).map((fn) => fn(args || {}))
      return results
    },
  }
})()

Il s’utilise ensuite ainsi :

1
2
3
datasette.plugins.register('numbers', ({a, b}) => a + b)
datasette.plugins.register('numbers', o => o.a * o.b)
datasette.plugins.call('numbers', {a: 4, b: 6})

Paramètres par défaut⚓︎

Il est possible de définir des paramètres par défaut en utilisant la syntaxe suivante :

parameters.js
1
2
3
function checkName({ name = 'Castor' } = {}) {
  console.log({ name })
}

Il est aussi possible d’avoir un comportement similaires aux **kwargs en Python grâce au rest parameter :

parameters-kwargs.js
1
2
3
function checkNameWithKwargs({ name = 'Pollux', ...kwargs } = {}) {
  console.log({ name, ...kwargs })
}

Cela nécessite d’appeler la fonction avec un objet (ce qui pourrait être une bonne pratique ?).

checkNameWithKwargs({name: 'Télaïre', tessiture:'soprano'})

Télécharger un fichier dynamiquement⚓︎

Parfois, on veut pouvoir télécharger un fichier généré dynamiquement en JavaScript, par exemple ici pour transformer un tableau en un export CSV (la récupération des données n’est pas montrée).

download-file.js
function downloadAsCSV(event) {
  event.preventDefault()
  const content = 'foo;bar' // (1)
  const name = 'baz_quux'
  const filename = `export_${new Date().toLocaleDateString()}_${name}.csv` // (2)
  const csvFile = new Blob([content], { type: 'text/csv' }) // (3)
  const fakeDownloadLink = document.createElement('a') // (4)
  fakeDownloadLink.download = filename // (5)
  fakeDownloadLink.href = window.URL.createObjectURL(csvFile) // (6)
  fakeDownloadLink.style.display = 'none'
  document.body.appendChild(fakeDownloadLink)
  fakeDownloadLink.click() // (7)
  fakeDownloadLink.remove()
}
  1. Le contenu souhaité du fichier à aller récupérer par ailleurs
  2. C’est toujours intéressant d’avoir la date dans des fichiers d’export
  3. Création d’un Blob simulant le fichier
  4. Création du faux lien qui va nous servir à simuler le téléchargement
  5. Utilisation de l’attribut download qui permet de donner un nom au fichier téléchargé
  6. Création d’une URL contenant le contenu du fichier
  7. Simulation du clic avant la suppression de l’élément pour lancer le téléchargement

Pour aller plus loin/différemment⚓︎


Dernière mise à jour: 2022-09-14