{}const=>[]async()letfn</>var
JSWeb

Mini application Web en JavaScript : application avec des notes

Guide étape par étape pour créer une mini application Web en JavaScript pur. Dans ce tutoriel, nous allons créer une application de prise de notes en utilisant HTML, CSS et JavaScript, et connecter localStorage pour enregistrer les données entre les sessions du navigateur.

К

Kodik

Auteur

8 min de lecture

Bonjour ! 👋 Aujourd'hui, nous allons créer mini application web en JavaScriptapplication pour les notes en utilisant HTML, CSS et JavaScript.

Cette application vous permettra ajouter, modifier et supprimer des notesqui seront conservés dans localStorage navigateur. Cela signifie que vos notes ne disparaîtront pas même après le redémarrage de la page!

Nous allons examiner chaque étape de la création d'une applicationafin que vous puissiez comprendre comment cela fonctionne et créer votre propre mini-application Web sur JS pur.

Prêts ? C'est parti ! 🚀

Pour le code source complet et éventuellement des améliorations supplémentaires, consultez notre GitHub.


Ce que fait notre application

Notre application de prise de notes permet aux utilisateurs de :

  1. Ajouter des notes avec des titres et des descriptions.

  2. Enregistrer les notes dans le navigateur afin que les données ne soient pas perdues lors du rechargement de la page.

  3. Voir la liste de toutes les notes créées.

  4. Modifier les notes existantes.

  5. Supprimer les notes inutiles.

Maintenant, commençons à créer !


1. Création d'une structure HTML

HTML est responsable de la structure de notre application. Commencez par créer un fichier index.html avec le balisage de base :

<!DOCTYPE html>
<html lang="ru" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>Приложение для заметок на JavaScript | Coursme</title>
  <link rel="stylesheet" href="style.css">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- Подключение иконок -->
  <link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.0/css/line.css">
</head>
<body>
  <!-- Всплывающее окно для добавления/редактирования заметок -->
  <div class="popup-box">
    <div class="popup">
      <div class="content">
        <header>
          <p>Добавить новую заметку</p>
          <i class="uil uil-times"></i> <!-- Кнопка закрытия -->
        </header>
        <form action="#">
          <div class="row title">
            <label>Заголовок</label>
            <input type="text" spellcheck="false">
          </div>
          <div class="row description">
            <label>Описание</label>
            <textarea spellcheck="false"></textarea>
          </div>
          <button>Сохранить заметку</button>
        </form>
      </div>
    </div>
  </div>

  <!-- Контейнер для добавления новой заметки -->
  <div class="wrapper">
    <li class="add-box">
      <div class="icon"><i class="uil uil-plus"></i></div>
      <p>Добавить новую заметку</p>
    </li>
  </div>

  <script src="script.js"></script>
</body>
</html>

Brève explication du code:

  • popup-box : fenêtre contextuelle pour créer une nouvelle note. Contient un formulaire avec des champs pour le titre et la description.

  • add-box : l'élément qui ouvre une fenêtre contextuelle pour ajouter une nouvelle note.


2. Style avec CSS

Créez un fichier style.css pour ajouter des styles à notre application. Voici les principaux styles que vous devez connaître :

