Un éditeur de texte en JavaScript

Salut tout le monde. Bienvenue dans le tutoriel d'aujourd'hui. Dans le tutoriel d'aujourd'hui, nous allons apprendre à créer un éditeur de texte enrichi. Pour construire ce projet, nous avons besoin de HTML, CSS et Javascript. Ce tutoriel est le mieux adapté aux intermédiaires javascript. Si vous souhaitez essayer d'autres projets pour améliorer vos compétences en javascript, consultez cette liste de lecture ici. Il se compose de plus de 70 projets javascript. La complexité de ces projets varie de facile à avancé. Ainsi, ces projets conviennent aussi bien aux débutants qu'aux experts. Le projet consiste en un champ de texte que l'utilisateur peut saisir. Au-dessus de ce champ de texte, nous avons une section d'options. 
Dans la section des options, il existe une variété de boutons et de listes déroulantes. L'utilisateur peut utiliser ces options pour modifier le texte. Ces options incluent : 
1 Formateurs de texte - gras, italique, souligné, barré. 
2 Options de liste - Liste ordonnée, liste non ordonnée. 
3 Bouton Annuler et Rétablir Bouton Ajouter un lien et Supprimer un lien. Boutons d'option d'alignement - Aligner à gauche, Aligner à droite, Aligner au centre et Justifier. 
4 Liste déroulante des titres - H1 à H6 Liste déroulante des familles de polices – 
5 6 polices différentes Liste déroulante de la taille de la police - 
6 Tailles allant de 1 à 7. 
8 Options pour changer la couleur du texte et la couleur de surbrillance.

Structure du dossier du projet :
Maintenant, avant de passer au codage proprement dit, examinons la structure du dossier du projet. Nous créons un dossier de projet appelé - "Rich Text Editor". Dans ce dossier, nous avons trois fichiers - index.html, style.css et script.js. Ces fichiers sont le document HTML, la feuille de style et le fichier de script.

Code HTML

Nous commençons par le code HTML. Copiez d'abord le code ci-dessous et collez-le dans votre document HTML. Cela crée la mise en page nécessaire à notre projet.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Rich Text Editor</title>
    <!-- FontAwesome Icons -->
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
    />
    <!-- Google Fonts -->
    <link
      href="https://fonts.googleapis.com/css2?family=Poppins&display=swap"
      rel="stylesheet"
    />
    <!-- Stylesheet -->
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="container">
      <div class="options">
        <!-- Text Format -->
        <button id="bold" class="option-button format">
          <i class="fa-solid fa-bold"></i>
        </button>
        <button id="italic" class="option-button format">
          <i class="fa-solid fa-italic"></i>
        </button>
        <button id="underline" class="option-button format">
          <i class="fa-solid fa-underline"></i>
        </button>
        <button id="strikethrough" class="option-button format">
          <i class="fa-solid fa-strikethrough"></i>
        </button>
        <button id="superscript" class="option-button script">
          <i class="fa-solid fa-superscript"></i>
        </button>
        <button id="subscript" class="option-button script">
          <i class="fa-solid fa-subscript"></i>
        </button>

        <!-- List -->
        <button id="insertOrderedList" class="option-button">
          <div class="fa-solid fa-list-ol"></div>
        </button>
        <button id="insertUnorderedList" class="option-button">
          <i class="fa-solid fa-list"></i>
        </button>

        <!-- Undo/Redo -->
        <button id="undo" class="option-button">
          <i class="fa-solid fa-rotate-left"></i>
        </button>
        <button id="redo" class="option-button">
          <i class="fa-solid fa-rotate-right"></i>
        </button>

        <!-- Link -->
        <button id="createLink" class="adv-option-button">
          <i class="fa fa-link"></i>
        </button>
        <button id="unlink" class="option-button">
          <i class="fa fa-unlink"></i>
        </button>

        <!-- Alignment -->
        <button id="justifyLeft" class="option-button align">
          <i class="fa-solid fa-align-left"></i>
        </button>
        <button id="justifyCenter" class="option-button align">
          <i class="fa-solid fa-align-center"></i>
        </button>
        <button id="justifyRight" class="option-button align">
          <i class="fa-solid fa-align-right"></i>
        </button>
        <button id="justifyFull" class="option-button align">
          <i class="fa-solid fa-align-justify"></i>
        </button>
        <button id="indent" class="option-button spacing">
          <i class="fa-solid fa-indent"></i>
        </button>
        <button id="outdent" class="option-button spacing">
          <i class="fa-solid fa-outdent"></i>
        </button>

        <!-- Headings -->
        <select id="formatBlock" class="adv-option-button">
          <option value="H1">H1</option>
          <option value="H2">H2</option>
          <option value="H3">H3</option>
          <option value="H4">H4</option>
          <option value="H5">H5</option>
          <option value="H6">H6</option>
        </select>

        <!-- Font -->
        <select id="fontName" class="adv-option-button"></select>
        <select id="fontSize" class="adv-option-button"></select>

        <!-- Color -->
        <div class="input-wrapper">
          <input type="color" id="foreColor" class="adv-option-button" />
          <label for="foreColor">Font Color</label>
        </div>
        <div class="input-wrapper">
          <input type="color" id="backColor" class="adv-option-button" />
          <label for="backColor">Highlight Color</label>
        </div>
      </div>
      <div id="text-input" contenteditable="true"></div>
    </div>
    <!--Script-->
    <script src="script.js"></script>
  </body>
