In embarking on this web development journey, I am excited to take on the challenge of creating a remarkable and unforgettable project. The task at hand is to design and develop a sophisticated rich text editor, one that not only offers the standard functionality but also boasts a stunning dark theme to enhance the user experience.
As I delve into the intricacies of building this editor, I will undoubtedly encounter numerous learning opportunities. These will range from honing my coding skills to grasping the nuances of designing an intuitive user interface. The knowledge gained during this process will undoubtedly be invaluable, leaving a lasting impact on my web development career.
In this endeavor, I envision overcoming obstacles, solving intricate problems, and discovering innovative solutions. Every step of the way, I will be pushing my boundaries, expanding my skillset, and embracing new technologies. This journey promises to be filled with excitement and growth.
Moreover, the dark theme, with its elegance and visual appeal, will set this project apart from others. It will showcase my ability to create not only functional but also aesthetically pleasing digital experiences. Users will appreciate the ease of their eyes and the modern touch this theme brings.
As I prepare to unveil the project, I cannot help but feel a sense of pride and satisfaction in what I've accomplished. This endeavor will undoubtedly be etched into my memory as a defining moment in my web development career.
Finally, I am deeply grateful to share the source code with the community. By doing so, I hope to inspire and support other aspiring developers on their journeys. Remember, knowledge grows when shared, and I encourage everyone to pass on the experience to others.
So, if you find value in this project, I encourage you to share it with your friends, colleagues, and fellow developers. Together, we can foster a culture of learning and collaboration, enriching the web development community as a whole.
With enthusiasm and determination, I embark on this path, knowing that this project will leave a meaningful impact not just on my career but also on those who use and learn from it. Let the journey begin!
What is a rich text editor?
The term "Rich Text Editor" is a simplified reference to a WYSIWYG (What You See Is What You Get) HTML editor. This powerful tool empowers users to effortlessly compose, revise, and manage text content. The primary objective of a WYSIWYG HTML editor, often referred to as a rich text editor, is to streamline the process of coding while handling textual content. Within this tool, fundamental formatting options such as bold, italic, underline, headings, and hyperlinking are conveniently accessible. Furthermore, the tool can be enhanced with a diverse array of supplementary components, tailored to individual preferences and requirements.
Detect browser using JavaScript - with source code
Presenting an exceptional WYSIWYG HTML editor, meticulously crafted with an array of indispensable features, all meticulously unified within an elegant dark-themed interface. This thoughtful design not only promotes visual comfort but also embodies a user-centric approach to content creation. By seamlessly blending sophisticated functionality with an aesthetically pleasing design, this WYSIWYG HTML editor in a dark theme offers an unparalleled experience in crafting compelling and visually captivating web content.
files and folders for the WYSIWYG HTML editor
You want to create three files (indux.html, style.css, and main.js) in a folder.
How to create an Internet status viewer using JavaScript?
index.html
This is the main HTML file that will contain the structure of the editor interface. You can include the necessary HTML elements, like the toolbar, editor area, and any other components needed for editing and displaying content.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="main">
<center>
<h1>Blog writer</h1>
</center><br>
<div class="textBlog">
<form action="#" method="POST">
<div class="options">
<!-- Text Format -->
<button type="button" id="bold" class="option-button format">
BOLD
</button>
<button type="button" id="italic" class="option-button format">
ITALIC
</button>
<button type="button" id="underline" class="option-button format">
UNDERLINE
</button>
<button type="button" id="strikethrough" class="option-button format">
STRICK
</button>
<button type="button" id="superscript" class="option-button script">
SUP
</button>
<button type="button" id="subscript" class="option-button script">
SUB
</button>
<!-- List -->
<button type="button" id="insertOrderedList" class="option-button">
OL
</button>
<button type="button" id="insertUnorderedList" class="option-button">
LI
</button>
<!-- Undo/Redo -->
<button type="button" id="undo" class="option-button">
UNDO
</button>
<button type="button" id="redo" class="option-button">
REDO
</button>
<!-- Link -->
<button type="button" id="createLink" class="adv-option-button">
LINK
</button>
<button type="button" id="unlink" class="option-button">
UNLINK
</button>
<!-- Alignment -->
<button type="button" id="justifyLeft" class="option-button align">
LEFT
</button>
<button type="button" id="justifyCenter" class="option-button align">
CENTER
</button>
<button type="button" id="justifyRight" class="option-button align">
RIGHT
</button>
<button type="button" id="justifyFull" class="option-button align">
JF
</button>
<button type="button" id="indent" class="option-button spacing">
INTENT
</button>
<button type="button" id="outdent" class="option-button spacing">
OUTDENT
</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>
<!-- 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 name="mainContent" class="textCon" spellcheck="true" id="text-input" contenteditable="true">
<p></p>
<p></p>
</div>
</form>
</div>
</div>
<div class="count">
<div class="maincou">
Post Words: <span id="pword" class="colorWord pword words">0</span>
</div>
</div>
<script src="main.js"></script>
<script>
document.getElementById('text-input').addEventListener('input', function () {
var text = this.textContent,
count = text.trim().replace(/s+/g, ' ').split(' ').length;
document.querySelector('.words').textContent = count;
});
</script>
</body>
</html>
style.css
* {
margin: 0%;
padding: 0%;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: rgb(6, 6, 20);
color: rgb(139, 140, 141);
}
.textBlog {
max-width: 800px;
margin: auto;
border: 1px solid rgb(126, 119, 119);
border-radius: 12px;
padding: 30px;
}
.textCon {
height: 400px;
overflow: auto;
border: none;
background-color: rgb(13, 13, 37);
border-radius: 10px;
outline: none;
color: rgb(173, 169, 169);
font-size: 20px;
padding: 10px 20px;
font-weight: 520;
}
.textCon p {
padding: 15px 0 15px 0;
}
.textCon b {
font-weight: 900;
}
.buttons {
color: rgb(169, 173, 169);
background-color: rgb(50, 0, 187);
padding: 8px;
font-size: 19px;
font-weight: 800;
border: none;
margin: 20px 20px 20px 0;
border-radius: 5px;
}
.buttons:hover {
background-color: rgb(221, 221, 221);
color: black;
}
::selection {
background-color: rgb(255, 102, 0);
color: white;
}
.count {
position: absolute;
top: 35px;
left: 33px;
display: inline-block;
position: fixed;
}
.maincou {
width: 300px;
border: 2px solid rgb(255, 255, 255);
color: rgb(224, 224, 224);
background-color: rgb(11, 57, 207);
border-radius: 30px;
padding: 20px;
font-weight: 600;
}
.colorWord {
font-weight: 800;
margin-left: 10px;
color: rgb(255, 255, 255);
}
.textCon::-webkit-scrollbar {
width: 4px;
}
.textCon::-webkit-scrollbar-track {
background-color: rgb(51, 51, 51);
}
.textCon::-webkit-scrollbar-thumb {
background-color: rgb(52, 89, 253);
}
.options button,
.options select {
padding: 10px;
background-color: blue;
border: none;
margin-bottom: 15px;
color: white;
outline: none;
font-weight: 700;
}
.options button:hover,
.options select:hover {
color: black;
background-color: white;
}
.active {
background-color: #e0e9ff;
}
main.js
let optionsButtons = document.querySelectorAll(".option-button"); let advancedOptionButton = document.querySelectorAll(".adv-option-button"); 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"); //Initial Settings const initializer = () => { //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); }); //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();
Comments