/* Import Google Font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Poppins', sans-serif;
}
body {
  background: #FFB3B3;
}
::selection {
  color: #fff;
  background: #FF6F61;
}
.wrapper {
  margin: 40px;
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, 270px);
}
.wrapper li {
  height: 260px;
  list-style: none;
  border-radius: 8px;
  padding: 15px 18px 18px;
  background: #ffffff;
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.08);
  transition: transform 0.3s ease-in-out;
}
.wrapper li:hover {
  transform: translateY(-5px);
}
.add-box,
.icon,
.bottom-content,
.popup,
header,
.settings .menu li {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.add-box {
  cursor: pointer;
  flex-direction: column;
  justify-content: center;
}
.add-box .icon {
  height: 80px;
  width: 80px;
  color: #FF6F61;
  font-size: 42px;
  border-radius: 50%;
  justify-content: center;
  border: 3px dashed #FF6F61;
}
.add-box p {
  color: #FF6F61;
  font-weight: 500;
  margin-top: 18px;
}
.note {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.note .details {
  max-height: 170px;
  overflow-y: auto;
}
.note .details::-webkit-scrollbar,
.popup textarea::-webkit-scrollbar {
  width: 0;
}
.note .details:hover::-webkit-scrollbar,
.popup textarea:hover::-webkit-scrollbar {
  width: 6px;
}
.note .details:hover::-webkit-scrollbar-track,
.popup textarea:hover::-webkit-scrollbar-track {
  background: #f3f3f3;
  border-radius: 20px;
}
.note .details:hover::-webkit-scrollbar-thumb,
.popup textarea:hover::-webkit-scrollbar-thumb {
  background: #ddd;
  border-radius: 20px;
}
.note p {
  font-size: 20px;
  font-weight: 500;
}
.note span {
  display: block;
  color: #626262;
  font-size: 15px;
  margin-top: 6px;
}
.note .bottom-content {
  padding-top: 8px;
  border-top: 1px solid #bbb;
}
.bottom-content span {
  color: #7A7A7A;
  font-size: 13px;
}
.bottom-content .settings {
  position: relative;
}
.bottom-content .settings i {
  color: #7A7A7A;
  cursor: pointer;
  font-size: 16px;
}
.settings .menu {
  z-index: 1;
  bottom: 0;
  right: -5px;
  padding: 6px 0;
  background: #ffffff;
  position: absolute;
  border-radius: 6px;
  transform: scale(0);
  transform-origin: bottom right;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.18);
  transition: transform 0.3s ease;
}
.settings.show .menu {
  transform: scale(1);
}
.settings .menu li {
  height: 28px;
  font-size: 15px;
  margin-bottom: 2px;
  padding: 18px 16px;
  cursor: pointer;
  box-shadow: none;
  border-radius: 0;
  justify-content: flex-start;
}
.menu li:last-child {
  margin-bottom: 0;
}
.menu li:hover {
  background: #f4f4f4;
}
.menu li i {
  padding-right: 8px;
}

.popup-box {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2;
  height: 100%;
  width: 100%;
  background: rgba(0, 0, 0, 0.5);
}
.popup-box .popup {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 3;
  width: 100%;
  max-width: 420px;
  justify-content: center;
  transform: translate(-50%, -50%) scale(0.9);
}
.popup-box,
.popup {
  opacity: 0;
  pointer-events: none;
  transition: all 0.35s ease;
}
.popup-box.show,
.popup-box.show .popup {
  opacity: 1;
  pointer-events: auto;
}
.popup-box.show .popup {
  transform: translate(-50%, -50%) scale(1);
}
.popup .content {
  border-radius: 8px;
  background: #ffffff;
  width: calc(100% - 20px);
  box-shadow: 0 0 18px rgba(0, 0, 0, 0.12);
}
.content header {
  padding: 16px 28px;
  border-bottom: 1px solid #bbb;
}
.content header p {
  font-size: 21px;
  font-weight: 500;
}
.content header i {
  color: #9a9898;
  cursor: pointer;
  font-size: 24px;
}
.content form {
  margin: 18px 28px 40px;
}
.content form .row {
  margin-bottom: 22px;
}
form .row label {
  font-size: 17px;
  display: block;
  margin-bottom: 7px;
}
form :where(input, textarea) {
  height: 52px;
  width: 100%;
  outline: none;
  font-size: 16px;
  padding: 0 16px;
  border-radius: 5px;
  border: 1px solid #aaa;
}
form :where(input, textarea):focus {
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.15);
}
form .row textarea {
  height: 155px;
  resize: none;
  padding: 10px 16px;
}
form button {
  width: 100%;
  height: 52px;
  color: #fff;
  outline: none;
  border: none;
  cursor: pointer;
  font-size: 17px;
  border-radius: 5px;
  background: #FF6F61;
}

@media (max-width: 660px) {
  .wrapper {
    margin: 12px;
    gap: 12px;
    grid-template-columns: repeat(auto-fill, 100%);
  }
  .popup-box .popup {
    max-width: calc(100% - 12px);
  }
  .bottom-content .settings i {
    font-size: 18px;
  }
}

Brève explication:

  • Fond: Nous avons défini un joli fond rose pour la page.

  • add-box: Élément avec l'icône "+" pour ajouter une nouvelle note.

  • popup-box : Fenêtre contextuelle qui s'affichera lors de l'ajout/modification d'une note.

Le code de style est disponible dans référentiels.


3. Logique de l'application en JavaScript

Créez un fichier script.js pour ajouter des fonctionnalités à l'application. Nous examinerons les principales fonctions nécessaires au fonctionnement de l'application.

const addBox = document.querySelector(".add-box"),
    popupBox = document.querySelector(".popup-box"),
    popupTitle = popupBox.querySelector("header p"),
    closeIcon = popupBox.querySelector("header i"),
    titleTag = popupBox.querySelector("input"),
    descTag = popupBox.querySelector("textarea"),
    addBtn = popupBox.querySelector("button");

// Mois en russe
const months = ["January", "February", "March", "April", "May", "June", "July",
    "August", "September", "October", "November", "December"];

// Nous obtenons les notes enregistrées à partir de localStorage, s'il y en a
const notes = JSON.parse(localStorage.getItem("notes") || "[]");
let isUpdate = false, updateId;

// Ouvrir une fenêtre pour ajouter une nouvelle note
addBox.addEventListener("click", () => {
    popupTitle.innerText = "Add a new note";
    addBtn.innerText = "Add a note";
    popupBox.classList.add("show");
    document.querySelector("body").style.overflow = "hidden";
    if(window.innerWidth > 660) titleTag.focus();
});

// Fermer la fenêtre d'ajout / de modification de la note
closeIcon.addEventListener("click", () => {
    isUpdate = false;
    titleTag.value = descTag.value = "";
    popupBox.classList.remove("show");
    document.querySelector("body").style.overflow = "auto";
});

// Fonction d'affichage de toutes les notes
function showNotes() {
    if(!notes) return;
    document.querySelectorAll(".note").forEach(li => li.remove());
    notes.forEach((note, id) => {
        let filterDesc = note.description.replaceAll("\n", '<br/>');
        let liTag = `<li class="note">
                        <div class="details">
                            <p>${note.title}</p>
                            <span>${filterDesc}</span>
                        </div>
                        <div class = "bottom-content">
                            <span>${note.date}</span>
                            <div class="settings">
                                <i onclick="showMenu(this)" class="uil uil-ellipsis-h"></i>
                                <ul class="menu">
                                    <li onclick="updateNote(${id}, '${note.title}', '${filterDesc}')"><i class="uil uil-pen"></i>Edit</li>
                                    <li onclick="deleteNote(${id})"><i class="uil uil-trash"></i>Delete</li>
                                </ ul>
                            </ div>
                        </ div>
                    </ li>`;
        addBox.insertAdjacentHTML("afterend", liTag);
    });
}
showNotes();

// Afficher le menu des paramètres pour les notes
function showMenu(elem) {
    elem.parentElement.classList.add("show");
    document.addEventListener("click", e => {
        if(e.target.tagName != "I" || e.target != elem) {
            elem.parentElement.classList.remove("show");
        }
    });
}

// Supprimer la note
function deleteNote(noteId) {
    let confirmDel = confirm("Are you sure you want to delete this note?");
    if(!confirmDel) return;
    notes.splice(noteId, 1);
    localStorage.setItem("notes", JSON.stringify(notes));
    showNotes();
}

// Mettre à jour la note
function updateNote(noteId, title, filterDesc) {
    let description = filterDesc.replaceAll('<br/>', '\r\n');
    updateId = noteId;
    isUpdate = true;
    addBox.click();
    titleTag.value = title;
    descTag.value = description;
    popupTitle.innerText = "Update note";
    addBtn.innerText = "Update note";
}

// Ajouter ou mettre à jour une note
addBtn.addEventListener("click", e => {
    e.preventDefault();
    let title = titleTag.value.trim(),
        description = descTag.value.trim();

    if(title || description) {
        let currentDate = new Date(),
            month = months[currentDate.getMonth()],
            day = currentDate.getDate(),
            year = currentDate.getFullYear();

        let noteInfo = {title, description, date: `${month} ${day}, ${year}`}
        if(!isUpdate) {
            notes.push(noteInfo);
        } else {
            isUpdate = false;
            notes[updateId] = noteInfo;
        }
        localStorage.setItem("notes", JSON.stringify(notes));
        showNotes();
        closeIcon.click();
    }
});

Explication détaillée:

  1. addBox et popupBox : ces variables font référence aux éléments pour ajouter une nouvelle note et une fenêtre contextuelle.

  2. Fonction d'ouverture du formulaire: Lorsque vous cliquez sur « Ajouter », un formulaire de saisie de données s'ouvre.

  3. Ajouter et enregistrer des notes: Lorsque vous cliquez sur le bouton « Enregistrer », les données sont enregistrées dans localStorage.

  4. Affichage des notes: Toutes les notes enregistrées sont affichées sur la page à l'aide de la fonction showNotes().

Le reste du code est disponible dans référentiels.


Conclusion

Vous avez maintenant une application complète avec des notes JavaScript ! Vous pouvez télécharger le code source et essayer de l'améliorer en ajoutant de nouvelles fonctionnalités. Bonne chance pour le développement ! 🚀

🎯Arrête de reporter

Tu as aimé l'article ?
Place à la pratique !

Avec Kodik, tu ne lis pas seulement — tu codes immédiatement. Théorie + pratique = vraies compétences.

Pratique instantanée
🧠L'IA explique le code
🏆Certificat

Sans inscription • Sans carte