</html>
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Rich Text Editor</title> <!-- FontAwesome Icons --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" /> <!-- Google Fonts --> <link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet" /> <!-- Stylesheet --> <link rel="stylesheet" href="style.css" /> </head> <body> <div class="container"> <div class="options"> <!-- Text Format --> <button id="bold" class="option-button format"> <i class="fa-solid fa-bold"></i> </button> <button id="italic" class="option-button format"> <i class="fa-solid fa-italic"></i> </button> <button id="underline" class="option-button format"> <i class="fa-solid fa-underline"></i> </button> <button id="strikethrough" class="option-button format"> <i class="fa-solid fa-strikethrough"></i> </button> <button id="superscript" class="option-button script"> <i class="fa-solid fa-superscript"></i> </button> <button id="subscript" class="option-button script"> <i class="fa-solid fa-subscript"></i> </button> <!-- List --> <button id="insertOrderedList" class="option-button"> <div class="fa-solid fa-list-ol"></div> </button> <button id="insertUnorderedList" class="option-button"> <i class="fa-solid fa-list"></i> </button> <!-- Undo/Redo --> <button id="undo" class="option-button"> <i class="fa-solid fa-rotate-left"></i> </button> <button id="redo" class="option-button"> <i class="fa-solid fa-rotate-right"></i> </button> <!-- Link --> <button id="createLink" class="adv-option-button"> <i class="fa fa-link"></i> </button> <button id="unlink" class="option-button"> <i class="fa fa-unlink"></i> </button> <!-- Alignment --> <button id="justifyLeft" class="option-button align"> <i class="fa-solid fa-align-left"></i> </button> <button id="justifyCenter" class="option-button align"> <i class="fa-solid fa-align-center"></i> </button> <button id="justifyRight" class="option-button align"> <i class="fa-solid fa-align-right"></i> </button> <button id="justifyFull" class="option-button align"> <i class="fa-solid fa-align-justify"></i> </button> <button id="indent" class="option-button spacing"> <i class="fa-solid fa-indent"></i> </button> <button id="outdent" class="option-button spacing"> <i class="fa-solid fa-outdent"></i> </button> <!-- Headings --> <select id="formatBlock" class="adv-option-button"> <option value="H1">H1</option> <option value="H2">H2</option> <option value="H3">H3</option> <option value="H4">H4</option> <option value="H5">H5</option> <option value="H6">H6</option> </select> <!-- Font --> <select id="fontName" class="adv-option-button"></select> <select id="fontSize" class="adv-option-button"></select> <!-- Color --> <div class="input-wrapper"> <input type="color" id="foreColor" class="adv-option-button" /> <label for="foreColor">Font Color</label> </div> <div class="input-wrapper"> <input type="color" id="backColor" class="adv-option-button" /> <label for="backColor">Highlight Color</label> </div> </div> <div id="text-input" contenteditable="true"></div> </div> <!--Script--> <script src="script.js"></script> </body> </html>

Code CSS

Ensuite, nous stylisons notre projet en utilisant CSS. Copiez maintenant le code qui vous est fourni ci-dessous et collez-le dans votre feuille de style.


* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
body {
  background-color: #338cf4;
}
.container {
  background-color: #ffffff;
  width: 90vmin;
  padding: 50px 30px;
  position: absolute;
  transform: translate(-50%, -50%);
  left: 50%;
  top: 50%;
  border-radius: 10px;
  box-shadow: 0 25px 50px rgba(7, 20, 35, 0.2);
}
.options {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 15px;
}
button {
  height: 28px;
  width: 28px;
  display: grid;
  place-items: center;
  border-radius: 3px;
  border: none;
  background-color: #ffffff;
  outline: none;
  color: #020929;
}
select {
  padding: 7px;
  border: 1px solid #020929;
  border-radius: 3px;
}
.options label,
.options select {
  font-family: "Poppins", sans-serif;
}
.input-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
}
input[type="color"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-color: transparent;
  width: 40px;
  height: 28px;
  border: none;
  cursor: pointer;
}
input[type="color"]::-webkit-color-swatch {
  border-radius: 15px;
  box-shadow: 0 0 0 2px #ffffff, 0 0 0 3px #020929;
}
input[type="color"]::-moz-color-swatch {
  border-radius: 15px;
  box-shadow: 0 0 0 2px #ffffff, 0 0 0 3px #020929;
}
#text-input {
  margin-top: 10px;
  border: 1px solid #dddddd;
  padding: 20px;
  height: 50vh;
}
.active {
  background-color: #e0e9ff;
}

Code JavaScript

Enfin, nous implémentons la logique en utilisant javascript. Pour cela, copiez le code ci-dessous et collez-le dans votre fichier de script.

let optionsButtons = document.querySelectorAll(".option-button");
let advancedOptionButton = document.querySelectorAll(".adv-option-button");
let fontName = document.getElementById("fontName");
let fontSizeRef = document.getElementById("fontSize");
let writingArea = document.getElementById("text-input");
let linkButton = document.getElementById("createLink");
let alignButtons = document.querySelectorAll(".align");
let spacingButtons = document.querySelectorAll(".spacing");
let formatButtons = document.querySelectorAll(".format");
let scriptButtons = document.querySelectorAll(".script");

//List of fontlist
let fontList = [
  "Arial",
  "Verdana",
  "Times New Roman",
  "Garamond",
  "Georgia",
  "Courier New",
  "cursive",
];

//Initial Settings
const initializer = () => {
  //function calls for highlighting buttons
  //No highlights for link, unlink,lists, undo,redo since they are one time operations
  highlighter(alignButtons, true);
  highlighter(spacingButtons, true);
  highlighter(formatButtons, false);
  highlighter(scriptButtons, true);

  //create options for font names
  fontList.map((value) => {
    let option = document.createElement("option");
    option.value = value;
    option.innerHTML = value;
    fontName.appendChild(option);
  });

  //fontSize allows only till 7
  for (let i = 1; i <= 7; i++) {
    let option = document.createElement("option");
    option.value = i;
    option.innerHTML = i;
    fontSizeRef.appendChild(option);
  }

  //default size
  fontSizeRef.value = 3;
};

//main logic
const modifyText = (command, defaultUi, value) => {
  //execCommand executes command on selected text
  document.execCommand(command, defaultUi, value);
};

//For basic operations which don't need value parameter
optionsButtons.forEach((button) => {
  button.addEventListener("click", () => {
    modifyText(button.id, false, null);
  });
});

//options that require value parameter (e.g colors, fonts)
advancedOptionButton.forEach((button) => {
  button.addEventListener("change", () => {
    modifyText(button.id, false, button.value);
  });
});

//link
linkButton.addEventListener("click", () => {
  let userLink = prompt("Enter a URL");
  //if link has http then pass directly else add https
  if (/http/i.test(userLink)) {
    modifyText(linkButton.id, false, userLink);
  } else {
    userLink = "http://" + userLink;
    modifyText(linkButton.id, false, userLink);
  }
});

//Highlight clicked button
const highlighter = (className, needsRemoval) => {
  className.forEach((button) => {
    button.addEventListener("click", () => {
      //needsRemoval = true means only one button should be highlight and other would be normal
      if (needsRemoval) {
        let alreadyActive = false;

        //If currently clicked button is already active
        if (button.classList.contains("active")) {
          alreadyActive = true;
        }

        //Remove highlight from other buttons
        highlighterRemover(className);
        if (!alreadyActive) {
          //highlight clicked button
          button.classList.add("active");
        }
      } else {
        //if other buttons can be highlighted
        button.classList.toggle("active");
      }
    });
  });
};

const highlighterRemover = (className) => {
  className.forEach((button) => {
    button.classList.remove("active");
  });
};

window.onload = initializer();

Fin du projet
C'est tout pour ce tutoriel. Si vous rencontrez des problèmes lors de la création de ce projet, vous pouvez télécharger le code source en cliquant sur le bouton de téléchargement ci-dessous. De plus, si vous avez des questions, des suggestions ou des commentaires, déposez-les dans les commentaires ci-dessous.

3 commentaires

  1. Coding Team
    Coding Team
    Envie d'un autre projet commenter ici
  2. Anonyme
    Moi j aimerais bien un projet html js bootstrap peut être angular svp
    1. Coding Team
      Coding Team
      Ok votre projet sera publiée sur le blog donc rester connectée
N'hésitez pas de mentionner votre nom d'utilisateur Telegram à la fin de votre message pour recevoir des cadeaux de la part des modérateurs. Merci de commenter